How LUXCM Handles Page Exports
Page selection and export — How to handle pages without categories
I deliberately did not make the “Select Pages” mode a copy of the “Select Posts” mode.
At first glance, both screens let you choose items with checkboxes. But pages are fundamentally different from posts.
Posts are grouped through a many-to-many classification system called categories. Pages, by contrast, have no concept of categories in the first place.
Instead, pages are organised through parent–child relationships—in other words, a hierarchy. If you ignore that distinction and migrate pages exactly like posts, the pages become scattered and lose the structure of the original site.

Pages: the “parent” is the site structure itself
In WordPress, posts are managed through a separate taxonomy called “categories,” while pages do not use that taxonomy.
Instead, each page can designate another page as its parent through the post_parent field. The resulting hierarchy is the site’s information architecture.
UIC’s guide to page hierarchy makes clear why this parent-page setting matters: assigning a parent page “automatically creates breadcrumb navigation” and provides editors with “authorial organisation in the back end.”
That was when I realised that “Select Pages” could not be built using the same logic as “Select Posts by Category.”
If that relationship is not migrated, the imported pages may look fine individually, but together they become a collection of disconnected fragments with no clear place in the site.
I applied the lesson from comments directly to pages
In the first article in this series, I discussed WordPress Core Trac ticket #8019.
The issue was that, when importing comments, WordPress assigned new IDs to avoid collisions but failed to update the parent ID that identifies which comment each reply belonged to. As a result, reply threads were broken.
I knew that page hierarchies contained exactly the same trap. Suppose the “About Us” page has ID 12 on the source site, and its child page, “History,” is stored with post_parent = 12. When “About Us” is created on the destination site, however, it will receive an entirely different ID—not 12.
If “History” continues to point to the old ID, 12, that relationship becomes a dead reference pointing to no page on the new site.
That is why I divided page importing into two stages.
In the first stage, all selected pages are created, while each page’s “old parent ID” is recorded.
The parent is not assigned yet, because we do not know what new ID the parent page will receive on the destination site.
Once every page has been created, the second stage uses an “old ID → new ID” mapping table. Each page’s old parent ID is looked up in that table, replaced with the corresponding new ID, and then linked back to its parent.
This is exactly the same principle used to solve the problem addressed in Trac #8019 for comments: to migrate a relationship, you must assume that the IDs of the referenced objects will change, create a mapping table, and use it later to reconnect the relationships.
One limitation I should state plainly
There is one limitation I should state plainly.
This mapping works only when the parent page is included in the same import.
If a user selects only the “History” page and leaves its parent, “About Us,” unselected, the mapping table contains no new ID corresponding to the old ID for “About Us.”
In that situation, “History” is created without its parent relationship restored, at the top level of the hierarchy.
That is not a bug; it is the only logical outcome. There is no way to connect a page to a parent that does not exist. Rather than treating this as an error and stopping the entire import, I let the page be created quietly as a top-level page.
Menus are clearly a separate structure from pages
There is another distinction worth making.
A thread on the WordPress.org support forum illustrates it precisely.
The user had created child pages such as “Our School” and “Curriculum” under “About Us” and wanted the navigation menu to reproduce the same structure.
But the developer of the tool the user was using replied that “importing hierarchical menus—with parent and child menu items—is not supported by default.”

post_parent field and migrating the hierarchy of menu items registered in WordPress navigation menus (wp_nav_menu) involve different data.I think it is important to explain this distinction accurately.
LUX Content Migration’s page-selection mode restores the parent–child relationship between pages—in other words, the post_parent field.
Once that relationship is restored, features that WordPress builds directly from the page hierarchy—such as breadcrumbs and lists of a page’s child pages—will work as expected. But a navigation menu configured manually by an administrator under Appearance → Menus is stored as separate data from the page hierarchy, so it falls outside this plugin’s scope.
The menu must be configured manually—or configured again—by the user after the pages have been migrated to the destination site. I do not want to suggest that the plugin handles this part automatically.
To put the structure in order
Pages are a different kind of data from posts.
They are not classified with category tags; they form the site’s structure through parent–child relationships.
I did not ignore that distinction when building page selection.
That said, this approach depends on the parent page being included in the same import. It is also important to be clear that menu structures are entirely separate data from the page hierarchy, so the plugin does not restore them on your behalf.
I believe it is more useful to distinguish precisely between what the plugin can and cannot do—especially for anyone migrating a site with a real hierarchical structure.
References
- WordPress Core Trac ticket #8019 — Thread structure lost because of comment ID handling errors during WXR import
- UIC RED — Importance of Parent Pages (Site Hierarchy)
- WordPress.org Support Forum — How would I import pages with parents pages and a menu?
