Create Block Theme and Version Control
|
This content was generated with the assistance of AI and should be verified against the official documentation before being relied on in production. This sub-section’s WordPress bibliography lists the reference material consulted while preparing these pages. |
The Site Editor never writes to a block theme’s files; it stores every save in the database. A theme developer wants
the result in the theme, under version control, reviewed and deployed like any other code. This page makes that round
trip for the Lumen Press theme lumen with the Create Block Theme plugin, with the core export where the plugin is
not an option, and as a repeatable team workflow.
This page was written against WordPress 7.1.3 (released 2026-10-06; 7.1.4, a security release of 2026-10-28, is the version to run in production), PHP 7.4 minimum and 8.3+ recommended, theme.json version 3, WP-CLI 2.12.0 and Create Block Theme 2.10.2 (released 2026-10-01; it requires WordPress 6.8 and PHP 7.4 and declares "Tested up to: 6.9", but every call below was run against 7.1.3), and checked on 2026-10-28. The Gutenberg plugin (24.2.0) is not needed. WordPress 7.2 is in beta and due in December 2026; nothing announced for it changes the storage model described here.
The site owner’s side (Styles, templates, fonts, revisions, storage and the Tools > Export zip) is covered in Site Editor and Global Styles.
Why Site Editor changes have to be moved
Each Site Editor save creates or updates a post: a wp_global_styles post holds the user style layer, wp_template
and wp_template_part posts hold customized templates and parts, wp_navigation holds menus and wp_block holds
synced patterns. At render time the database copy wins over the theme file of the same slug. So nothing designed
in the Site Editor is in Git (it cannot be reviewed, rolled back or deployed except by copying the database), a later
edit to templates/home.html seems to do nothing on a site where home was customized, and theme updates do not reach
customized templates.
The fix is always the same: write the database state into the theme files, commit them, then delete the database copies so the files are served again.
The Create Block Theme plugin
Create Block Theme is maintained by WordPress.org contributors in the WordPress/create-block-theme repository and
distributed in the Plugin Directory. Its own description calls it a development mode: it rewrites theme files on the
server, so it belongs on a local or staging site with the theme checked out from Git, never on production.
After activation it adds a wrench icon next to the Save button of the Site Editor, which opens the plugin sidebar, and
an Appearance > Create Block Theme landing page (visible to users with edit_themes). Tutorials written for the
1.x releases show form-based admin screens, including a separate font manager; in 2.x the actions live in the Site
Editor sidebar and the plugin’s readme calls the old admin page deprecated.
What it can do
| Sidebar action | Effect |
|---|---|
Save Changes to Theme |
Writes the user style layer into |
Edit Theme Metadata |
Rewrites the |
Edit Theme Settings |
Since 2.10.0: edits |
Create Theme > Clone Theme |
Copies the active theme, with the current customizations applied, to a new theme folder with a new name and slug. |
Create Theme > Create Child Theme |
Creates a child of the active theme containing the current user styles, and activates it. |
Create Blank Theme |
Creates a new minimal block theme (header and footer parts, an index template, system fonts). |
Create Theme Variation |
Writes the current user style layer as |
Export Zip |
Downloads the active theme as a zip with the customizations, images and activated fonts included. |
Inspect Theme JSON |
Shows the theme’s |
Reset Theme |
Deletes user styles, customized templates and customized template parts, each selectable. |
Editor preference (2.10.0) |
Opt-in expanded typography controls in the block inspector while authoring a theme. |
The Theme Handbook’s Quick-Start Guide uses this plugin to create and export a first theme; the Developer Blog’s 2023 walkthrough shows the same actions in an older release (1.13).
Save Changes to Theme options
The save dialog lists checkboxes; each maps to one request parameter of the save endpoint. The defaults are the sidebar’s defaults in 2.10.2.
| Option (parameter) | Default | What it does |
|---|---|---|
Save Fonts ( |
on |
Copies fonts activated in the Font Library into the theme and declares them in |
Save Style Changes ( |
on |
Merges the user layer into |
Save Template Changes ( |
on |
Writes templates and parts, then deletes every customized |
Process Only Modified Templates ( |
on |
Rewrites only templates that have a database copy. Off, every template of the theme is reprocessed (a large diff the first time). |
Save Patterns ( |
on |
Writes every synced pattern ( |
Localize Text ( |
off |
Wraps visible text in templates and patterns in translation calls, so it can be translated with the theme’s text domain. |
Localize Images ( |
off |
Copies media used in templates and patterns into |
Remove Navigation Refs ( |
off |
Drops the |
Remove Taxonomy Query ( |
off |
Drops |
In every mode the plugin also removes image and cover block IDs (wp-image-123 classes) and strips PHP tags from
template and pattern content before writing it.
For a theme that ships to several sites, turn Remove Navigation Refs on (a header with "ref":42 points at a menu
that exists nowhere else) and Save Patterns off unless every synced pattern on the site belongs in the theme: editors'
synced patterns are content, and saving them moves them out of the Patterns screen.
REST endpoints and permissions
The sidebar calls REST routes in the create-block-theme/v1 namespace. The plugin has no WP-CLI commands, but the
routes can be called from wp eval-file with rest_do_request(), as the examples below do.
| Route | Method | Purpose |
|---|---|---|
|
POST |
Save Changes to Theme (parameters in the previous table) |
|
PUT, PATCH, POST |
|
|
POST |
|
|
POST |
|
|
POST |
Edit Theme Metadata |
|
POST |
Edit Theme Settings (JSON body) |
|
POST |
Streams the zip |
|
GET |
Fonts used by the theme and its variations (needs only |
Every route except /font-families requires current_user_can( 'edit_themes' ) and
wp_is_file_mod_allowed( 'create_block_theme_modify_theme' ). In practice:
-
DISALLOW_FILE_EDITset totrueremovesedit_themesfrom everybody, so the plugin returns 403 (verified on 7.1.3) while the Site Editor keeps working withedit_theme_options.DISALLOW_FILE_MODSand thefile_mod_allowedfilter also block it. -
On Multisite only Super Admins have
edit_themes, so site administrators cannot rewrite a network theme (enforced since 2.10.0). -
The web server user must be able to write the theme folder. On a hardened server it cannot, and the save fails; that is the intended state for production (see File Permissions and Filesystem).
A working copy to try it on
The examples use the Compose stack (MariaDB and a WP-CLI container; the scripts call the REST routes in process) of
Site Editor and Global Styles, with
one more volume: the lumen theme of Themes Overview (plus a
parts/header.html) bind-mounted from a Git checkout, so every file the plugin writes shows up in git diff.
# compose.yaml, service cli: the volumes list
volumes:
- wp:/var/www/html
- ./lumen:/var/www/html/wp-content/themes/lumen
- ./scripts:/scripts:ro
The bind mount makes Docker create wp-content as root, so it is handed to the web server user (33) before anything
is installed:
export WP_DB_PASSWORD='<a-local-db-password>' WP_ADMIN_PASSWORD='<a-local-admin-password>'
docker compose up -d
docker compose exec -u 0 cli chown 33:33 /var/www/html/wp-content /var/www/html/wp-content/themes
docker compose exec cli sh -c 'php -d memory_limit=512M /usr/local/bin/wp core download --version=7.1.3 --skip-content'
docker compose exec cli sh -c 'wp config create --dbname=wordpress --dbuser=wordpress --dbpass="$WP_DB_PASSWORD" --dbhost=db &&
wp core install --url=https://lumenpress.test --title="Lumen Press" --admin_user=admin \
--admin_email=admin@lumenpress.test --admin_password="$WP_ADMIN_PASSWORD" --skip-email &&
wp theme activate lumen &&
wp plugin install create-block-theme --version=2.10.2 --activate'
Source: WP-CLI: wp plugin install
Every script below runs with --user=admin: the routes check capabilities, and global styles saved without a user
lose their wp_theme term.
From the Site Editor to a Git commit
Making the change
This script makes the two saves a designer would make in the Site Editor of lumen: in Styles, links become ink
coloured with a red hover state and headings bold; in Templates, a new "Blog Home" template (home) with a heading
above the post list.
<?php
/**
* Makes the two saves a designer would make in the Site Editor:
* a Styles change and a new "Blog home" template.
* Run with: wp eval-file /scripts/edit-like-site-editor.php --user=admin
*/
$id = WP_Theme_JSON_Resolver::get_user_global_styles_post_id();
$request = new WP_REST_Request( 'POST', "/wp/v2/global-styles/$id" );
$request->set_body_params(
array(
'styles' => array(
'elements' => array(
'link' => array(
'color' => array( 'text' => 'var(--wp--preset--color--ink)' ),
':hover' => array( 'color' => array( 'text' => 'var(--wp--preset--color--lumen-red)' ) ),
),
'heading' => array(
'typography' => array( 'fontWeight' => '700' ),
),
),
),
)
);
WP_CLI::log( 'styles HTTP ' . rest_do_request( $request )->get_status() );
$markup = '<!-- wp:template-part {"slug":"header","tagName":"header"} /-->' . "\n\n";
$markup .= '<!-- wp:group {"tagName":"main","layout":{"type":"constrained"}} -->' . "\n";
$markup .= '<main class="wp-block-group"><!-- wp:heading {"level":1} -->' . "\n";
$markup .= '<h1 class="wp-block-heading">New from Lumen Press</h1>' . "\n";
$markup .= '<!-- /wp:heading -->' . "\n\n";
$markup .= '<!-- wp:query {"queryId":2,"query":{"inherit":true}} -->' . "\n";
$markup .= '<div class="wp-block-query"><!-- wp:post-template -->' . "\n";
$markup .= '<!-- wp:post-title {"isLink":true} /-->' . "\n";
$markup .= '<!-- /wp:post-template --></div>' . "\n";
$markup .= '<!-- /wp:query --></main>' . "\n";
$markup .= '<!-- /wp:group -->';
$request = new WP_REST_Request( 'POST', '/wp/v2/templates' );
$request->set_body_params(
array(
'slug' => 'home',
'title' => 'Blog Home',
'content' => $markup,
)
);
WP_CLI::log( 'template HTTP ' . rest_do_request( $request )->get_status() );
Source: REST API Handbook: Templates
$ wp eval-file /scripts/edit-like-site-editor.php --user=admin
styles HTTP 200
template HTTP 201
$ wp post list --post_type=wp_template,wp_template_part,wp_global_styles --post_status=any --fields=ID,post_type,post_name
ID post_type post_name
4 wp_global_styles wp-global-styles-lumen
6 wp_template home
Source: WP-CLI: wp post list
At this point git status in the lumen checkout is clean: the work exists only in the database.
Saving it to the theme
The next script sends the request that the sidebar’s Save Changes button sends, with Save Patterns and Save Fonts off and Remove Navigation Refs on, the settings recommended above for a shared theme:
<?php
/**
* Calls the endpoint behind Create Block Theme's "Save Changes to Theme".
* Run with: wp eval-file /scripts/save-to-theme.php --user=admin
*/
$request = new WP_REST_Request( 'POST', '/create-block-theme/v1/save' );
$request->set_body_params(
array(
'saveStyle' => true,
'saveTemplates' => true,
'processOnlySavedTemplates' => true,
'savePatterns' => false,
'saveFonts' => false,
'removeNavRefs' => true,
'localizeText' => false,
'localizeImages' => false,
'removeTaxQuery' => false,
)
);
$response = rest_do_request( $request );
WP_CLI::log( 'HTTP ' . $response->get_status() . ' ' . wp_json_encode( $response->get_data() ) );
$ wp eval-file /scripts/save-to-theme.php --user=admin
HTTP 200 {"status":"SUCCESS","message":"Theme Saved."}
$ wp post list --post_type=wp_template,wp_template_part,wp_global_styles --post_status=any --fields=ID,post_type,post_name
ID post_type post_name
4 wp_global_styles wp-global-styles-lumen
$ wp post get 4 --field=post_content
{"styles":[],"settings":[],"isGlobalStylesUserThemeJSON":true,"version":3}
$ git -C lumen status --short && git -C lumen diff
M theme.json
?? templates/home.html
diff --git a/theme.json b/theme.json
@@ -5,9 +5,21 @@
"appearanceTools": true,
"color": {
"palette": [
- { "slug": "paper", "name": "Paper", "color": "#fbf8f1" },
- { "slug": "ink", "name": "Ink", "color": "#1f1d1a" },
- { "slug": "lumen-red", "name": "Lumen red", "color": "#a3271f" }
(15 added lines: the same three entries, one key per line, keys sorted)
@@ -21,9 +33,21 @@
"elements": {
+ "heading": {
+ "typography": {
+ "fontWeight": "700"
+ }
+ },
"link": {
- "color": { "text": "var(--wp--preset--color--lumen-red)" }
+ ":hover": {
+ "color": {
+ "text": "var(--wp--preset--color--lumen-red)"
+ }
+ },
+ "color": {
+ "text": "var(--wp--preset--color--ink)"
+ }
}
}
}
-}
+}
\ No newline at end of file
What the run shows:
-
templates/home.htmlholds the saved markup, thewp_templatepost is gone and the user style layer is empty: the site renders as before, now from the files. -
theme.jsonis rewritten, not patched: keys are sorted, compact one-line objects are expanded,$schemaandversionare kept at the top (since 2.8.0) and the final newline is dropped. The first save of a hand-written theme therefore produces a noisy diff. Committing that reformatting on its own ("normalize theme.json") keeps later diffs down to the real changes, because the plugin always writes the same layout. -
The style revisions of the
wp_global_stylespost are kept, but no longer describe what the files contain.
The two files are then committed like any other change.
Without the plugin: the core export
Where installing a plugin is not allowed, the Site Editor’s Tools > Export (core since 5.9; the zip holds the
whole theme since 6.0) produces a zip of the theme with the customizations written in.
wp_generate_block_templates_export_file() builds the same zip, so it can be unpacked straight into the checkout. Here a tagline is added to the header part, then only templates/ and
parts/ are taken from the export:
<?php
/**
* Adds a tagline to the header part, as an edit in the Site Editor would.
* Run with: wp eval-file /scripts/edit-header.php --user=admin
*/
$markup = '<!-- wp:group {"tagName":"header","layout":{"type":"constrained"}} -->' . "\n";
$markup .= '<header class="wp-block-group"><!-- wp:site-title {"level":0} /-->' . "\n\n";
$markup .= '<!-- wp:site-tagline /--></header>' . "\n";
$markup .= '<!-- /wp:group -->';
$request = new WP_REST_Request( 'POST', '/wp/v2/template-parts/lumen//header' );
$request->set_body_params( array( 'content' => $markup ) );
WP_CLI::log( 'header HTTP ' . rest_do_request( $request )->get_status() );
docker compose exec cli wp eval-file /scripts/edit-header.php --user=admin
docker compose exec cli sh -c 'zip=$(wp eval "echo wp_generate_block_templates_export_file();" --user=admin)
unzip -o -q "$zip" "parts/*" "templates/*" -d wp-content/themes/lumen && rm -f "$zip"'
git -C lumen diff
diff --git a/parts/header.html b/parts/header.html
@@ -1,5 +1,5 @@
<!-- wp:group {"tagName":"header","layout":{"type":"constrained"}} -->
-<header class="wp-block-group">
- <!-- wp:site-title {"level":0} /-->
-</header>
-<!-- /wp:group -->
+<header class="wp-block-group"><!-- wp:site-title {"level":0} /-->
+
+<!-- wp:site-tagline /--></header>
+<!-- /wp:group -->
\ No newline at end of file
Templates that were never customized come out of the export byte for byte as they are in the theme, so they produce no diff. Compared with the plugin, the core export:
-
does not delete the database copies; that is a separate step (next section), and forgetting it is the most common source of "my file change does nothing";
-
writes a
theme.jsonthat is the theme file merged with the user layer, but with keys sorted alphabetically (versionends up last) instead of the plugin’s layout; mixing both tools on one theme produces churn in every diff; -
keeps Navigation
"ref"IDs, image IDs and query term IDs, which then have to be removed by hand; -
knows nothing about fonts, patterns, variations or child themes.
Style variations and child themes
The same mechanism saves a look as a style variation or starts a child theme. The script sets a dark background in Styles, saves it as the variation "Reading Room" and then creates a child theme from it:
<?php
/**
* Calls "Create Theme Variation" and "Create Child Theme" of Create Block Theme.
* Run with: wp eval-file /scripts/variation-and-child.php --user=admin
*/
$id = WP_Theme_JSON_Resolver::get_user_global_styles_post_id();
$colors = array(
'background' => 'var(--wp--preset--color--ink)',
'text' => 'var(--wp--preset--color--paper)',
);
$request = new WP_REST_Request( 'POST', "/wp/v2/global-styles/$id" );
$request->set_body_params( array( 'styles' => array( 'color' => $colors ) ) );
WP_CLI::log( 'styles HTTP ' . rest_do_request( $request )->get_status() );
$request = new WP_REST_Request( 'POST', '/create-block-theme/v1/create-variation' );
$request->set_body_params( array( 'name' => 'Reading Room', 'saveFonts' => false ) );
WP_CLI::log( 'variation HTTP ' . rest_do_request( $request )->get_status() );
$request = new WP_REST_Request( 'POST', '/create-block-theme/v1/create-child' );
$request->set_body_params(
array(
'name' => 'Lumen Child',
'description' => 'Site-specific adjustments to Lumen.',
'author' => 'Lumen Press',
'version' => '0.1.0',
)
);
WP_CLI::log( 'child HTTP ' . rest_do_request( $request )->get_status() );
$ wp eval-file /scripts/variation-and-child.php --user=admin
styles HTTP 200
variation HTTP 200
child HTTP 200
$ wp theme list --fields=name,status,version
name status version
lumen-child active 0.1.0
lumen parent 0.1.0
$ cd wp-content/themes && ls lumen-child lumen/styles && grep -E "Requires|Template:" lumen-child/style.css
lumen-child:
readme.txt screenshot.png style.css theme.json
lumen/styles:
reading-room.json
Requires at least: 7.1
Requires PHP: 5.7
Template: lumen
Source: WP-CLI: wp theme list
styles/reading-room.json holds the styles.color object above, "version": 3 and "title": "Reading Room".
Points to check after these two actions:
-
The variation is written into the active theme’s
styles/folder, but the user layer is not cleared: the site still shows the dark look as a customization. Reset the styles (next section) and pick the variation in Styles > Browse styles instead. -
The child theme receives the current user styles in its
theme.json, areadme.txtand a generatedscreenshot.png, and is activated immediately. Itsstyle.csssaysRequires at least= the running version unlessrequires_wpis sent, andRequires PHP: 5.7, a value hard-coded by the plugin that corresponds to no PHP release. Edit the header to the real requirements (Requires at least: 6.9,Requires PHP: 7.4for Lumen) before the first commit. The finishedlumen-childis described in Child Themes. -
Clone Theme and Create Blank Theme write a new folder next to
lumen, outside the Git checkout, so the new theme needs its own repository. Variation rules are on Style Variations and Section Styles.
Resetting templates and styles
Once the files hold the change, the database copies must go, on every environment that has them. The ways to do it:
| Method | Removes |
|---|---|
Site Editor > Templates or Patterns > a customized item > Reset (or "Clear customizations") |
That template or part’s database copy |
Site Editor > Styles > Revisions > Reset to defaults |
The user style layer (the post stays, emptied; revisions stay) |
Create Block Theme > Reset Theme |
Any of user styles, all customized templates, all customized parts |
|
Exactly the copies listed; final, with no trash |
|
One template copy, through REST (without |
Run any of them only after the files are committed, because a copy that was not exported is lost. The scriptable form lists the active theme’s customized templates and parts through the template API and deletes exactly those posts:
<?php
/**
* Lists the active theme's templates and parts that have a database copy.
* Run with: wp eval-file /scripts/list-customized.php
*/
foreach ( array( 'wp_template', 'wp_template_part' ) as $type ) {
foreach ( get_block_templates( array(), $type ) as $template ) {
if ( 'custom' === $template->source ) {
WP_CLI::log( sprintf( '%d %s %s', $template->wp_id, $type, $template->id ) );
}
}
}
$ wp eval-file /scripts/list-customized.php
8 wp_template_part lumen//header
$ wp post delete 8 --force
Success: Deleted post 8.
$ wp eval 'echo get_block_template( "lumen//header", "wp_template_part" )->source, PHP_EOL;'
theme
Source: WP-CLI: wp post delete
theme as the source means the header is served from parts/header.html again. A shortcut such as
wp post delete $(wp post list --post_type=wp_template,wp_template_part --format=ids) --force removes the copies of
every theme, and wp post list cannot narrow it: a --wp_theme=lumen argument is silently ignored.
A REST DELETE on a template without force=true does not delete it: it moves the copy to the trash, renamed
home__trashed, and --post_status=any no longer lists it. Pass force=true, or include trash in the status
list when cleaning up.
The plugin’s reset route does the same for the active theme only:
<?php
/**
* Calls Create Block Theme's "Reset Theme" for styles, templates and parts.
* Run with: wp eval-file /scripts/reset-theme.php --user=admin
*/
$request = new WP_REST_Request( 'PATCH', '/create-block-theme/v1/reset-theme' );
$request->set_body_params(
array(
'resetStyles' => true,
'resetTemplates' => true,
'resetTemplateParts' => true,
)
);
$response = rest_do_request( $request );
WP_CLI::log( 'HTTP ' . $response->get_status() . ' ' . wp_json_encode( $response->get_data() ) );
Run as wp eval-file /scripts/reset-theme.php --user=admin, it answers
HTTP 200 {"status":"SUCCESS","message":"Theme Reset."} and leaves the wp_global_styles post as
{"styles":[],"settings":[],"isGlobalStylesUserThemeJSON":true,"version":3}.
Menus (wp_navigation) and synced patterns (wp_block) are content, not theme state; they move with the content
export (Importing, Exporting and Migrating).
A team workflow for block themes
Lumen Press keeps lumen in Git while designers keep using the Site Editor; production only receives theme files.
-
One source of truth. The theme repository is the design. A site’s database may hold customizations only temporarily, on the environment where someone is designing.
-
Design on a disposable site. wp-env, the Compose stack above, or WordPress Playground with the theme imported from GitHub (the Developer Blog describes a Playground flow that ends with "Export to GitHub" opening a pull request). Set
define( 'WP_DEVELOPMENT_MODE', 'theme' );in that site’swp-config.phpsotheme.jsonand pattern caches are skipped and edits to files show at once. -
Save to the theme, never edit the same template in both places at once. If a developer changes
templates/home.htmlin Git while a designer has a database copy ofhome, the designer’s save overwrites the developer’s change. Pull before designing, and save to the theme before pulling again. -
Review the diff like code. Look for
"ref"on Navigation blocks,wp-image-<id>classes, absolute URLs tohttps://lumenpress.test/wp-content/uploads/..., term IDs intaxQuery, and unexpectedpatterns/*.phpfiles. Validatetheme.jsonagainst its$schemain CI and keep the JSON layout produced by the tool the team chose. -
Deploy files, then reset. After a deploy, any environment that still has customizations of the changed templates keeps serving the old copies. List them with the
list-customized.phpscript above and reset what is listed, after confirming it is not unsaved work. -
Lock production. Do not install Create Block Theme there; set
DISALLOW_FILE_EDIT(which also disables the plugin if present) and keep the theme folder unwritable by the web server. Administrators can still customize in the Site Editor; if that is not wanted, restrict who holdsedit_theme_options(see Users, Roles and Profiles).
For a theme that a third party maintains, the same workflow applies to a child theme, so that the parent can still be updated (Child Themes).
What older books get wrong or leave out
| Older advice | Current state (7.1) |
|---|---|
Full site editing appeared in 5.4 to 5.6 (PRO) or is "still maturing" (UWH) |
Block themes and the Site Editor arrived in 5.9 (2022), with the Site Editor export; Create Block Theme is the WordPress.org-maintained tool for turning Site Editor work into theme files. |
Customizing a theme means editing its files in Appearance > Theme File Editor, or keeping Customizer settings (PRO, UWH) |
For block themes, design changes are made in the Site Editor and saved to the database; they reach the theme files only through an export or Create Block Theme. Editing files on a live server is disabled on a hardened site ( |
A theme update keeps or overwrites your changes as a whole (AIO) |
Customized templates and styles survive updates in the database and hide the updated files until they are reset. |
Version control is not discussed for site design |
Site Editor work can be committed: save to the theme, review the diff, deploy files, reset database copies. |
A child theme is created by hand-writing |
A block child theme needs only |
Common errors and pitfalls
| Symptom | Cause and fix |
|---|---|
The plugin sidebar’s actions fail with "Sorry, you are not allowed to do that." (403) |
The user lacks |
Save reports success but the files did not change in the repository |
The theme was saved on another copy (the container’s own |
Edits to a template file have no effect |
A customized database copy of that template exists. Reset it after saving its content. |
Synced patterns disappeared from the Patterns screen |
Save Patterns was on: they were moved to |
"A pattern with this name already exists" |
Save Patterns found a file with the same name in |
The header’s menu is empty on another site |
A Navigation |
Images in templates are broken after deploy |
The markup points at the design site’s uploads. Save with Localize Images, which copies them into |
A new child theme is active unexpectedly, or lists |
Create Child Theme activates the child and writes a placeholder PHP requirement. Switch back if needed and fix the header. |
The site still looks customized after creating a variation |
Create Theme Variation does not clear the user layer. Reset styles, then choose the variation. |
Security notes: the plugin can write any file content an administrator puts into templates and patterns into a PHP
folder of the theme (patterns are .php files). Since 2.10.0 it strips PHP tags from pattern bodies and validates
downloaded media against an extension and MIME allowlist, but it remains a tool for trusted developers on non-public
sites. Review every generated patterns/*.php file before committing it.