# WordPress sites

Besides static hotsites, rapadura creates **WordPress sites** inside the
`rapadura.net` multisite. It is for people who prefer editing content in
WordPress, or for an agent that builds the site through the REST API and
`wp-cli`.

Each site is a **subsite** `name.rapadura.net`. You are its administrator and
nothing else's. Available themes and plugins are the ones the administrator
enabled on the network; today the theme is Twenty Twenty-Five.

This page is the reference. The step-by-step, with content, menu, footer,
images and a co-organizer, is in [Recipes: WordPress](recipes-wordpress.md).

## Create

```sh
rapadura wp blueprints
rapadura wp create meetup-sobral --blueprint event --title "Meetup Sobral" --email you@example.com
```

- `--blueprint`: `blank` (just the site), `event` (home, schedule, speakers,
  venue, registration), `meetup`, `course`. Pages come with placeholder text
  for the agent to replace. Except for `blank`, the blueprint also sets up
  the top menu and the footer and deletes WordPress's "Sample Page" and
  "Hello world!".
- `--email`: needed the first time only. It becomes your WordPress account's
  email and is remembered.

The answer carries the address, the `wp-admin` URL, your WordPress login
(derived from GitHub, letters and digits only) and an **application
password** shown exactly once. It gives your agent REST API access as you,
**on that site only**. Treat it like a token; if it leaks, revoke it in your
WordPress profile.

## Edit through the REST API

With the login and the application password any HTTP client works:

```sh
curl -u "yourlogin:xxxx xxxx xxxx xxxx xxxx xxxx" \
  https://meetup-sobral.rapadura.net/wp-json/wp/v2/pages
```

Creating pages, uploading images, building menus is a matter of endpoint;
the API documentation is WordPress's own. The password only has power on
this site: on the network's other sites you have no role, and any write is
refused. Upload and page examples are in
[Recipes: WordPress](recipes-wordpress.md#8-images-from-your-computer-rest-api).

## Edit through wp-cli

Everything after `--` goes to `wp-cli`, already pinned to your site and your
user. Do not pass `--url`, `--path` or `--user`; the gateway sets them.

```sh
rapadura wp meetup-sobral -- post list --post_type=page --format=json
rapadura wp meetup-sobral -- post create --post_type=page --post_title="Sponsors" --post_status=publish
rapadura wp meetup-sobral -- post update 4 --post_content="$(cat schedule.html)"
rapadura wp meetup-sobral -- option update blogdescription "PHP community of Ceará"
rapadura wp meetup-sobral -- media import https://example.com/banner.png --title="Banner"
rapadura wp meetup-sobral -- cache flush
```

`wp-cli` runs **on the server**. So files from your computer go in as
content (`--post_content="$(cat file.html)"`) or through the REST API, never
by name: `post create file.html` and `media import ./photo.jpg` are refused.
And since the theme is a block theme, the top menu is a `wp_navigation`
post, not a `wp menu` menu; see
[Recipes: WordPress](recipes-wordpress.md#5-top-menu).

Output and exit status are wp-cli's own. With `--json` you get `stdout`,
`stderr` and `exit_code` separately.

### What is allowed

The rule of thumb: everything that stays **inside your site** is allowed;
anything that reaches the network, other sites, other accounts or files on
the server is refused, with the reason and a hint.

| command | allowed | note |
|---|---|---|
| `post` | everything but `edit` and `generate` | `create`/`update` do not read files: use `--post_content` |
| `post-type`, `taxonomy`, `term`, `comment`, `menu`, `widget`, `sidebar`, `transient`, `rewrite`, `embed`, `help` | everything | no `term`/`comment generate` |
| `export` | with `--stdout` | the WXR comes back to you; writing it on the server (`--dir`, `--filename_format`) is refused |
| `option` | everything | except changing `upload_path`, `upload_url_path` and `active_plugins` (use `plugin activate`) |
| `media` | everything | `import` from http(s) URLs only |
| `search-replace` | yes | always on your site's tables only: rapadura appends `wp_N_*`; no `--export=file`/`--log=file` |
| `cache` | `flush`, `type` | |
| `cron` | `event list`, `event run`, `schedule list`, `test` | no scheduling new events |
| `user` | `list`, `create`, `add-role`, `set-role`, `remove-role` | for your own password and credentials: `rapadura wp password` / `rapadura wp credentials` |
| `plugin` | `list`, `get`, `status`, `activate`, `deactivate`... | no install, update or delete; `activate` only from the list below |
| `theme` | `list`, `get`, `status`, `activate`, `mod`... | no install, update or delete |

`plugin activate` follows a list. The administrator may set the plugins
allowed on your site; when the site has no list of its own, the network's
list applies. A plugin outside the list is refused with `wp_refused` and the
hint names the allowed ones; `--all` is refused whenever a list applies.
`rapadura sites show <site>` shows your site's list.

Always refused: `eval`, `eval-file`, `shell`, `db`, `config`, `core`,
`network`, `site`, `super-admin`, `import`, `language`, `maintenance-mode`,
`package`, `scaffold`, and the flags `--network`, `--all-tables`,
`--blog_id`, `--url`, `--path`, `--user`, `--require`, `--exec`, `--ssh`,
`--http`. A command not on the list is refused until the administrator
allows it.

## Logging into wp-admin

Your WordPress account starts without a known password. To use the browser:

```sh
rapadura wp password meetup-sobral
```

Shows a fresh password once. It is your user's password across the network
(you only have access to your own sites). Change it in your profile if you
like.

## New credentials

```sh
rapadura wp credentials meetup-sobral
```

Mints another application password. Older ones keep working until you revoke
them in your WordPress profile.

An application password belongs to your WordPress account, not to one site:
it works on every site of the network where you have a role (your own sites)
and has no permissions anywhere else.

## Taking a site offline

```sh
rapadura sites delete meetup-sobral --yes
```

The site is **archived**, not deleted: visitors see a notice, the content is
kept, and `rapadura sites restore meetup-sobral` brings it all back.

## Limits and caveats

- WordPress sites have no versions and no `rollback`; history is WordPress's
  own revisions.
- Upload space per site is the network's (100 MB today).
- Only the `rapadura.net` domain for now. Custom domains and
  `phpcomrapadura.org` for WordPress sites come later, with approval.
- Every wp-cli call lands in the audit log with the full command. Do not pass
  secrets as arguments.
