PageMotor guide
Building your own theme
Three ways to put a structure into a PageMotor site, which of them an AI can actually drive, and why two people a fortnight apart concluded the API could not do something it had been doing all along.
Use this guide with any AI assistant
Download it as a prompt file, paste it into Claude, ChatGPT, Gemini or any LLM, and it will walk you through it.
Start here: which route are you on
Everything below follows from one decision, so make it before you open a chat window.
You want your own structure
A layout that is yours, not a stock Theme bent into shape.
Go toRoute 1, import a bundle. One call, named instances, safety backup taken for you.
You want it driven from the chat
Happy to let the AI build it piece by piece and watch it happen.
Go toRoute 2, the incremental API. It works. You give up control of the instance names.
You do not care about the structure
You want pages on screen and the stock look is fine.
Go toRoute 3, a Theme with a seed. Least work, and least yours.
The instinct that costs people a day. Almost everywhere else in software, extending something that works beats building from scratch. Here it is the other way round. The route that authors a whole Theme in one go is well supported; the route that adapts an existing Theme piece by piece is the awkward one. If you find yourself bending a stock Theme through an API, stop and read Route 1.
What a Theme actually is
Three things, and people usually only count the first.
Options
The instances, blocks, templates, head and CSS, stored as data against the Theme.
Files
A stylesheet, images, scripts. A url(img/…) is relative to the stylesheet, so it breaks the moment you move it.
PHP
theme.php, plus any valet methods the Theme defines for itself.
Copy only the options and you have copied a third of a Theme. That is the single most common reason a "copied" Theme renders wrong.
A seed is the part that matters here
A seed is a Theme's starting architecture: the named instances that make up its pages. Of the Themes that ship with PageMotor, two carry one and one does not.
| Theme | Ships | Means |
|---|---|---|
| Attention | theme.php, seed.php, stylesheets | A full page architecture already built |
| Admin Conductor | theme.php, seed.php, stylesheets | The same, for the admin |
| Blank Slate | theme.php only | Nothing at all. That is the point of it |
Blank Slate's class body is literally empty, and its own header calls it a clean starting point for design conversions. It is not a minimal Theme, it is an absent one, and it is the correct base for building your own. It is the wrong base for asking a chat to furnish it, which is a different sentence and the one that catches people.
Instances inside a seed are named, and the names carry the structure: Page_Container_Home_Page_Title is a Page Title box, inside the Home page container. Hold on to that shape, because it is what Route 2 cannot give you.
The three routes
Route 1: import a bundle
One action takes an entire Theme: instances, blocks, templates, head, the CSS keys, design and display. It refuses a bundle whose internal theme key does not match the Theme you are importing into, takes an automatic safety backup first unless you tell it not to, and recompiles the CSS afterwards.
This is the route that produces named instances, and it is reachable three ways: the Theme Data screen in the admin, the REST API, and, on a current release, over MCP. That last one is the part most people do not know, and it is covered in the trap below.
Build the bundle once, keep it in version control, and import it. Changing your mind later is an edit to a file you own rather than a hundred calls you have to repeat.
Route 2: the incremental API
Add an instance, then configure it, one at a time. This genuinely works, and it is the right call when you want to watch the thing being built and correct it as it goes.
The catch is naming. Adding an instance by class mints its id for you, as the class name plus a timestamp. You cannot choose it. So you get a working site whose parts are called things like HTML_Container_179214430081900 rather than Page_Container_Home, and every later conversation about that site is harder for it.
Route 3: a Theme that already has a seed
Start from Attention or Admin Conductor and the page architecture is there before you begin. Cheapest by a distance if you do not want to own the structure.
Be honest with yourself about which you are doing, though. A stock Theme brings its own opinions and they push back: containers cap their width, headings centre themselves, stock CSS partials keep compiling underneath yours unless you switch each one off explicitly. Bending it can cost more than building it.
The trap: your AI cannot see the route that works
Here is the failure, because it has now happened to two people independently, a fortnight apart, and both reached the same wrong conclusion.
1. You ask an AI, connected over MCP, to build a structure into a Theme.
2. It looks for a way to write a Theme's instances and does not find the import action, because on an older core that action is not in the list it can see.
3. It falls back to the bulk writer that is in the list.
4. That writer only updates instances that already exist. Anything new is dropped, and the call reports success anyway.
5. The AI reads the site back, finds most of its work missing, and tells you the API cannot create Theme structure.
Every step of that is the AI behaving correctly on the evidence available to it. The conclusion is still wrong.
Why the import action was invisible
It was never a permissions question. On older cores the Theme's data surface is not built at all unless the request is an admin page or a REST API call. An MCP request is neither, so the object is never created, its actions are never registered, and the action is absent from the menu rather than refused. From inside the chat that is indistinguishable from the feature not existing.
Two gates had to widen for this to change, and they widened together in the same release that removed the bulk writers.
What changed, and when. In 0.11.3 the wholesale writers for instances, blocks and templates were removed, replaced by single-entry equivalents, and the Theme data surface began registering over MCP. So on 0.11.3 and later the misleading endpoint is gone and the good one is reachable from a chat. Before it, the misleading one answered and the good one was invisible.
Two version numbers appear on this page because they are boundaries, not instructions. The instruction is simply: run the current PageMotor release.
If you are on a core older than 0.11.3, nothing on your site will tell you an update exists. The in-band update notice arrived later still, so an older site never nags. Check the admin rather than waiting to be prompted.
How to tell which side of it you are on
Ask your connected AI to list the actions it can see for the Theme, and look for an import action among them. If it is there, Route 1 is available to you from the chat. If it is not, you are on an older core and your options are the admin screen, the REST API, or updating.
Boxes you did not create
Make a page container and two boxes appear inside it that you never asked for, usually a title and a content box, named after their parent.
They are not stray scaffolding. Some boxes declare a container as their custodian and ask to be created with it, so core wires up a page container with the parts a page container needs. Others declare the same custodian without asking to appear automatically, which is why a date and an author box do not show up alongside them.
The naming follows the same parent-then-class shape as a seed, which is why they look hand-written. They effectively are: core wrote them, deliberately.
Where standalone Documents fit
There is a shortcut that looks like it makes all of this unnecessary: have the AI write a complete HTML document and let PageMotor serve it. For a self-contained page, that is a good answer and the right tool.
It is not an answer for a site. A Document is served exactly as stored, which means no Theme, no shared header or navigation, and no shortcodes, so anything a plugin renders through a shortcode stays as literal text on the page. It also stops the content being structured, so the AI you connected to the site can no longer answer questions about it.
The full breakdown of what each surface gives you is in Documents, Boxes and Blank_Slate. Read it before committing a site to Documents.
Quick lookup
| Route | Creates named instances | Drivable from a chat | Best for |
|---|---|---|---|
| Import a bundle | Yes | Yes, on a current release | Your own structure, kept in version control |
| Theme Data screen | Yes | No, it is a browser screen | The same, when you would rather click |
| Incremental API | No, ids are minted | Yes | Watching it built, correcting as it goes |
| Theme with a seed | Already done | Not needed | Not owning the structure at all |
| Standalone Documents | No Theme involved | Yes | One self-contained page, never a whole site |
Questions people ask next
My bulk save said success and nothing happened. Was it lying?
Effectively, yes, on cores before 0.11.3. It updated the instances that already existed and silently ignored the ones that did not, then reported success for the whole call. That endpoint no longer exists; on a current release the same call fails as an unknown action, which is the honest answer.
Should I use a stock Theme or build my own?
Build your own if the design is yours. The usual reasoning, that extending beats starting fresh, does not survive contact with a Theme that has its own opinions about width, alignment and which stylesheets compile. Use a stock Theme when you genuinely want the stock look.
Can I just ask the AI to write standalone HTML instead?
For one page, yes. For a site, you lose shortcodes, shared chrome and the structure that lets an AI answer questions about your own content later. Repetition is cheap to create and expensive to change: the cost arrives on the second change, not the first.
My AI told me the API cannot do this. Was it wrong?
It was right about what it could see and wrong about the product. That is worth knowing in general: an agent reporting a missing capability is reporting on its own visible action list, which depends on your core version and on the transport it connected over. Check the version before accepting the conclusion.