Migrating a WordPress site to PageMotor
The honest end-to-end walkthrough: what carries over cleanly, what needs rebuilding, and the surprises to plan for before you start.
What you'll need before you start: WordPress admin access to install the exporter; a PageMotor installation running version 0.8.3b or later; PHP 7.0+ on the computer you'll run the translator from (run php -v in Terminal to check); an SFTP client such as Cyberduck (free) or Transmit (Mac); and the three downloads below. Get all three before you begin.
Is this guide the right one for your site? This guide covers Thesis/Focus WordPress sites migrating to an existing PageMotor installation. It will not work for Divi, Gutenberg block-based sites, or WooCommerce shops — those have different export shapes and different importers. The "Beyond this guide" section at the bottom covers those paths and points you at the right tools.
Three things to know before you start
These surprises catch nearly everyone on their first migration. Reading them now saves you an hour of confusion later.
Surprise 1 — The images are on you
The translator rewrites every image path in your content to point at the new location in PageMotor — but it does not move the actual image files. You will need your SFTP credentials, 10–30 minutes depending on how many images your site has, and a client like Cyberduck or Transmit to transfer them manually. Budget for this. Most migrations feel roughly on track until this step, then slow down here.
Surprise 2 — One click makes the site look right
After importing your theme data, the site has no CSS and looks completely broken. This is normal and expected — but only if you know about it. The fix is a single click: open Admin › Theme Settings › Design Options and click Save. That triggers a full CSS recompile from your imported settings. Without it, the site stays unstyled. Do not skip this step, and do not be alarmed when you first see it.
Surprise 3 — Payment forms look right but don't work
Contact forms — name, email, message, phone — migrate cleanly and work fine after you install EP Email. Anything with a payment back-end (Stripe, PayPal), PDF generation, file upload, or conditional logic will appear in the right place in PageMotor and render visually, but the back-end processing that made it charge a card or generate a document does not come with it. If your site has order forms, read the payment form troubleshooting entry before you start, not after.
What migrates automatically
The translator handles all of this without any manual work from you. Once the import is done, these things will be on your PageMotor site exactly as they were on WordPress.
| Content | Status | Notes |
|---|---|---|
| Pages (all levels of nesting) | Migrates | Full parent/child hierarchy preserved, however deep it goes |
| Posts | Migrates | Nested under /blog/ with paginated listing and thumbnails |
| Blog index | Migrates | Paginated listing with thumbnails |
| Top-level navigation menus | Migrates | Flat menus only — see below for dropdowns |
| Footer widgets and menus | Migrates | |
| Focus skin CSS | Migrates | Compiled CSS imported directly; your design looks the same |
| Focus custom CSS | Migrates | Included in the compiled output |
| Focus design options | Migrates | Colours, fonts, layout settings |
| Featured images | Migrates | Injected inline at the top of content; files still need manual transfer (Step 12) |
| Focus Cards | Migrates | Converted to static HTML grids, or to the EP Cards plugin if you run a separate Cards export |
| YouTube embeds | Migrates | Converted to lazy-loading with thumbnail preview |
| Internal links | Migrates | Rewritten to hierarchical paths — /child/ becomes /parent/child/ |
| Contact form shortcodes | Migrates | Gravity Forms, CF7, WPForms shortcodes mapped to EP Email format |
| Breadcrumbs (if used) | Migrates | Auto-detected from Thesis breadcrumb add-on; requires the EP Breadcrumbs plugin (Step 15) |
What does not migrate automatically
| Content | What you'll need to do |
|---|---|
| Dropdown / multi-level menus | Rebuild manually in PageMotor after import |
| Gutenberg block content | Classic Editor only. Gutenberg needs a different migration path — see Beyond this guide |
| Newsletter subscriber lists | Export from your email provider separately |
| Dynamic sidebar widgets | Archives, categories, and tag clouds need rebuilding |
| WooCommerce products, orders, customers | Needs a separate migration — see Beyond this guide |
| Payment form back-ends | Stripe, PayPal, PDF generation, conditional logic do not migrate — forms appear on-page but processing stops working |
| Multilingual content (WPML / Polylang) | Must be migrated one language at a time |
| Multiple user accounts | Author attributions are preserved in content, but additional users must be recreated manually |
Steps in this guide
- Stage 1 — Export from WordPress
- Install the EP WP Exporter
- Run the export
- Clean up WordPress
- Stage 2 — Translate
- Check your PHP version
- Run the translator
- Review the page map
- Stage 3 — Import into PageMotor
- Back up your database
- Install the Focus Bridge Theme
- Import the theme data
- Install Content Types plugin (if generated)
- Recompile CSS ← do not skip
- Transfer images via SFTP
- Run the content migration
- Stage 4 — Configure and test
- Set up contact forms
- Add breadcrumbs (optional)
- Review and test
- Something wrong? Jump to troubleshooting →
Stage 1 — Export from WordPress
Install the exporter plugin, pull everything out of WordPress in one file, then uninstall it. The exporter is read-only — it does not change your WordPress site in any way.
1 Install the EP WP Exporter
Log in to your WordPress admin. Go to Plugins › Add New › Upload Plugin, upload ep-wp-exporter-1.4.0.zip, and activate it. That is all you need to do here.
2 Run the export
Go to Tools › EP WP Export. Tick all the boxes: Posts, Pages, Custom Post Types, Navigation Menus, Widgets, Media Manifest, Theme Settings. Click Export for PageMotor and save the JSON file that downloads. The filename will include your site name and today's date — keep it somewhere you can find it.
This one file contains everything: your content, menus, widgets, compiled CSS, and all your Focus skin settings.
Migrating Focus Cards to the EP Cards plugin? If your site uses Focus Cards and you want them managed natively in PageMotor's EP Cards plugin rather than converted to static HTML, run a second export: untick everything, tick only Focus Cards (for EP Cards Importer add-on). This produces a separate smaller JSON file for the EP Cards importer. See the EP Cards announcement for download links and import instructions.
3 Clean up WordPress
Deactivate and delete the EP WP Exporter plugin. You are done with it.
Stage 2 — Translate
The translator converts your WordPress export JSON into three files PageMotor can work with. It runs from the command line and takes under a minute for most sites.
Using Claude Code? If you have Claude Code, you can skip Steps 4–6 and run the entire translation in a single session. Hand it your export JSON and the translator zip and it handles the PHP execution, form-mapping edits, output review, and troubleshooting as one conversation. The manual steps below are here for anyone who prefers to run it themselves.
4 Check your PHP version
The translator is a PHP command-line script. Open Terminal and run:
php -v
You need PHP 7.0 or later. If you see "command not found", you will need to install PHP or add it to your PATH before continuing.
5 Run the translator
Unzip pagemotor-migrator-v2.2.zip to a convenient location (your Downloads folder is fine). Open Terminal and run:
# Navigate into the unzipped folder
cd ~/Downloads/pagemotor-migrator
# Run the translator against your export file
php translate.php /path/to/your-export.json --verbose
The translator auto-detects Focus sites and selects the Focus Bridge theme. You will see a line for each page, post, and menu item it processes.
"No such file or directory"? You need to be inside the unzipped pagemotor-migrator folder before running the translate command. Run ls translate.php — if you see the file listed, you are in the right place. If not, find where you unzipped it and cd there first.
When it finishes, three files appear in the same directory:
| File | What it is |
|---|---|
*-import.txt |
Theme data file. Your blocks, templates, compiled CSS, design options, menus, and footer. This goes into PageMotor via the admin importer. |
*-content.php |
Content migration script. Inserts all your pages and posts into the PageMotor database when you visit it in a browser. Runs once, then delete it immediately. |
*-pagemap.md |
Page map. Every page and post with its old WordPress URL, new PageMotor URL, content type, and any migration notes. Use this as your testing checklist later. |
Want to preview what the translator will do without writing any files? Add --dry-run to the command.
6 Review the page map
Open the *-pagemap.md file before you import anything. Check that every page and post is accounted for, the new URLs look right, and there are no unexpected notes on any entries. This is also the document you will use as a testing checklist in Step 16.
One thing to expect: WordPress can serve any page at its slug directly (/about/), but PageMotor uses the full hierarchical path (/company/about/). The translator rewrites these in content and menus, but any hardcoded links in unusual HTML may have been missed. The page map is the easiest place to spot-check this.
Stage 3 — Import into PageMotor
This is the longest stage. Steps 9 and 13 write to the database, which is why a backup comes first. Steps 8 and 9 are order-dependent: Focus Bridge must be active before you import. Step 12 (images) takes the most clock time, though most of it is just waiting for files to copy.
7 Back up your database
Use phpMyAdmin, Adminer, or your hosting control panel to export a full SQL dump of your PageMotor database. Save it somewhere safe. If you are importing into a fresh PageMotor installation with nothing in it yet, this is less critical — but it is still good practice and takes two minutes.
8 Install the Focus Bridge Theme
- In PageMotor admin, go to Manage Themes
- Upload
focus-bridge.zip - Activate it
Focus Bridge is a minimal bridge theme — it adds the CSS class hooks (.focus and .mode-focus) that your existing Focus skin expects, so all your styles work without any modifications.
9 Import the theme data
Focus Bridge must be the active theme before you import. The import file is tagged with the Focus Bridge theme class name. PageMotor will reject the file if a different theme is active. Make sure you completed Step 8 and Focus Bridge is your current active theme — not just installed — before continuing.
- Go to Admin › Theme Settings › Theme Data
- Click Import
- Upload the
*-import.txtfile from Step 5
This imports your blocks, templates, menus, footer content, compiled CSS, and all your Focus design option values in one operation.
10 Install the Content Types plugin (if generated)
If the translator generated a *-content-types/ folder alongside the other output files, your WordPress site used custom post types (Focus Cards, Modular Content blocks, or similar) that need to be registered in PageMotor.
- Using SFTP (you will be setting this up in Step 12 anyway), upload the entire
*-content-types/folder touser-content/plugins/on your PageMotor server - In PageMotor admin, go to Manage Plugins and activate the "Content Types" plugin
If the translator did not generate this folder, skip this step. Most Focus Card sites will have one; simpler sites without custom post types will not.
11 Recompile CSS
Do not skip this step. Without it, your site has no CSS at all and will look completely unstyled. It takes ten seconds.
- Go to Admin › Theme Settings › Design Options
- Click Save
The save action always triggers a full CSS recompile from your imported design options. You do not need to change any values — just open the page and click Save. When you reload the front end, your styles should be there.
12 Transfer images via SFTP
The translator rewrites every image path in your content to point at the correct location on PageMotor — but it does not move the actual files. You will need to copy them from your WordPress server to your PageMotor server yourself.
What you will need
- SFTP credentials for your PageMotor server — hostname, username, and password. Find these in your hosting control panel (cPanel, Plesk) or your provider's welcome email. If you cannot find them, contact your hosting provider's support. Not FTP — SFTP, port 22.
- An SFTP client — Cyberduck (free, Mac and Windows), FileZilla (free, all platforms), or Transmit (Mac).
- Your WordPress images — either from your live WordPress server via a second SFTP connection, or from a local backup.
Where things live
On your WordPress server, your images are in wp-content/uploads/, organised in year/month subfolders like 2024/01/, 2024/02/.
On your PageMotor server, images go into user-content/uploads/wp-media/. You may need to create the wp-media subfolder if it does not exist yet.
How to transfer
- Connect to your PageMotor server in your SFTP client using the hostname, username, and password from your hosting control panel. Set the protocol to SFTP and port to 22.
- Navigate to
user-content/uploads/on the server. Create awp-mediafolder here if one does not already exist. - Upload all your WordPress image files into
user-content/uploads/wp-media/, preserving the same folder structure they had inwp-content/uploads/.
Keep the folder structure. A WordPress image at /wp-content/uploads/2024/01/photo.jpg should end up at /user-content/uploads/wp-media/2024/01/photo.jpg on PageMotor. Mirror the year/month subfolders exactly. If your WordPress site had all images in a flat folder (year/month organization disabled), upload them directly into wp-media/ without subfolders.
13 Run the content migration
- Using the SFTP connection from Step 12, upload the
*-content.phpfile to the PageMotor root directory — the top-level folder where you can seeindex.phpandconfig.php. - Visit the file in your browser:
https://your-site.com/your-site-content.php - The script runs through every page and post, printing Created, Updated, or Skipped for each one. When it finishes, it shows a summary with totals.
Delete the script immediately after it finishes. The content migration script has direct database write access and no authentication. Anyone who can reach the URL can run it. As soon as the summary screen appears, delete the file from your server via SFTP. Do not wait until later — do it now.
The script is safe to re-run. If something looks wrong and you need to run it again after fixing something, re-upload and re-visit it. It updates existing content rather than creating duplicates. Just remember to delete it again afterwards.
Stage 4 — Configure and test
Your content is in. This stage connects the working parts and checks that everything landed correctly.
14 Set up contact forms
If your WordPress site had forms, the translator has already converted the shortcodes to EP Email's [contact-form] format and placed them in the right pages. To make them actually send email:
- Install and activate EP Email on your PageMotor site
- Configure SMTP in EP Suite › Email › SMTP Connection — the Mailgun guide covers this in detail if you need it
- The translator maps WordPress form IDs to EP Email form names — check your page map for the exact names used
- For forms with compound name/address fields, star ratings, or conditional logic, also install EP Email Advanced Forms
Form mapping is built into the translator. The translator has a built-in mapping of common WordPress form IDs to EP Email form names. If your site uses unusual IDs or you need different mappings, edit the map_shortcodes() method in translate.php before running the translator.
If your site had no forms, skip this step.
15 Add breadcrumbs (optional)
If your Focus site used the Thesis breadcrumbs add-on, the translator has already placed an EP Breadcrumbs instance above the page title in the content block. You just need the plugin itself.
EP Breadcrumbs v1.2 — Auto-detected from Thesis breadcrumb data. Outputs Schema.org BreadcrumbList JSON-LD.- Upload via Manage Plugins and activate
- Breadcrumbs appear automatically on all pages that use the imported templates
- Optionally configure the default home label and separator in EP Suite › Breadcrumbs
EP Breadcrumbs uses the same CSS class names as Focus breadcrumbs (.crumbs, .crumbs-crumb, .crumbs-sep), so your existing breadcrumb styles carry over unchanged.
If your site did not use breadcrumbs, skip this step.
16 Review and test
Open the page map (*-pagemap.md) and use it as your testing checklist. Walk through the site and verify:
- All pages load and display correctly, with the right layout and styles
- Navigation menus work and link to the right URLs
- Internal links resolve correctly (check a few from deep pages back to shallow ones)
- Featured images display at the top of content
- Footer matches your WordPress site
- Contact forms submit and you receive the emails
- Blog index shows posts with thumbnails and pagination works
- Individual blog posts display correctly with dates
- Custom CSS overrides are working
What success looks like. Your PageMotor site should be visually identical to the WordPress version: same layout, same colours, same fonts, same content. The URLs will be hierarchical now (e.g. /parent/child/ instead of just /child/), but the design and content should match exactly.
Beyond this guide
This guide is built around one specific path: Thesis/Focus WordPress → existing PageMotor installation, preserving the Focus design. If your situation is different, here are the right tools for each case.
divi-extract.php handle Divi migrations. For Gutenberg or recipe-blog-style sites, the wp-to-pm-migration Claude Code skill drives the extraction — different content shape, different importer.
Troubleshooting
Open these only if you hit them.
Pages look completely unstyled — no layout, no colours, just plain text
You skipped Step 11. Go to Admin › Theme Settings › Design Options and click Save. This triggers a CSS recompile. Your site will look right after the page reload.
Admin login keeps redirecting to the home page
PageMotor checks two things when you log in: the user must exist in the users table, AND have a type=administrator row in the user_options table. Login succeeds on the first check alone — but then every /admin/* URL silently redirects to the front page. If you created your admin user manually (rather than via the installer), run this once in your hosting control panel's SQL tool:
INSERT INTO pm_user_options (user_id, name, value)
VALUES (<user-id>, 'type', 'administrator');
Replace <user-id> with the numeric ID of your admin user, and pm_ with your table prefix if you changed it during installation. The translator handles this correctly on fresh installs, so this fix is only needed if you created the admin user by hand.
On PageMotor 0.10 and later, user options moved to a class-scoped shape: PageMotor reads type from a single PM_Users JSON row, not a flat type row, so the command above is silently ignored. On a 0.10 install use this instead:
INSERT INTO pm_user_options (user_id, name, value)
VALUES (<user-id>, 'PM_Users', '{"type":"administrator"}');
If a PM_Users row already exists for that user, edit its JSON to include "type":"administrator" rather than inserting a second row. The 0.9 command above stays correct for 0.9.x installs.
Import says "does not apply to the current Theme"
The import file is tagged with a theme class name and PageMotor only accepts it if the active theme matches exactly. Two things to check: (1) Is Focus Bridge the active theme, not just installed? Go to Manage Themes and confirm it is activated. (2) Does the class name match? Open your *-import.txt in a text editor — the very first key is "theme":"Focus_Bridge". This must match the Class: line in Focus Bridge's theme.php exactly, including case. If Claude Code generated the import, it may have used a slightly different class name. Edit the value in the import file to match.
My order form (Stripe / payments / PDF generation) does not work after migration
The translator migrates form shortcodes — the form renders on the page and looks correct. It does not migrate the back-end functionality: payment processing, PDF generation, file uploads, conditional logic, or electronic signatures. These are tied to WordPress-specific plugins (Gravity Forms Stripe add-on, Gravity PDF, etc.) with no equivalent on PageMotor today.
Two practical options: (1) Replace the order form with a contact-to-order notice — the customer fills a simple form, you reply manually with a Stripe Payment Link or bank transfer details. This works in days, not weeks. (2) Re-implement as a custom PageMotor plugin — a multi-day developer job, worth it only for high-volume flows. Plain contact forms (name, email, message, optionally phone or subject) migrate cleanly and work fine after Step 14.
Images are broken
The translator rewrites image paths to /user-content/uploads/wp-media/. Make sure your images are uploaded there, preserving the same folder structure they had in wp-content/uploads/. If your WordPress site used year/month subfolders, those must exist on the PageMotor server too — copy the entire folder tree, not just the image files. If images are still broken after checking the folder structure, compare one broken image URL in your browser's dev tools against what is actually on the server via SFTP.
Content migration script shows a blank page
The script bootstraps PageMotor by looking for config.php in its own directory. If it is in the wrong folder, it fails silently with a blank page. Make sure you uploaded it to the PageMotor root — the same directory where index.php and config.php live.
Content migration script times out on a large site
Sites with hundreds of pages may hit PHP's execution time limit. Add set_time_limit(0); as the first line of the content script (immediately after the opening <?php), or ask your hosting provider to raise max_execution_time in your server's PHP configuration. The script is idempotent — if it times out partway through, fix the limit and run it again. It will skip pages that already exist and pick up where it left off.
Terminal says "no such file or directory" when running translate.php
You need to be inside the unzipped pagemotor-migrator folder before running the command. Run ls translate.php — if the file is listed, you are in the right place. If not, find where you unzipped the file and cd there first.
Navigation menu is missing
The menu is imported as an HTML Box inside the Header block. Go to the Theme Editor and confirm that the Header block is assigned to your templates.
Forms show "Form not found"
The form name in the [contact-form] shortcode must match a configured form in EP Email exactly. Open the page with the broken form in the content editor, note the form name in the shortcode, and then check EP Email has a form with that exact name. If not, either add the form in EP Email or update the shortcode to match an existing form name.
Shortcodes showing as raw text on the page
If you can see [contact-form name="…"] or [booking-form] as literal text rather than rendered forms, the plugin that handles that shortcode is not installed or not activated. Install EP Email for contact forms, or the appropriate plugin for other shortcode types.
Internal links point to the wrong pages
WordPress serves pages at their slug alone (/about/). PageMotor requires the full hierarchical path (/company/about/). The translator rewrites these throughout your content and menus, but hardcoded links in unusual HTML structures may have been missed. Check the page map for the correct new URL for each page, then search your content for any remaining old-style short slugs.
I do not know my SFTP credentials
Check your hosting provider's control panel — look for "FTP Accounts" or "SFTP Access". On IONOS it is under Hosting › SFTP & SSH. On cPanel hosts (Bluehost, HostGator, SiteGround), it is under the FTP Accounts section. If you cannot find them, contact your hosting provider's support team — they can reset or provide credentials in a few minutes.
🌱 Not installed yet? If you are setting up PageMotor for the first time before migrating to it, start with Installing PageMotor on Bluehost (or SiteGround), then come back here.
Still stuck? Post where you got to in the PageMotor forum and include the output from the translator or the migration script. Paste the last few lines of what you see — that is usually enough to diagnose it.