# WordPress

> How midcode runs a WordPress site from its root or from a theme's folder, what it can edit in a classic theme, and why a block theme is mostly out of reach.

- Page: https://midcode.app/docs/frameworks/wordpress
- From the midcode docs. Every page as Markdown: https://midcode.app/llms.txt
- Status: This ships with the next release of midcode. The version you can download today (1.1.2) doesn't have it yet.

midcode opens a WordPress site and edits the markup written in its theme: the header, the footer, the templates and their parts. A classic theme is mostly editable. A block theme mostly isn't, because its pages are drawn by blocks and kept in the database, not written in files. Post and page content is never editable from the canvas: it lives in the database.

WordPress pages reach the canvas without saying where each element is written, so midcode finds each one in the theme's files after the page loads. [Sites a server renders](https://midcode.app/docs/frameworks/server-templates.md) explains how, and what that means for editing.

## At a glance

| | WordPress |
| --- | --- |
| Detected by | `wp-load.php` at the top of the folder, or a theme's `style.css` inside `wp-content/themes/<theme>` |
| Runs with | `php -S 127.0.0.1:$PORT`, with one file of midcode's loaded first |
| Elements are marked by | midcode, after each page loads, by matching it against the theme's `.php` files |
| Editing | Text, classes, attributes and tag; insert, move, duplicate and remove. Only what the theme writes as HTML |
| Pages | Not listed. Type the path |
| Styles | Tailwind 4 classes, or `mid:` utilities with `midcode.css` in the theme's folder, linked from `header.php` |
| Tried with | WordPress 7.1 on SQLite: a classic theme (21 of 23 elements found) and Twenty Twenty-Five (6 of 94) |

## How midcode runs it

You can open either of two folders.

**The whole install**: the folder with `wp-load.php` and `wp-config.php` or `wp-includes/`. midcode runs this in it:

```bash
php -d auto_prepend_file=<midcode's data folder>/injected/wordpress-prepend.php -S 127.0.0.1:$PORT
```

**A theme's folder**: usually the theme is the repository and WordPress is around it. midcode recognises a folder whose `style.css` starts with a `Theme Name:` header and that sits three levels inside an install (`wp-content/themes/<theme>`). It serves that install with the same command plus `-t <path to the install>`.

`$PORT` is a free port midcode picks. The command runs in your login shell, so `php` is the one your terminal would use. What it prints is in the **Dev server log** in the top bar.

### The site's address

WordPress keeps its own address in its database and sends every request there. Served on a new port, it would redirect to a site that isn't running.

The file loaded first fixes that for this one process. It's a few lines of PHP in midcode's data folder that define `WP_HOME` and `WP_SITEURL` as the address the request came to, which WordPress takes over what the database says:

```php title="wordpress-prepend.php (in midcode's data folder)"
if (PHP_SAPI === 'cli-server' && !empty($_SERVER['HTTP_HOST'])) {
    if (!defined('WP_HOME')) {
        define('WP_HOME', 'http://' . $_SERVER['HTTP_HOST']);
    }
    if (!defined('WP_SITEURL')) {
        define('WP_SITEURL', 'http://' . $_SERVER['HTTP_HOST']);
    }
}
```

Nothing in your `wp-config.php`, your theme or your database changes, and the site answers as before everywhere else.

### A site that already runs

If `wp-config.php` sets `WP_HOME` to an address, as some local setups do, midcode asks that address first. When it answers, the log says "Already running at …: midcode shows it." and nothing is started.

### What you need

- PHP on your Mac, on your shell's PATH.
- A working install: `wp-config.php` in place and its database running. midcode starts PHP, not MySQL.

## What you can edit

In a classic theme, what's written as HTML in the theme's files can be edited where it's written:

```php title="template-parts/content.php"
<article id="post-<?php the_ID(); ?>" <?php post_class( 'entry' ); ?>>
	<h2 class="entry-title"><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>
	<div class="entry-content"><?php the_content(); ?></div>
	<p class="entry-more">Keep reading</p>
</article>
```

- The `<article>`, the `<h2>`, the link, the `<div>` and the `<p>` are written here, so midcode can find them and change their classes, attributes and tag. The file is one post of the loop: a change shows on every post.
- "Keep reading" is written in the file, so a double-click edits it.
- The title is `the_title()`: it isn't in the file. Neither is the HTML that `the_content()` prints inside the `<div>`.

A text and a style change in the footer:

```diff title="footer.php"
-	<p class="site-info">Made with care in Rosario</p>
+	<p class="site-info mid:text-[14px]">Made with care in Buenos Aires</p>
```

On the classic theme that was tried (a header, a footer, an index, template parts and the loop), 21 of the 23 elements of the page were found. The two that weren't are the posts' content.

When you open the whole install, only the themes the page is drawn with count: midcode reads their names from the `wp-theme-…` and `wp-child-theme-…` classes of `<body>` and from where the page's assets come from. Other installed themes are ignored, and `wp-admin` and `wp-includes` are never read.

### Block themes

A block theme's templates are block markup, and most of what you see is drawn by dynamic blocks that have no HTML in the theme. What the Site Editor changes is saved in the database. With Twenty Twenty-Five, 6 of the page's 94 elements were found. For a block theme, midcode is a way to see every breakpoint and leave comments, not to edit.

## Pages

midcode doesn't read WordPress's pages: **Pages** in the top bar shows the home page. To open another one, type its path there (for example `/sample-page`) and press `Enter`.

## Styles

Unless the theme has Tailwind 4, midcode writes its own `mid:` utilities and keeps their CSS in `midcode.css` ([Without Tailwind](https://midcode.app/docs/styling/without-tailwind.md)).

Opened from the theme's folder, `midcode.css` goes in that folder and the theme's `header.php` gets one line, on your first style edit:

```diff title="header.php"
 	<?php wp_head(); ?>
+	<link rel="stylesheet" href="<?php echo esc_url( get_theme_file_uri( 'midcode.css' ) ); ?>">
 </head>
```

The file ships with the theme, like any of its assets.

Opened from the whole install, or with a block theme (which has no `header.php`), midcode can't tell where the link goes. It writes `midcode.css` at the top of the folder, says it couldn't tell where to import it, and leaves the link to you. To style a classic theme, open the theme's folder.

## Limits

- Text printed by PHP isn't editable on the canvas. That includes strings passed through translation functions, like `<?php esc_html_e( 'Read more', 'mytheme' ); ?>`: edit those in the file.
- Menus, widgets, the post content, anything set in the Customizer or the Site Editor: they come from the database.
- What a plugin draws is the plugin's. Opened from the whole install, a plugin's files are read like any other file of the folder, so an element may point into `wp-content/plugins`. An edit there is lost when the plugin updates.
- A theme opened on its own, outside an install, isn't recognised as WordPress.
- The install that was tried keeps its database in SQLite. One on MySQL wasn't tried, and neither were child themes or multisite.
- [The free canvas](https://midcode.app/docs/editor/free-canvas.md) is for Next.js projects.
- midcode doesn't add pages to a WordPress site, and [Site settings](https://midcode.app/docs/editor/site-settings.md) isn't offered: WordPress keeps its title, description and icon in its database and prints them with `wp_head()`.

## Troubleshooting

**The canvas jumps to another address, or stays blank.** `wp-config.php` fixes `WP_HOME` and nothing answers there, so WordPress redirects to a site that's down. Start it (Local, MAMP, Herd) and press **Restart** in the dev server log, or remove the constant.

**"Error establishing a database connection".** WordPress is answering, its database isn't. Start it.

**"php" isn't installed on this Mac.** midcode runs the `php` your shell finds. Install it, or point midcode at a site that already runs with **Change how it runs** on the error card ([Any other stack](https://midcode.app/docs/frameworks/custom-server.md)).

**A theme you opened by itself doesn't run.** Open it from inside the install, at `wp-content/themes/<theme>`. A theme folder that isn't inside a WordPress isn't recognised as one.
