WP-CLI scaffold pipeline
Every WordPress build starts the same way: settings, plugins, pages, menus, SEO defaults, a form. None of it is hard, all of it is repetitive, and doing it by hand for every client is exactly the kind of work that should be templated once and generated after that.
The pipeline
- Gather the client spec — colours, fonts, logo, pages, tone.
- Fill in
spec-template.md. - Open a fresh Claude conversation and feed it, in one go: the completed spec,
vps-base.sh,scaffold-base.sh, the Bricks generation rules + CSS custom properties, and a full worked example (the Hartley Plumbing build). - Claude produces five deliverables (below).
- Spin up a fresh WordPress install on a Hetzner VPS subdomain and run the generated scripts.
- Import the Bricks JSON page by page, wire up WPForms, run Rank Math and Wordfence, tick off the pre-launch checklist, hand off.
The five deliverables
vps-[client].sh— provisions the database, web root, and Nginx vhost for the subdomain.scaffold-[client].sh— the WP-CLI script that configures the install (see below).[client]-asset-requirements.md— every image, font, and placeholder the generated JSON is still waiting on, sourced automatically from scanning the output forPLACEHOLDER:strings.- Per-page Bricks JSON — one file per page, built off the Hartley Plumbing structure with the client's own colours, copy, and services swapped in.
wpforms-[client].json— a ready-to-import form (quote request for trades, contact form otherwise).
What the scaffold script actually does
scaffold-base.sh is the part that used to be forty minutes of clicking through wp-admin. Running it against a fresh install:
wp option update permalink_structure "/%postname%/"
wp option update default_comment_status "closed"
wp config set DISALLOW_FILE_EDIT true --raw
wp plugin install seo-by-rank-math wpforms-lite wp-mail-smtp \
wp-smushit updraftplus wordfence coming-soon --activate
— locks down wp-config.php, strips comments and pingbacks, removes Hello Dolly and Akismet, and installs the standard plugin stack in one pass. It then creates the blank pages (Home, Services, About, Contact, Privacy, Terms, FAQ, plus anything vertical-specific), sets the front page, builds the nav menu, and pre-fills Rank Math's local SEO fields (business type, phone, address, opening hours) so the schema markup is right from the first save.
Every value that's client-specific is a marker like ##[INJECT: business name]## — the base script is never run directly. The generator prompt fills those markers in: subdomain and DB name/user derived from the client's slug, real 16+ character random passwords (not placeholder text), and a WP admin username that's never admin.
Guardrails baked into the prompt
The reason the output can go straight to a terminal without a rewrite is that the generation rules are strict, not just a style guide:
- Australian English throughout, and a banned word list — no "solutions", "seamlessly", "leverage", "tailored", "one-stop shop".
- Bricks element IDs must be exactly six lowercase letters, never mixed with numbers.
- No hardcoded hex values — everything goes through
var(--kd-color-primary)and friends. settingsis always an object, never an array, and_cssGlobalClassessits alongside it, not inside it.
None of these matter much in isolation, but they're the difference between "review it once and import" and "debug a broken Bricks import at 11pm."
What it replaces
A day of manual WordPress setup and page building becomes: fill in one spec sheet, run two scripts, import some JSON. The time saved isn't really the WP-CLI commands — it's not having to remember which of the seven plugins needs configuring in which order, every single time.
