Recipes: WordPress
By the end of this page you have an event site on WordPress with real content, a menu, a footer, a site icon, images and a co-organizer, all from the terminal or through your agent. The commands were tested on the production multisite with a subsite administrator account, same as yours.
How it works, in one line: rapadura wp <site> -- <wp-cli command>.
Everything after -- goes to wp-cli, already pinned to your site and your
user. What is allowed is in WordPress sites.
1. Create the site
rapadura wp create php-sobral-2026 --blueprint event --title "PHP Sobral 2026" --email you@example.com
PHP Sobral 2026 is live at https://php-sobral-2026.rapadura.net (WordPress, blueprint event).
site: https://php-sobral-2026.rapadura.net
wp-admin: https://php-sobral-2026.rapadura.net/wp-admin/
REST: https://php-sobral-2026.rapadura.net/wp-json/wp/v2/
WordPress login: yourlogin
application password (shown once): xxxx xxxx xxxx xxxx xxxx xxxx
note: Shown once. It signs your agent in to the WordPress REST API as you (HTTP basic auth). Application passwords belong to your WordPress account, not to one site: it works on every site of the network where you have a role, and has no permissions anywhere else. Keep it like a token; revoke it in wp-admin › Users › Profile if it leaks.
next: Edit content with wp-cli: rapadura wp php-sobral-2026.rapadura.net -- post list --post_type=page
next: Or use the REST API at https://php-sobral-2026.rapadura.net/wp-json/wp/v2/ with HTTP basic auth: yourlogin and the application password.
next: To log into https://php-sobral-2026.rapadura.net/wp-admin/ in a browser, set a password with: rapadura wp password php-sobral-2026.rapadura.net
Keep the application password: it is shown once and it is what gives
access to the REST API (step 8). Lost it? rapadura wp credentials php-sobral-2026 mints another. --email is only needed the first time.
Blueprints: blank (empty), event (home, schedule, speakers, venue,
registration), meetup (next meetup, past editions, give a talk) and
course (about, syllabus, enroll). rapadura wp blueprints lists them. The
blueprint pages are in Portuguese, with placeholder text.
Create a WordPress site on rapadura called php-sobral-2026 with the event blueprint and the title "PHP Sobral 2026". Keep the application password in this session only, never in a file, and tell me the address and the wp-admin link.2. See what came with it
rapadura wp php-sobral-2026 -- post list --post_type=page --fields=ID,post_title,post_name
ID post_title post_name
6 Local local
7 Inscrições inscricoes
5 Palestrantes palestrantes
4 Programação programacao
3 Início inicio
The blueprint pages come with placeholder text. The blueprint has also set up the top menu (step 5) and the footer (step 6), and deleted the "Sample Page" and "Hello world!" post WordPress puts on every new site.
The blank blueprint does none of this: the site stays as WordPress made
it. To delete the two samples on a blank site:
rapadura wp php-sobral-2026 -- post delete 2 1 --force
3. Replace a page's content with your own file
Write the content on your computer. With block markup
(<!-- wp:... -->) the editor opens each part as an editable block; plain
HTML works too, as a "Classic" block.
<!-- programacao.html -->
<!-- wp:heading -->
<h2 class="wp-block-heading">Saturday, November 14</h2>
<!-- /wp:heading -->
<!-- wp:table -->
<figure class="wp-block-table"><table><tbody>
<tr><td>09:00</td><td>Check-in</td></tr>
<tr><td>09:30</td><td>Opening</td></tr>
<tr><td>10:00</td><td>PHP 8.5 in practice</td></tr>
</tbody></table></figure>
<!-- /wp:table -->
ID=$(rapadura wp php-sobral-2026 -- post list --post_type=page --name=programacao --field=ID)
rapadura wp php-sobral-2026 -- post update "$ID" --post_content="$(cat programacao.html)"
Success: Updated post 4.
The content travels inside the command, hence the $(cat ...). Passing
the file name (post update 4 programacao.html) does not work: wp-cli runs
on the server and would look for the file there, and rapadura refuses it.
For very large pages (above roughly 100 KB), use the REST API (step 9).
4. Create a new page
rapadura wp php-sobral-2026 -- post create --post_type=page --post_status=publish \
--post_title="Sponsors" --post_name=sponsors \
--post_content="<!-- wp:paragraph --><p>Want to support us? Write to contato@phpcomrapadura.org.</p><!-- /wp:paragraph -->" \
--porcelain
11
--porcelain prints only the new page's ID, handy for scripts and agents.
5. Top menu
The network's theme is Twenty Twenty-Five, a block theme. Menus made
with wp menu do not show up in it: the header uses a navigation block,
which reads the site's most recent navigation post.
The blueprint has already created that post, "Menu principal", with a link
to every page except the home page, labeled with the page titles in
blueprint order. To change items, order or labels, update the post with the
whole list, one navigation-link per item:
MENU=$(rapadura wp php-sobral-2026 -- post list --post_type=wp_navigation --field=ID)
rapadura wp php-sobral-2026 -- post update "$MENU" \
--post_content='<!-- wp:navigation-link {"label":"Schedule","url":"/programacao/"} /--><!-- wp:navigation-link {"label":"Speakers","url":"/palestrantes/"} /--><!-- wp:navigation-link {"label":"Venue","url":"/local/"} /--><!-- wp:navigation-link {"label":"Register","url":"/inscricoes/"} /-->'
Success: Updated post 8.
A blank site has no such post yet. Create it with the same content:
rapadura wp php-sobral-2026 -- post create --post_type=wp_navigation --post_status=publish \
--post_title="Main menu" --post_content='<!-- wp:navigation-link {"label":"Schedule","url":"/programacao/"} /-->' --porcelain
6. Footer
The theme's default footer has sample links (Blog, About, FAQs, Shop...).
The blueprint has already replaced it with one line carrying the site title,
in Portuguese like the rest of the blueprint: "PHP Sobral 2026 · uma
realização da comunidade PHP Com Rapadura". It is your own version of the
theme's "footer" part, a wp_template_part post. To change the text,
update that post:
ID=$(rapadura wp php-sobral-2026 -- post list --post_type=wp_template_part --name=footer --field=ID)
rapadura wp php-sobral-2026 -- post update "$ID" \
--post_content='<!-- wp:group {"layout":{"type":"constrained"}} --><div class="wp-block-group"><!-- wp:paragraph {"align":"center"} --><p class="has-text-align-center">PHP Sobral 2026 · organized by the <a href="https://phpcomrapadura.org">PHP Com Rapadura</a> community</p><!-- /wp:paragraph --></div><!-- /wp:group -->'
rapadura wp php-sobral-2026 -- cache flush
Success: Updated post 9.
Success: The cache was flushed.
On a blank site the footer is still the theme's. Create your own version
and tie it to the theme and to the footer area; without the two
post term set lines WordPress ignores the post:
ID=$(rapadura wp php-sobral-2026 -- post create --post_type=wp_template_part --post_status=publish \
--post_name=footer --post_title=Footer --porcelain \
--post_content='<!-- wp:group {"layout":{"type":"constrained"}} --><div class="wp-block-group"><!-- wp:paragraph {"align":"center"} --><p class="has-text-align-center">PHP Sobral 2026 · organized by the <a href="https://phpcomrapadura.org">PHP Com Rapadura</a> community</p><!-- /wp:paragraph --></div><!-- /wp:group -->')
rapadura wp php-sobral-2026 -- post term set "$ID" wp_theme twentytwentyfive
rapadura wp php-sobral-2026 -- post term set "$ID" wp_template_part_area footer
rapadura wp php-sobral-2026 -- cache flush
To go back to the theme's original footer, on any site, delete the post
(post delete "$ID" --force).
7. Title, tagline and icon
rapadura wp php-sobral-2026 -- option update blogname "PHP Sobral 2026"
rapadura wp php-sobral-2026 -- option update blogdescription "The PHP meetup of the Ceará backlands"
ICON=$(rapadura wp php-sobral-2026 -- media import https://www.php.net/images/logos/new-php-logo.png --title="Logo" --porcelain)
rapadura wp php-sobral-2026 -- option update site_icon "$ICON"
media import takes http(s) addresses: the server downloads the image.
For a file on your computer, use the REST API (next step).
8. Images from your computer (REST API)
With the login and the application password from step 1:
export WP_SITE=https://php-sobral-2026.rapadura.net
export WP_AUTH="yourlogin:xxxx xxxx xxxx xxxx xxxx xxxx"
curl -s -u "$WP_AUTH" \
-H "Content-Disposition: attachment; filename=palco.png" \
-H "Content-Type: image/png" \
--data-binary @palco.png \
"$WP_SITE/wp-json/wp/v2/media" | jq '{id, source_url}'
{
"id": 15,
"source_url": "https://php-sobral-2026.rapadura.net/wp-content/uploads/sites/7/2026/10/palco.png"
}
To put the image on a page, use source_url in an image block:
<!-- wp:image --><figure class="wp-block-image"><img src="https://php-sobral-2026.rapadura.net/wp-content/uploads/sites/7/2026/10/palco.png" alt="The PHP Sobral stage"/></figure><!-- /wp:image -->
Upload space per site is 100 MB.
9. Pages through the REST API
The same application password creates and edits pages. Good for agents that prefer HTTP, and for large content.
# list
curl -s -u "$WP_AUTH" "$WP_SITE/wp-json/wp/v2/pages?per_page=50&_fields=id,slug,title"
# create
curl -s -u "$WP_AUTH" -H "Content-Type: application/json" \
-d '{"title":"Code of conduct","slug":"conduct","status":"publish","content":"<!-- wp:paragraph --><p>Respect above all.</p><!-- /wp:paragraph -->"}' \
"$WP_SITE/wp-json/wp/v2/pages" | jq '{id, link}'
{
"id": 16,
"link": "https://php-sobral-2026.rapadura.net/conduct/"
}
# update page 16
curl -s -u "$WP_AUTH" -H "Content-Type: application/json" \
-d '{"status":"draft"}' "$WP_SITE/wp-json/wp/v2/pages/16" | jq '{id, status}'
The password belongs to your WordPress account, not to this one site: it works on every site of the network where you have a role (your own sites) and has no permissions anywhere else. The full reference is the WordPress REST API.
10. Bring in a co-organizer
rapadura wp php-sobral-2026 -- user create maria maria@example.com --role=editor
Success: Created user 6.
Password: t7Qx2LmV9rBz1sPw4KcE
The password is shown once; send it to the person over a safe channel. The
login takes lowercase letters and digits only. Roles: editor (all
content), author (their own posts), administrator (the whole site,
appearance included). To change it later: user set-role maria author.
11. Draft, unpublish, delete
rapadura wp php-sobral-2026 -- post update 16 --post_status=draft # offline, kept
rapadura wp php-sobral-2026 -- post delete 16 # to the trash
rapadura wp php-sobral-2026 -- post delete 16 --force # gone for good
12. Back up the content
rapadura wp php-sobral-2026 -- export --stdout > php-sobral-2026.xml
Always --stdout: writing the file on the server (--dir) is refused.
The file is a WXR with pages, posts, menus and references to the images. To
restore it on another site: activate the importer
(plugin activate wordpress-importer) and use Tools › Import in
wp-admin.
13. Replace a string across the site
Always with --dry-run first:
rapadura wp php-sobral-2026 -- search-replace "2025" "2026" --dry-run
rapadura wp php-sobral-2026 -- search-replace "2025" "2026"
rapadura always limits search-replace to your site's tables
(wp_7_posts, wp_7_options...). The output lists each table and how many
replacements it got.
14. For agents: JSON output
With --json before the --, the answer separates output, errors and exit
status:
rapadura --json wp php-sobral-2026 -- option get blogname
{
"host": "php-sobral-2026.rapadura.net",
"args": [
"option",
"get",
"blogname"
],
"stdout": "PHP Sobral 2026\n",
"stderr": "",
"exit_code": 0,
"duration": "1.2s"
}
Over MCP, the wp_cli tool takes the same arguments as a list:
["option", "get", "blogname"].
What you cannot do, and what to do instead
| I want to | what happens | do this |
|---|---|---|
| install a plugin or theme | refused | ask the administrator; today only Twenty Twenty-Five is enabled |
media import ./photo.jpg |
refused: the path would be read on the server | REST API (step 8) or a URL |
post create page.html |
refused, same reason | --post_content="$(cat page.html)" |
wp menu create |
works, but the theme does not show it | a wp_navigation post (step 5) |
| change my password or credentials | user update is refused |
rapadura wp password / rapadura wp credentials |
| touch another site or the network | refused | only your own site is reachable |
Ready-made prompts
On the php-sobral-2026 WordPress site on rapadura, replace the placeholder text of every blueprint page with real content about PHP Sobral 2026 (November 14, Sobral, Ceará). Use WordPress block markup and show me the final list of pages.On php-sobral-2026, relabel the top menu in English (Schedule, Speakers, Venue, Register), add a link to the Sponsors page, and change the footer to say "organized by the PHP Com Rapadura community". Check by opening the home page.Upload the photos in ./photos to the php-sobral-2026 media library through the REST API, using the application password I will paste, and create a "Gallery" page with all of them.Back up the content of php-sobral-2026 to php-sobral-2026.xml and tell me how many pages and images it has.