Tools: WordPress Page Builder Automation: Generate Layouts via Scripts

Tools: WordPress Page Builder Automation: Generate Layouts via Scripts

Source: Dev.to

Why Automate Page Builder Layouts? ## Architecture: JSON Config → Script → Page Builder ## Supported Page Builders ## Example 1: Elementor Automation ## Step 1: Export Template as JSON ## Step 2: Create City Data JSON ## Step 3: PHP Automation Script ## Step 4: Run Script ## Example 2: Divi Layout Automation ## Divi Storage Format ## Divi Automation Script ## Example 3: WP-CLI Integration ## Create WP-CLI Command ## Advanced: REST API Integration ## Create REST Endpoint ## Call API from External Script ## Real-World Use Case: Agency Workflow ## Client: National HVAC Company ## Implementation ## Handling Dynamic Content ## ACF Integration ## Dynamic Elementor Widgets ## Error Handling & Logging ## Bottom Line Client wants: 50 landing pages with same layout, different cities Manual method: 50 × 15 minutes = 12.5 hours clicking in Elementor!! My response: "Give me 45 minutes to write a script" Here's how to automate page builder layout generation programmatically: Manual page building SUCKS when: Automation = sanity!! This technique works with: Key insight: All page builders store layouts as JSON or shortcodes in database!! Create one perfect page manually in Elementor Saved as: template.json File: generate-elementor-pages.php 3 pages created in seconds!! Divi stores layouts as JSON in _et_pb_page_layout postmeta File: wp-content/mu-plugins/page-generator.php Need: Landing page for every city (300+ locations) Manual time: 300 × 20 minutes = 100 hours!! Data file: hvac-locations.csv Result: 300 pages generated in 5 minutes!! Elementor renders ACF shortcode dynamically!! Stop clicking page builders for repetitive layouts!! ROI: Pays for itself after 10 pages!! For 50+ pages: Automation is NON-NEGOTIABLE!! Page builder automation = agency superpower!! 🚀 This article contains affiliate links! Templates let you quickly answer FAQs or store snippets for re-use. Used this exact workflow last month for client with 85 location pages... saved me like 3 DAYS of clicking around in Divi!! Template took 90 min to perfect, wrote the PHP script in 2 hours, then just ran it and boom - 85 pages with unique city content, phone numbers, map embeds, everything. Client was like "how did you do this so fast" lol... JSON config is KEY - once you nail the placeholder system you can pump out pages for ANY repetitive layout. Game changer for agency work honestly... Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment's permalink. Hide child comments as well For further actions, you may consider blocking this person and/or reporting abuse CODE_BLOCK: cities.json → automation-script.php → wp-cli → 50 pages created Enter fullscreen mode Exit fullscreen mode CODE_BLOCK: cities.json → automation-script.php → wp-cli → 50 pages created CODE_BLOCK: cities.json → automation-script.php → wp-cli → 50 pages created CODE_BLOCK: Elementor → Tools → Export Template Enter fullscreen mode Exit fullscreen mode CODE_BLOCK: Elementor → Tools → Export Template CODE_BLOCK: Elementor → Tools → Export Template CODE_BLOCK: { "content": [ { "id": "abc123", "elType": "section", "elements": [ { "elType": "column", "elements": [ { "elType": "widget", "widgetType": "heading", "settings": { "title": "{{CITY_NAME}} Services" } } ] } ] } ] } Enter fullscreen mode Exit fullscreen mode CODE_BLOCK: { "content": [ { "id": "abc123", "elType": "section", "elements": [ { "elType": "column", "elements": [ { "elType": "widget", "widgetType": "heading", "settings": { "title": "{{CITY_NAME}} Services" } } ] } ] } ] } CODE_BLOCK: { "content": [ { "id": "abc123", "elType": "section", "elements": [ { "elType": "column", "elements": [ { "elType": "widget", "widgetType": "heading", "settings": { "title": "{{CITY_NAME}} Services" } } ] } ] } ] } CODE_BLOCK: [ { "city": "Chicago", "state": "IL", "zip": "60601", "phone": "(312) 555-0100" }, { "city": "Boston", "state": "MA", "zip": "02108", "phone": "(617) 555-0200" }, { "city": "Seattle", "state": "WA", "zip": "98101", "phone": "(206) 555-0300" } ] Enter fullscreen mode Exit fullscreen mode CODE_BLOCK: [ { "city": "Chicago", "state": "IL", "zip": "60601", "phone": "(312) 555-0100" }, { "city": "Boston", "state": "MA", "zip": "02108", "phone": "(617) 555-0200" }, { "city": "Seattle", "state": "WA", "zip": "98101", "phone": "(206) 555-0300" } ] CODE_BLOCK: [ { "city": "Chicago", "state": "IL", "zip": "60601", "phone": "(312) 555-0100" }, { "city": "Boston", "state": "MA", "zip": "02108", "phone": "(617) 555-0200" }, { "city": "Seattle", "state": "WA", "zip": "98101", "phone": "(206) 555-0300" } ] COMMAND_BLOCK: <?php /** * Elementor Page Generator * Usage: php generate-elementor-pages.php */ // Load WordPress require_once('/path/to/wp-load.php'); // Load data $template = json_decode(file_get_contents('template.json'), true); $cities = json_decode(file_get_contents('cities.json'), true); foreach ($cities as $city) { // Replace placeholders in template $layout = replace_placeholders($template, [ '{{CITY_NAME}}' => $city['city'], '{{STATE}}' => $city['state'], '{{ZIP}}' => $city['zip'], '{{PHONE}}' => $city['phone'] ]); // Create page $page_id = wp_insert_post([ 'post_title' => $city['city'] . ' Services', 'post_status' => 'publish', 'post_type' => 'page', 'post_content' => '' // Elementor uses meta, not content ]); if (!is_wp_error($page_id)) { // Save Elementor data update_post_meta($page_id, '_elementor_data', wp_slash(json_encode($layout['content']))); update_post_meta($page_id, '_elementor_edit_mode', 'builder'); update_post_meta($page_id, '_elementor_template_type', 'wp-page'); update_post_meta($page_id, '_elementor_version', '3.16.0'); echo "✅ Created: {$city['city']} (ID: {$page_id})\n"; } } function replace_placeholders($data, $replacements) { $json = json_encode($data); foreach ($replacements as $placeholder => $value) { $json = str_replace($placeholder, $value, $json); } return json_decode($json, true); } echo "\n✨ Generation complete!\n"; Enter fullscreen mode Exit fullscreen mode COMMAND_BLOCK: <?php /** * Elementor Page Generator * Usage: php generate-elementor-pages.php */ // Load WordPress require_once('/path/to/wp-load.php'); // Load data $template = json_decode(file_get_contents('template.json'), true); $cities = json_decode(file_get_contents('cities.json'), true); foreach ($cities as $city) { // Replace placeholders in template $layout = replace_placeholders($template, [ '{{CITY_NAME}}' => $city['city'], '{{STATE}}' => $city['state'], '{{ZIP}}' => $city['zip'], '{{PHONE}}' => $city['phone'] ]); // Create page $page_id = wp_insert_post([ 'post_title' => $city['city'] . ' Services', 'post_status' => 'publish', 'post_type' => 'page', 'post_content' => '' // Elementor uses meta, not content ]); if (!is_wp_error($page_id)) { // Save Elementor data update_post_meta($page_id, '_elementor_data', wp_slash(json_encode($layout['content']))); update_post_meta($page_id, '_elementor_edit_mode', 'builder'); update_post_meta($page_id, '_elementor_template_type', 'wp-page'); update_post_meta($page_id, '_elementor_version', '3.16.0'); echo "✅ Created: {$city['city']} (ID: {$page_id})\n"; } } function replace_placeholders($data, $replacements) { $json = json_encode($data); foreach ($replacements as $placeholder => $value) { $json = str_replace($placeholder, $value, $json); } return json_decode($json, true); } echo "\n✨ Generation complete!\n"; COMMAND_BLOCK: <?php /** * Elementor Page Generator * Usage: php generate-elementor-pages.php */ // Load WordPress require_once('/path/to/wp-load.php'); // Load data $template = json_decode(file_get_contents('template.json'), true); $cities = json_decode(file_get_contents('cities.json'), true); foreach ($cities as $city) { // Replace placeholders in template $layout = replace_placeholders($template, [ '{{CITY_NAME}}' => $city['city'], '{{STATE}}' => $city['state'], '{{ZIP}}' => $city['zip'], '{{PHONE}}' => $city['phone'] ]); // Create page $page_id = wp_insert_post([ 'post_title' => $city['city'] . ' Services', 'post_status' => 'publish', 'post_type' => 'page', 'post_content' => '' // Elementor uses meta, not content ]); if (!is_wp_error($page_id)) { // Save Elementor data update_post_meta($page_id, '_elementor_data', wp_slash(json_encode($layout['content']))); update_post_meta($page_id, '_elementor_edit_mode', 'builder'); update_post_meta($page_id, '_elementor_template_type', 'wp-page'); update_post_meta($page_id, '_elementor_version', '3.16.0'); echo "✅ Created: {$city['city']} (ID: {$page_id})\n"; } } function replace_placeholders($data, $replacements) { $json = json_encode($data); foreach ($replacements as $placeholder => $value) { $json = str_replace($placeholder, $value, $json); } return json_decode($json, true); } echo "\n✨ Generation complete!\n"; CODE_BLOCK: php generate-elementor-pages.php Enter fullscreen mode Exit fullscreen mode CODE_BLOCK: php generate-elementor-pages.php CODE_BLOCK: php generate-elementor-pages.php CODE_BLOCK: ✅ Created: Chicago (ID: 123) ✅ Created: Boston (ID: 124) ✅ Created: Seattle (ID: 125) ✨ Generation complete! Enter fullscreen mode Exit fullscreen mode CODE_BLOCK: ✅ Created: Chicago (ID: 123) ✅ Created: Boston (ID: 124) ✅ Created: Seattle (ID: 125) ✨ Generation complete! CODE_BLOCK: ✅ Created: Chicago (ID: 123) ✅ Created: Boston (ID: 124) ✅ Created: Seattle (ID: 125) ✨ Generation complete! CODE_BLOCK: [ { "type": "et_pb_section", "attrs": { "background_color": "#ffffff" }, "content": [ { "type": "et_pb_row", "content": [ { "type": "et_pb_column", "content": [ { "type": "et_pb_text", "attrs": { "content": "<h1>{{CITY_NAME}} Professional Services</h1>" } } ] } ] } ] } ] Enter fullscreen mode Exit fullscreen mode CODE_BLOCK: [ { "type": "et_pb_section", "attrs": { "background_color": "#ffffff" }, "content": [ { "type": "et_pb_row", "content": [ { "type": "et_pb_column", "content": [ { "type": "et_pb_text", "attrs": { "content": "<h1>{{CITY_NAME}} Professional Services</h1>" } } ] } ] } ] } ] CODE_BLOCK: [ { "type": "et_pb_section", "attrs": { "background_color": "#ffffff" }, "content": [ { "type": "et_pb_row", "content": [ { "type": "et_pb_column", "content": [ { "type": "et_pb_text", "attrs": { "content": "<h1>{{CITY_NAME}} Professional Services</h1>" } } ] } ] } ] } ] COMMAND_BLOCK: <?php require_once('/path/to/wp-load.php'); $template = json_decode(file_get_contents('divi-template.json'), true); $cities = json_decode(file_get_contents('cities.json'), true); foreach ($cities as $city) { $layout = replace_placeholders($template, [ '{{CITY_NAME}}' => $city['city'], '{{STATE}}' => $city['state'] ]); $page_id = wp_insert_post([ 'post_title' => $city['city'] . ' Services', 'post_status' => 'publish', 'post_type' => 'page' ]); if (!is_wp_error($page_id)) { // Divi-specific meta update_post_meta($page_id, '_et_pb_use_builder', 'on'); update_post_meta($page_id, '_et_pb_page_layout', wp_slash(json_encode($layout))); update_post_meta($page_id, '_et_pb_old_content', ''); echo "✅ Divi page: {$city['city']}\n"; } } Enter fullscreen mode Exit fullscreen mode COMMAND_BLOCK: <?php require_once('/path/to/wp-load.php'); $template = json_decode(file_get_contents('divi-template.json'), true); $cities = json_decode(file_get_contents('cities.json'), true); foreach ($cities as $city) { $layout = replace_placeholders($template, [ '{{CITY_NAME}}' => $city['city'], '{{STATE}}' => $city['state'] ]); $page_id = wp_insert_post([ 'post_title' => $city['city'] . ' Services', 'post_status' => 'publish', 'post_type' => 'page' ]); if (!is_wp_error($page_id)) { // Divi-specific meta update_post_meta($page_id, '_et_pb_use_builder', 'on'); update_post_meta($page_id, '_et_pb_page_layout', wp_slash(json_encode($layout))); update_post_meta($page_id, '_et_pb_old_content', ''); echo "✅ Divi page: {$city['city']}\n"; } } COMMAND_BLOCK: <?php require_once('/path/to/wp-load.php'); $template = json_decode(file_get_contents('divi-template.json'), true); $cities = json_decode(file_get_contents('cities.json'), true); foreach ($cities as $city) { $layout = replace_placeholders($template, [ '{{CITY_NAME}}' => $city['city'], '{{STATE}}' => $city['state'] ]); $page_id = wp_insert_post([ 'post_title' => $city['city'] . ' Services', 'post_status' => 'publish', 'post_type' => 'page' ]); if (!is_wp_error($page_id)) { // Divi-specific meta update_post_meta($page_id, '_et_pb_use_builder', 'on'); update_post_meta($page_id, '_et_pb_page_layout', wp_slash(json_encode($layout))); update_post_meta($page_id, '_et_pb_old_content', ''); echo "✅ Divi page: {$city['city']}\n"; } } COMMAND_BLOCK: <?php /** * Plugin Name: Page Generator CLI */ if (defined('WP_CLI') && WP_CLI) { WP_CLI::add_command('generate pages', 'Page_Generator_CLI'); } class Page_Generator_CLI { /** * Generate pages from template * * ## OPTIONS * * --template=<file> * : Template JSON file * * --data=<file> * : Data JSON file * * --builder=<name> * : Page builder (elementor|divi|beaver) * * ## EXAMPLES * * wp generate pages --template=template.json --data=cities.json --builder=elementor */ public function __invoke($args, $assoc_args) { $template_file = $assoc_args['template']; $data_file = $assoc_args['data']; $builder = $assoc_args['builder']; if (!file_exists($template_file)) { WP_CLI::error("Template file not found: {$template_file}"); } if (!file_exists($data_file)) { WP_CLI::error("Data file not found: {$data_file}"); } $template = json_decode(file_get_contents($template_file), true); $data = json_decode(file_get_contents($data_file), true); $generated = 0; foreach ($data as $item) { $page_id = $this->create_page($template, $item, $builder); if ($page_id) { WP_CLI::success("Created page ID {$page_id}: {$item['city']}"); $generated++; } } WP_CLI::success("Generated {$generated} pages!"); } private function create_page($template, $data, $builder) { // Replace placeholders $layout = $this->replace_placeholders($template, $data); // Create page $page_id = wp_insert_post([ 'post_title' => $data['city'] . ' Services', 'post_status' => 'publish', 'post_type' => 'page' ]); if (is_wp_error($page_id)) { return false; } // Save builder-specific meta switch ($builder) { case 'elementor': update_post_meta($page_id, '_elementor_data', wp_slash(json_encode($layout))); update_post_meta($page_id, '_elementor_edit_mode', 'builder'); break; case 'divi': update_post_meta($page_id, '_et_pb_use_builder', 'on'); update_post_meta($page_id, '_et_pb_page_layout', wp_slash(json_encode($layout))); break; case 'beaver': update_post_meta($page_id, '_fl_builder_enabled', '1'); update_post_meta($page_id, '_fl_builder_data', $layout); break; } return $page_id; } private function replace_placeholders($data, $replacements) { $json = json_encode($data); // Build replacement map $search = []; $replace = []; foreach ($replacements as $key => $value) { $search[] = '{{' . strtoupper($key) . '}}'; $replace[] = $value; } $json = str_replace($search, $replace, $json); return json_decode($json, true); } } Enter fullscreen mode Exit fullscreen mode COMMAND_BLOCK: <?php /** * Plugin Name: Page Generator CLI */ if (defined('WP_CLI') && WP_CLI) { WP_CLI::add_command('generate pages', 'Page_Generator_CLI'); } class Page_Generator_CLI { /** * Generate pages from template * * ## OPTIONS * * --template=<file> * : Template JSON file * * --data=<file> * : Data JSON file * * --builder=<name> * : Page builder (elementor|divi|beaver) * * ## EXAMPLES * * wp generate pages --template=template.json --data=cities.json --builder=elementor */ public function __invoke($args, $assoc_args) { $template_file = $assoc_args['template']; $data_file = $assoc_args['data']; $builder = $assoc_args['builder']; if (!file_exists($template_file)) { WP_CLI::error("Template file not found: {$template_file}"); } if (!file_exists($data_file)) { WP_CLI::error("Data file not found: {$data_file}"); } $template = json_decode(file_get_contents($template_file), true); $data = json_decode(file_get_contents($data_file), true); $generated = 0; foreach ($data as $item) { $page_id = $this->create_page($template, $item, $builder); if ($page_id) { WP_CLI::success("Created page ID {$page_id}: {$item['city']}"); $generated++; } } WP_CLI::success("Generated {$generated} pages!"); } private function create_page($template, $data, $builder) { // Replace placeholders $layout = $this->replace_placeholders($template, $data); // Create page $page_id = wp_insert_post([ 'post_title' => $data['city'] . ' Services', 'post_status' => 'publish', 'post_type' => 'page' ]); if (is_wp_error($page_id)) { return false; } // Save builder-specific meta switch ($builder) { case 'elementor': update_post_meta($page_id, '_elementor_data', wp_slash(json_encode($layout))); update_post_meta($page_id, '_elementor_edit_mode', 'builder'); break; case 'divi': update_post_meta($page_id, '_et_pb_use_builder', 'on'); update_post_meta($page_id, '_et_pb_page_layout', wp_slash(json_encode($layout))); break; case 'beaver': update_post_meta($page_id, '_fl_builder_enabled', '1'); update_post_meta($page_id, '_fl_builder_data', $layout); break; } return $page_id; } private function replace_placeholders($data, $replacements) { $json = json_encode($data); // Build replacement map $search = []; $replace = []; foreach ($replacements as $key => $value) { $search[] = '{{' . strtoupper($key) . '}}'; $replace[] = $value; } $json = str_replace($search, $replace, $json); return json_decode($json, true); } } COMMAND_BLOCK: <?php /** * Plugin Name: Page Generator CLI */ if (defined('WP_CLI') && WP_CLI) { WP_CLI::add_command('generate pages', 'Page_Generator_CLI'); } class Page_Generator_CLI { /** * Generate pages from template * * ## OPTIONS * * --template=<file> * : Template JSON file * * --data=<file> * : Data JSON file * * --builder=<name> * : Page builder (elementor|divi|beaver) * * ## EXAMPLES * * wp generate pages --template=template.json --data=cities.json --builder=elementor */ public function __invoke($args, $assoc_args) { $template_file = $assoc_args['template']; $data_file = $assoc_args['data']; $builder = $assoc_args['builder']; if (!file_exists($template_file)) { WP_CLI::error("Template file not found: {$template_file}"); } if (!file_exists($data_file)) { WP_CLI::error("Data file not found: {$data_file}"); } $template = json_decode(file_get_contents($template_file), true); $data = json_decode(file_get_contents($data_file), true); $generated = 0; foreach ($data as $item) { $page_id = $this->create_page($template, $item, $builder); if ($page_id) { WP_CLI::success("Created page ID {$page_id}: {$item['city']}"); $generated++; } } WP_CLI::success("Generated {$generated} pages!"); } private function create_page($template, $data, $builder) { // Replace placeholders $layout = $this->replace_placeholders($template, $data); // Create page $page_id = wp_insert_post([ 'post_title' => $data['city'] . ' Services', 'post_status' => 'publish', 'post_type' => 'page' ]); if (is_wp_error($page_id)) { return false; } // Save builder-specific meta switch ($builder) { case 'elementor': update_post_meta($page_id, '_elementor_data', wp_slash(json_encode($layout))); update_post_meta($page_id, '_elementor_edit_mode', 'builder'); break; case 'divi': update_post_meta($page_id, '_et_pb_use_builder', 'on'); update_post_meta($page_id, '_et_pb_page_layout', wp_slash(json_encode($layout))); break; case 'beaver': update_post_meta($page_id, '_fl_builder_enabled', '1'); update_post_meta($page_id, '_fl_builder_data', $layout); break; } return $page_id; } private function replace_placeholders($data, $replacements) { $json = json_encode($data); // Build replacement map $search = []; $replace = []; foreach ($replacements as $key => $value) { $search[] = '{{' . strtoupper($key) . '}}'; $replace[] = $value; } $json = str_replace($search, $replace, $json); return json_decode($json, true); } } COMMAND_BLOCK: # Generate 50 city pages wp generate pages \ --template=elementor-template.json \ --data=cities.json \ --builder=elementor # Output: # Success: Created page ID 123: Chicago # Success: Created page ID 124: Boston # Success: Created page ID 125: Seattle # Success: Generated 50 pages! Enter fullscreen mode Exit fullscreen mode COMMAND_BLOCK: # Generate 50 city pages wp generate pages \ --template=elementor-template.json \ --data=cities.json \ --builder=elementor # Output: # Success: Created page ID 123: Chicago # Success: Created page ID 124: Boston # Success: Created page ID 125: Seattle # Success: Generated 50 pages! COMMAND_BLOCK: # Generate 50 city pages wp generate pages \ --template=elementor-template.json \ --data=cities.json \ --builder=elementor # Output: # Success: Created page ID 123: Chicago # Success: Created page ID 124: Boston # Success: Created page ID 125: Seattle # Success: Generated 50 pages! COMMAND_BLOCK: <?php add_action('rest_api_init', function() { register_rest_route('page-gen/v1', '/create', [ 'methods' => 'POST', 'callback' => 'generate_page_via_api', 'permission_callback' => function() { return current_user_can('edit_pages'); } ]); }); function generate_page_via_api($request) { $params = $request->get_json_params(); $template = $params['template']; $data = $params['data']; $builder = $params['builder']; // Replace placeholders $layout = replace_placeholders($template, $data); // Create page $page_id = wp_insert_post([ 'post_title' => $data['title'], 'post_status' => 'publish', 'post_type' => 'page' ]); // Save builder meta if ($builder === 'elementor') { update_post_meta($page_id, '_elementor_data', wp_slash(json_encode($layout))); update_post_meta($page_id, '_elementor_edit_mode', 'builder'); } return new WP_REST_Response([ 'success' => true, 'page_id' => $page_id, 'url' => get_permalink($page_id) ], 201); } Enter fullscreen mode Exit fullscreen mode COMMAND_BLOCK: <?php add_action('rest_api_init', function() { register_rest_route('page-gen/v1', '/create', [ 'methods' => 'POST', 'callback' => 'generate_page_via_api', 'permission_callback' => function() { return current_user_can('edit_pages'); } ]); }); function generate_page_via_api($request) { $params = $request->get_json_params(); $template = $params['template']; $data = $params['data']; $builder = $params['builder']; // Replace placeholders $layout = replace_placeholders($template, $data); // Create page $page_id = wp_insert_post([ 'post_title' => $data['title'], 'post_status' => 'publish', 'post_type' => 'page' ]); // Save builder meta if ($builder === 'elementor') { update_post_meta($page_id, '_elementor_data', wp_slash(json_encode($layout))); update_post_meta($page_id, '_elementor_edit_mode', 'builder'); } return new WP_REST_Response([ 'success' => true, 'page_id' => $page_id, 'url' => get_permalink($page_id) ], 201); } COMMAND_BLOCK: <?php add_action('rest_api_init', function() { register_rest_route('page-gen/v1', '/create', [ 'methods' => 'POST', 'callback' => 'generate_page_via_api', 'permission_callback' => function() { return current_user_can('edit_pages'); } ]); }); function generate_page_via_api($request) { $params = $request->get_json_params(); $template = $params['template']; $data = $params['data']; $builder = $params['builder']; // Replace placeholders $layout = replace_placeholders($template, $data); // Create page $page_id = wp_insert_post([ 'post_title' => $data['title'], 'post_status' => 'publish', 'post_type' => 'page' ]); // Save builder meta if ($builder === 'elementor') { update_post_meta($page_id, '_elementor_data', wp_slash(json_encode($layout))); update_post_meta($page_id, '_elementor_edit_mode', 'builder'); } return new WP_REST_Response([ 'success' => true, 'page_id' => $page_id, 'url' => get_permalink($page_id) ], 201); } CODE_BLOCK: // Node.js example const axios = require('axios'); async function generatePages() { const template = require('./template.json'); const cities = require('./cities.json'); for (const city of cities) { const response = await axios.post( 'https://yoursite.com/wp-json/page-gen/v1/create', { template: template, data: { title: `${city.city} Services`, ...city }, builder: 'elementor' }, { auth: { username: 'admin', password: 'application-password' } } ); console.log(`✅ Created: ${response.data.url}`); } } generatePages(); Enter fullscreen mode Exit fullscreen mode CODE_BLOCK: // Node.js example const axios = require('axios'); async function generatePages() { const template = require('./template.json'); const cities = require('./cities.json'); for (const city of cities) { const response = await axios.post( 'https://yoursite.com/wp-json/page-gen/v1/create', { template: template, data: { title: `${city.city} Services`, ...city }, builder: 'elementor' }, { auth: { username: 'admin', password: 'application-password' } } ); console.log(`✅ Created: ${response.data.url}`); } } generatePages(); CODE_BLOCK: // Node.js example const axios = require('axios'); async function generatePages() { const template = require('./template.json'); const cities = require('./cities.json'); for (const city of cities) { const response = await axios.post( 'https://yoursite.com/wp-json/page-gen/v1/create', { template: template, data: { title: `${city.city} Services`, ...city }, builder: 'elementor' }, { auth: { username: 'admin', password: 'application-password' } } ); console.log(`✅ Created: ${response.data.url}`); } } generatePages(); CODE_BLOCK: city,state,zip,phone,lat,lng Chicago,IL,60601,(312) 555-0100,41.8781,-87.6298 Boston,MA,02108,(617) 555-0200,42.3601,-71.0589 Enter fullscreen mode Exit fullscreen mode CODE_BLOCK: city,state,zip,phone,lat,lng Chicago,IL,60601,(312) 555-0100,41.8781,-87.6298 Boston,MA,02108,(617) 555-0200,42.3601,-71.0589 CODE_BLOCK: city,state,zip,phone,lat,lng Chicago,IL,60601,(312) 555-0100,41.8781,-87.6298 Boston,MA,02108,(617) 555-0200,42.3601,-71.0589 COMMAND_BLOCK: <?php require_once('wp-load.php'); $template = json_decode(file_get_contents('hvac-template.json'), true); $csv = array_map('str_getcsv', file('hvac-locations.csv')); $headers = array_shift($csv); foreach ($csv as $row) { $location = array_combine($headers, $row); $layout = replace_placeholders($template, [ '{{CITY}}' => $location['city'], '{{STATE}}' => $location['state'], '{{PHONE}}' => $location['phone'], '{{LAT}}' => $location['lat'], '{{LNG}}' => $location['lng'] ]); $page_id = wp_insert_post([ 'post_title' => "HVAC Services in {$location['city']}, {$location['state']}", 'post_name' => sanitize_title("hvac-{$location['city']}-{$location['state']}"), 'post_status' => 'publish', 'post_type' => 'page' ]); update_post_meta($page_id, '_elementor_data', wp_slash(json_encode($layout))); update_post_meta($page_id, '_elementor_edit_mode', 'builder'); // SEO meta update_post_meta($page_id, '_yoast_wpseo_title', "HVAC Services {$location['city']}, {$location['state']} | Company Name"); update_post_meta($page_id, '_yoast_wpseo_metadesc', "Professional HVAC services in {$location['city']}, {$location['state']}. Call {$location['phone']} today!"); echo "✅ {$location['city']}, {$location['state']}\n"; } Enter fullscreen mode Exit fullscreen mode COMMAND_BLOCK: <?php require_once('wp-load.php'); $template = json_decode(file_get_contents('hvac-template.json'), true); $csv = array_map('str_getcsv', file('hvac-locations.csv')); $headers = array_shift($csv); foreach ($csv as $row) { $location = array_combine($headers, $row); $layout = replace_placeholders($template, [ '{{CITY}}' => $location['city'], '{{STATE}}' => $location['state'], '{{PHONE}}' => $location['phone'], '{{LAT}}' => $location['lat'], '{{LNG}}' => $location['lng'] ]); $page_id = wp_insert_post([ 'post_title' => "HVAC Services in {$location['city']}, {$location['state']}", 'post_name' => sanitize_title("hvac-{$location['city']}-{$location['state']}"), 'post_status' => 'publish', 'post_type' => 'page' ]); update_post_meta($page_id, '_elementor_data', wp_slash(json_encode($layout))); update_post_meta($page_id, '_elementor_edit_mode', 'builder'); // SEO meta update_post_meta($page_id, '_yoast_wpseo_title', "HVAC Services {$location['city']}, {$location['state']} | Company Name"); update_post_meta($page_id, '_yoast_wpseo_metadesc', "Professional HVAC services in {$location['city']}, {$location['state']}. Call {$location['phone']} today!"); echo "✅ {$location['city']}, {$location['state']}\n"; } COMMAND_BLOCK: <?php require_once('wp-load.php'); $template = json_decode(file_get_contents('hvac-template.json'), true); $csv = array_map('str_getcsv', file('hvac-locations.csv')); $headers = array_shift($csv); foreach ($csv as $row) { $location = array_combine($headers, $row); $layout = replace_placeholders($template, [ '{{CITY}}' => $location['city'], '{{STATE}}' => $location['state'], '{{PHONE}}' => $location['phone'], '{{LAT}}' => $location['lat'], '{{LNG}}' => $location['lng'] ]); $page_id = wp_insert_post([ 'post_title' => "HVAC Services in {$location['city']}, {$location['state']}", 'post_name' => sanitize_title("hvac-{$location['city']}-{$location['state']}"), 'post_status' => 'publish', 'post_type' => 'page' ]); update_post_meta($page_id, '_elementor_data', wp_slash(json_encode($layout))); update_post_meta($page_id, '_elementor_edit_mode', 'builder'); // SEO meta update_post_meta($page_id, '_yoast_wpseo_title', "HVAC Services {$location['city']}, {$location['state']} | Company Name"); update_post_meta($page_id, '_yoast_wpseo_metadesc', "Professional HVAC services in {$location['city']}, {$location['state']}. Call {$location['phone']} today!"); echo "✅ {$location['city']}, {$location['state']}\n"; } COMMAND_BLOCK: // Add ACF fields to generated page update_field('service_area', $location['city'], $page_id); update_field('phone_number', $location['phone'], $page_id); update_field('map_coordinates', [ 'lat' => $location['lat'], 'lng' => $location['lng'] ], $page_id); Enter fullscreen mode Exit fullscreen mode COMMAND_BLOCK: // Add ACF fields to generated page update_field('service_area', $location['city'], $page_id); update_field('phone_number', $location['phone'], $page_id); update_field('map_coordinates', [ 'lat' => $location['lat'], 'lng' => $location['lng'] ], $page_id); COMMAND_BLOCK: // Add ACF fields to generated page update_field('service_area', $location['city'], $page_id); update_field('phone_number', $location['phone'], $page_id); update_field('map_coordinates', [ 'lat' => $location['lat'], 'lng' => $location['lng'] ], $page_id); CODE_BLOCK: { "elType": "widget", "widgetType": "text-editor", "settings": { "editor": "[acf field='service_area']" } } Enter fullscreen mode Exit fullscreen mode CODE_BLOCK: { "elType": "widget", "widgetType": "text-editor", "settings": { "editor": "[acf field='service_area']" } } CODE_BLOCK: { "elType": "widget", "widgetType": "text-editor", "settings": { "editor": "[acf field='service_area']" } } COMMAND_BLOCK: <?php class Page_Generator { private $log = []; public function generate($template, $data) { foreach ($data as $item) { try { $page_id = $this->create_page($template, $item); $this->log[] = "✅ Success: {$item['city']} (ID: {$page_id})"; } catch (Exception $e) { $this->log[] = "❌ Error: {$item['city']} - {$e->getMessage()}"; } } // Save log file_put_contents('generation-log.txt', implode("\n", $this->log)); } private function create_page($template, $item) { $page_id = wp_insert_post([ 'post_title' => $item['city'] . ' Services', 'post_status' => 'publish', 'post_type' => 'page' ]); if (is_wp_error($page_id)) { throw new Exception($page_id->get_error_message()); } // Validate layout before saving if (!$this->validate_layout($template)) { throw new Exception('Invalid layout structure'); } $layout = $this->replace_placeholders($template, $item); update_post_meta($page_id, '_elementor_data', wp_slash(json_encode($layout))); return $page_id; } private function validate_layout($layout) { // Check required fields exist return isset($layout['content']) && is_array($layout['content']); } } Enter fullscreen mode Exit fullscreen mode COMMAND_BLOCK: <?php class Page_Generator { private $log = []; public function generate($template, $data) { foreach ($data as $item) { try { $page_id = $this->create_page($template, $item); $this->log[] = "✅ Success: {$item['city']} (ID: {$page_id})"; } catch (Exception $e) { $this->log[] = "❌ Error: {$item['city']} - {$e->getMessage()}"; } } // Save log file_put_contents('generation-log.txt', implode("\n", $this->log)); } private function create_page($template, $item) { $page_id = wp_insert_post([ 'post_title' => $item['city'] . ' Services', 'post_status' => 'publish', 'post_type' => 'page' ]); if (is_wp_error($page_id)) { throw new Exception($page_id->get_error_message()); } // Validate layout before saving if (!$this->validate_layout($template)) { throw new Exception('Invalid layout structure'); } $layout = $this->replace_placeholders($template, $item); update_post_meta($page_id, '_elementor_data', wp_slash(json_encode($layout))); return $page_id; } private function validate_layout($layout) { // Check required fields exist return isset($layout['content']) && is_array($layout['content']); } } COMMAND_BLOCK: <?php class Page_Generator { private $log = []; public function generate($template, $data) { foreach ($data as $item) { try { $page_id = $this->create_page($template, $item); $this->log[] = "✅ Success: {$item['city']} (ID: {$page_id})"; } catch (Exception $e) { $this->log[] = "❌ Error: {$item['city']} - {$e->getMessage()}"; } } // Save log file_put_contents('generation-log.txt', implode("\n", $this->log)); } private function create_page($template, $item) { $page_id = wp_insert_post([ 'post_title' => $item['city'] . ' Services', 'post_status' => 'publish', 'post_type' => 'page' ]); if (is_wp_error($page_id)) { throw new Exception($page_id->get_error_message()); } // Validate layout before saving if (!$this->validate_layout($template)) { throw new Exception('Invalid layout structure'); } $layout = $this->replace_placeholders($template, $item); update_post_meta($page_id, '_elementor_data', wp_slash(json_encode($layout))); return $page_id; } private function validate_layout($layout) { // Check required fields exist return isset($layout['content']) && is_array($layout['content']); } } - Script runs: 3 minutes - 50 pages created: Identical layouts, unique content - JSON config drives everything - Zero clicking!! - Creating 50+ similar pages (locations, products, services) - Client wants consistent layouts across all pages - Content changes frequently but structure stays same - Testing A/B variations of layouts - Migrating layouts between sites - JSON configuration (layout structure + content variables) - PHP script (reads JSON, generates page builder meta) - WP-CLI command (creates pages programmatically) - Elementor (stores layouts in postmeta _elementor_data) - Divi (stores layouts in _et_pb_page_layout) - Beaver Builder (stores layouts in _fl_builder_data) - WPBakery (stores layouts as shortcodes in post_content) - Oxygen (stores layouts in postmeta ct_builder_shortcodes) - Hero with city name - Service list - Local testimonials - Contact form with city phone - Map embed with city coordinates - Template creation: 2 hours - CSV data prep: 1 hour - Script development: 3 hours - Generation: 5 minutes - Total: 6 hours = 94 hours saved!! - 100+ pages: Minutes not days - Zero human error - Consistent layouts guaranteed - Easy bulk updates (regenerate all pages) - Client thinks you're wizard!! - Build one perfect template manually (1 hour) - Export as JSON (30 seconds) - Prepare data CSV/JSON (30 minutes) - Write generation script (2 hours) - Run script (2 minutes) - Location Sint Maartensdijk - Joined Aug 31, 2025