Providing content for your demo with Playground
One of the things you may want to do to provide a good demo with WordPress Playground is to load default content to better highlight the features of your plugin or theme. This default content may include images or other assets.
There are several Blueprint steps and strategies you can use to import content (or generate it) in the Playground instance. This guide walks through the available sources. For a focused comparison of XML, PHP, and ZIP imports—including pros, cons, and measured performance—see Importing content into WordPress with Blueprints.
importWxr
With the importWxr step, you can import content from a
WordPress eXtended RSS (WXR) .xml file previously
exported from an existing WordPress installation.
The step can fetch attachments, rewrite URLs, include or exclude comments, and
control how imported authors map to local users. This example assigns imported
content to the existing admin user and leaves attachment downloads disabled:
{
"$schema": "https://playground.wordpress.net/blueprint-schema.json",
"landingPage": "/wp-admin/edit.php",
"login": true,
"steps": [
{
"step": "importWxr",
"file": {
"resource": "url",
"url": "https://raw.githubusercontent.com/WordPress/blueprints/trunk/blueprints/install-activate-setup-theme-from-gh-repo/blueprint-content.xml"
},
"fetchAttachments": false,
"rewriteUrls": true,
"importComments": true,
"authorsMode": "default-author",
"defaultAuthorUsername": "admin"
}
]
}
Run Blueprint See blueprint.json
Set authorsMode to create to create local users for imported authors, or to
map and provide authorsMap when the corresponding users already exist. You
can also provide urlMapping for explicit old-to-new URL replacements.
To download the media referenced by the export, set fetchAttachments to
true and enable Blueprint networking. The original media URLs must still be
available:
{
"$schema": "https://playground.wordpress.net/blueprint-schema.json",
"features": {
"networking": true
},
"steps": [
{
"step": "importWxr",
"file": {
"resource": "url",
"url": "https://example.com/wordpress-export.xml"
},
"fetchAttachments": true
}
]
}
When the original attachment URLs are unavailable, one approach is to upload
the images to the repository that hosts the Blueprint and replace their paths
in the exported .xml file. For a public GitHub repository, use a raw URL such
as https://raw.githubusercontent.com/{repo}/{branch}/{image_path}.
<!-- wp:image {"lightbox":{"enabled":false},"id":4751,"width":"78px","sizeSlug":"full","linkDestination":"none","align":"center","className":"no-border"} -->
<figure class="wp-block-image aligncenter size-full is-resized no-border">
<img src="https://raw.githubusercontent.com/WordPress/blueprints/trunk/blueprints/install-activate-setup-theme-from-gh-repo/images/avatars.png" alt="" class="wp-image-4751" style="width:78px" />
</figure>
<!-- /wp:image -->
For a self-contained demo, place the exported .xml file and its assets next
to blueprint.json in a Blueprint bundle, and use a
bundled resource instead of a remote URL.
importWordPressFiles
With the importWordPressFiles step, you can restore the
top-level WordPress files from a .zip file into the instance's root folder.
For example, if an archive contains wp-content and wp-includes, those
directories replace the corresponding directories in Playground.
The ZIP can be created from a Playground instance with the Download as zip option in the Playground Options Menu. Current Playground exports include a manifest that lets the import step update Playground scope URLs after restoration.
You can prepare a demo for your WordPress theme or plugin—including the
database, images, plugins, themes, and settings—in a Playground instance and
then export a snapshot of that demo. The snapshot can be restored later using
importWordPressFiles. This example expects site.zip next to blueprint.json
in a Blueprint bundle:
{
"$schema": "https://playground.wordpress.net/blueprint-schema.json",
"landingPage": "/",
"login": true,
"steps": [
{
"step": "importWordPressFiles",
"wordPressFilesZip": {
"resource": "bundled",
"path": "/site.zip"
}
}
]
}
The step can detect a complete WordPress directory inside a wrapper folder. If
an archive contains more than one site or needs an explicit starting directory,
set pathInZip to the directory that contains the WordPress files. Keep the
source and destination WordPress, PHP, theme, and plugin versions compatible,
and only restore ZIP files from sources you trust because they can contain an
entire database and executable PHP.
importThemeStarterContent
Some themes have starter content that can be published to highlight the features of a theme.
With the importThemeStarterContent step, you can publish
the starter content of any installed theme, even if that theme is not activated
in the Playground instance:
{
"$schema": "https://playground.wordpress.net/blueprint-schema.json",
"steps": [
{
"step": "installTheme",
"themeData": {
"resource": "wordpress.org/themes",
"slug": "twentytwenty"
}
},
{
"step": "installTheme",
"themeData": {
"resource": "wordpress.org/themes",
"slug": "twentytwentyone"
},
"options": {
"activate": true
}
},
{
"step": "importThemeStarterContent",
"themeSlug": "twentytwenty"
}
]
}
You can also publish the starter content of a theme while installing it with the
installTheme step by setting its importStarterContent
option to true:
{
"$schema": "https://playground.wordpress.net/blueprint-schema.json",
"steps": [
{
"step": "installTheme",
"themeData": {
"resource": "wordpress.org/themes",
"slug": "twentytwenty"
},
"options": {
"activate": true,
"importStarterContent": true
}
}
]
}
wp-cli
Another way of generating content for your theme or plugin is the
wp-cli step. It runs
WP-CLI commands such as
wp post generate:
{
"$schema": "https://playground.wordpress.net/blueprint-schema.json",
"landingPage": "/wp-admin/edit.php",
"login": true,
"steps": [
{
"step": "wp-cli",
"command": "wp post generate --count=20 --post_type=post --post_date=1999-01-04"
}
]
}
You can also combine the wp-cli step with the
writeFile step to create posts from existing content and
import images into the Playground instance:
{
"$schema": "https://playground.wordpress.net/blueprint-schema.json",
"landingPage": "/?p=4",
"login": true,
"steps": [
{
"step": "writeFile",
"path": "/wordpress/wp-content/postcontent.md",
"data": {
"resource": "url",
"url": "https://raw.githubusercontent.com/wordpress/blueprints/trunk/blueprints/wpcli-post-with-image/postcontent.md"
}
},
{
"step": "wp-cli",
"command": "wp post create --post_title='Welcome to Playground' --post_status='published' /wordpress/wp-content/postcontent.md"
},
{
"step": "writeFile",
"path": "/wordpress/wp-content/Select-storage-method.png",
"data": {
"resource": "url",
"url": "https://raw.githubusercontent.com/wordpress/blueprints/trunk/blueprints/wpcli-post-with-image/Select-storage-method.png"
}
},
{
"step": "wp-cli",
"command": "wp media import wordpress/wp-content/Select-storage-method.png --post_id=4 --title='Select your storage method' --featured_image"
}
]
}
Check the “Use wp-cli to add a post with image” example from the Blueprints Gallery to see the full example showing the connection between the content and the featured image.
runPHP
With the runPHP step, you can run PHP code to insert or
configure data in your WordPress installation, for example with the
wp_insert_post function.
Load /wordpress/wp-load.php before calling WordPress APIs, and handle errors
so a failed setup does not silently produce an incomplete demo:
{
"$schema": "https://playground.wordpress.net/blueprint-schema.json",
"landingPage": "/wp-admin/edit.php",
"login": true,
"steps": [
{
"step": "runPHP",
"code": "<?php\nrequire_once '/wordpress/wp-load.php';\n\n$post_id = wp_insert_post(\n\tarray(\n\t\t'post_title' => 'Simple post from PHP',\n\t\t'post_content' => '<!-- wp:paragraph --><p>This is a simple post inserted with wp_insert_post.</p><!-- /wp:paragraph -->',\n\t\t'post_author' => 1,\n\t\t'post_status' => 'publish',\n\t),\n\ttrue\n);\n\nif ( is_wp_error( $post_id ) ) {\n\tthrow new RuntimeException( $post_id->get_error_message() );\n}"
}
]
}
For small, deterministic fixtures, runPHP keeps setup logic close to the
Blueprint. For large editorial datasets or a complete prepared site, WXR or a
ZIP snapshot is usually easier to maintain. The
import comparison guide explains the
trade-offs in detail.