Skip to content

WordPress

Next release

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.

View as Markdown

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 explains how, and what that means for editing.

At a glance

WordPress
Detected bywp-load.php at the top of the folder, or a theme’s style.css inside wp-content/themes/<theme>
Runs withphp -S 127.0.0.1:$PORT, with one file of midcode’s loaded first
Elements are marked bymidcode, after each page loads, by matching it against the theme’s .php files
EditingText, classes, attributes and tag; insert, move, duplicate and remove. Only what the theme writes as HTML
PagesNot listed. Type the path
StylesTailwind 4 classes, or mid: utilities with midcode.css in the theme’s folder, linked from header.php
Tried withWordPress 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:

Terminal
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:

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:

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:

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).

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:

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 is for Next.js projects.

  • midcode doesn’t add pages to a WordPress site, and Site settings 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).

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.