Skip to main content

Build your first Blueprint

Let's build an elementary Blueprint that

  1. Creates a new WordPress site
  2. Sets the site title to "My first Blueprint"
  3. Installs the Adventurer theme
  4. Installs the Hello Dolly plugin from the WordPress plugin directory
  5. Installs a custom plugin
  6. Changes the site content

1. Create a new WordPress site

Let's start by creating a blueprint.json file with the following contents:

{}

It may seem like nothing is happening, but this Blueprint already spins up a WordPress site with the latest major version.

  Run Blueprint  

Autocomplete

If you use an IDE, like VS Code or PHPStorm, you can use the Blueprint JSON Schema for an autocompleted Blueprint development experience. Add the following line at the top of your blueprint.json file:

{
"$schema": "https://playground.wordpress.net/blueprint-schema.json"
}

Here's what it looks like in VS Code:

Autocompletion visualized

2. Set the site title to "My first Blueprint"

Blueprints consist of a series of steps that define how to build a WordPress site. Before you write the first step, declare an empty list of steps:

{
"$schema": "https://playground.wordpress.net/blueprint-schema.json",
"steps": []
}

This Blueprint isn't very exciting—it creates the same default site as the empty Blueprint above. Let's do something about it!

WordPress stores the site title in the blogname option. Add your first step and set that option to "My first Blueprint":

{
"$schema": "https://playground.wordpress.net/blueprint-schema.json",
"steps": [
{
"step": "setSiteOptions",
"options": {
"blogname": "My first Blueprint"
}
}
]
}

  Run Blueprint  

The setSiteOptions step specifies the site options in the WordPress database. The options object contains the key-value pairs to set. In this case, you changed the value of the blogname key to "My first Blueprint". You can read more about all available steps in the Blueprint Steps API Reference.

Shorthands

You can specify some steps using a shorthand syntax. For example, you could write the setSiteOptions step like this:

{
"$schema": "https://playground.wordpress.net/blueprint-schema.json",
"siteOptions": {
"blogname": "My first Blueprint"
}
}

The shorthand syntax and the step syntax correspond with each other. Every step specified with the shorthand syntax is automatically added at the beginning of the steps array in an arbitrary order. Which should you choose? Use shorthands when brevity is your main concern, use steps when you need more control over the order of execution.

3. Install the Adventurer theme

Adventurer is an open-source theme available in the WordPress theme directory. Let's install it using the installTheme step:

{
"siteOptions": {
"blogname": "My first Blueprint"
},
"steps": [
{
"step": "installTheme",
"themeZipFile": {
"resource": "wordpress.org/themes",
"slug": "adventurer"
}
}
]
}

  Run Blueprint  

The site should now look like the screenshot below:

Site with the adventurer theme

Resources

The themeZipFile defines a resource and referrences an external file required to complete the step. Playground supports different types of resources, including

  • url,
  • wordpress.org/themes,
  • wordpress.org/plugins,
  • vfs(virtual file system), or
  • literal.

The example uses the wordpress.org/themes resource, which requires a slug identical to the one used in WordPress theme directory:

In this case, https://wordpress.org/themes/<slug>/ becomes https://wordpress.org/themes/adventurer/.

note

Learn more about the supported resources in the Blueprint Resources API Reference.

4. Install the Hello Dolly plugin

A classic WordPress plugin that displays random lyrics from the song "Hello, Dolly!" in the admin dashboard. Let's install it using the installPlugin step:

{
"siteOptions": {
"blogname": "My first Blueprint"
},
"steps": [
{
"step": "installTheme",
"themeZipFile": {
"resource": "wordpress.org/themes",
"slug": "adventurer"
}
},
{
"step": "installPlugin",
"pluginZipFile": {
"resource": "wordpress.org/plugins",
"slug": "hello-dolly"
}
}
]
}

  Run Blueprint  

The Hello Dolly plugin is now installed and activated.

Like the themeZipFile, the pluginZipFile defines a reference to an external file required for the step. The example uses the wordpress.org/plugins resource to install the plugin with the matching slug from the WordPress plugin directory.

5. Install a custom plugin

Let's install a custom WordPress plugin that adds a message to the admin dashboard:

<?php
/*
Plugin Name: "Hello" on the Dashboard
Description: A custom plugin to showcase WordPress Blueprints
Version: 1.0
Author: WordPress Contributors
*/

function my_custom_plugin() {
echo '<h1>Hello from My Custom Plugin!</h1>';
}

add_action('admin_notices', 'my_custom_plugin');

You can use the installPlugin, but that requires creating a ZIP file. Let's start with something different to see if the plugin works:

  1. Create a wp-content/plugins/hello-from-the-dashboard directory using the mkdir step.
  2. Write a plugin.php file using the writeFile step.
  3. Activate the plugin using the activatePlugin step.

Here's what that looks like in a Blueprint:

{
// ...
"steps": [
// ...
{
"step": "mkdir",
"path": "/wordpress/wp-content/plugins/hello-from-the-dashboard"
},
{
"step": "writeFile",
"path": "/wordpress/wp-content/plugins/hello-from-the-dashboard/plugin.php",
"data": "<?php\n/*\nPlugin Name: \"Hello\" on the Dashboard\nDescription: A custom plugin to showcase WordPress Blueprints\nVersion: 1.0\nAuthor: WordPress Contributors\n*/\n\nfunction my_custom_plugin() {\n echo '<h1>Hello from My Custom Plugin!</h1>';\n}\n\nadd_action('admin_notices', 'my_custom_plugin');"
},
{
"step": "activatePlugin",
"pluginPath": "hello-from-the-dashboard/plugin.php"
}
]
}

The last thing to do is log the user in as an admin. You can do that with a shorthand of the login step:

{
"login": true,
"steps": {
// ...
}
}

Here's the complete Blueprint:

{
"$schema": "https://playground.wordpress.net/blueprint-schema.json",
"login": true,
"siteOptions": {
"blogname": "My first Blueprint"
},
"steps": [
{
"step": "installTheme",
"themeZipFile": {
"resource": "wordpress.org/themes",
"slug": "adventurer"
}
},
{
"step": "installPlugin",
"pluginZipFile": {
"resource": "wordpress.org/plugins",
"slug": "hello-dolly"
}
},
{
"step": "mkdir",
"path": "/wordpress/wp-content/plugins/hello-from-the-dashboard"
},
{
"step": "writeFile",
"path": "/wordpress/wp-content/plugins/hello-from-the-dashboard/plugin.php",
"data": "<?php\n/*\nPlugin Name: \"Hello\" on the Dashboard\nDescription: A custom plugin to showcase WordPress Blueprints\nVersion: 1.0\nAuthor: WordPress Contributors\n*/\n\nfunction my_custom_plugin() {\n echo '<h1>Hello from My Custom Plugin!</h1>';\n}\n\nadd_action('admin_notices', 'my_custom_plugin');"
},
{
"step": "activatePlugin",
"pluginPath": "hello-from-the-dashboard/plugin.php"
}
]
}

  Run Blueprint  

That's what it looks like when you navigate to the dashboard:

Site with the custom plugin

Create a plugin and zip it

Encoding PHP files as JSON can be useful for quick testing, but it's inconvenient and difficult to read. Instead, create a file with the plugin code, compress it, and use the ZIP file as the resource in the installPlugin step to install it (the path in the URL should match the one in your GitHub repository):

{
"$schema": "https://playground.wordpress.net/blueprint-schema.json",
"login": true,
"siteOptions": {
"blogname": "My first Blueprint"
},
"steps": [
{
"step": "installTheme",
"themeZipFile": {
"resource": "wordpress.org/themes",
"slug": "adventurer"
}
},
{
"step": "installPlugin",
"pluginZipFile": {
"resource": "wordpress.org/plugins",
"slug": "hello-dolly"
}
},
{
"step": "installPlugin",
"pluginZipFile": {
"resource": "url",
"url": "https://raw.githubusercontent.com/wordpress/blueprints/trunk/docs/assets/hello-from-the-dashboard.zip"
}
}
]
}

You can shorten that Blueprint even more using the shorthand syntax:

{
"$schema": "https://playground.wordpress.net/blueprint-schema.json",
"login": true,
"siteOptions": {
"blogname": "My first Blueprint"
},
"plugins": ["hello-dolly", "https://raw.githubusercontent.com/wordpress/blueprints/trunk/docs/assets/hello-from-the-dashboard.zip"],
"steps": [
{
"step": "installTheme",
"themeZipFile": {
"resource": "wordpress.org/themes",
"slug": "adventurer"
}
}
]
}

  Run Blueprint  

6. Change the site content

Finally, let's delete the default content of the site and import a new one from a WordPress export file (WXR).

Delete the old content

There isn't a Blueprint step to delete the default content, but you can do that with a snippet of PHP code:

<?php
require '/wordpress/wp-load.php';

// Delete all posts and pages
$posts = get_posts(array(
'numberposts' => -1,
'post_type' => array('post', 'page'),
'post_status' => 'any'
));

foreach ($posts as $post) {
wp_delete_post($post->ID, true);
}

To run that code during the site setup, use the runPHP step:

{
// ...
"steps": [
// ...
{
"step": "runPHP",
"code": "<?php\nrequire '/wordpress/wp-load.php';\n\n$posts = get_posts(array(\n 'numberposts' => -1,\n 'post_type' => array('post', 'page'),\n 'post_status' => 'any'\n));\n\nforeach ($posts as $post) {\n wp_delete_post($post->ID, true);\n}"
}
]
}

Import the new content

Let's use the importWxr step to import a WordPress export (WXR) file that helps test WordPress themes. The file is available in the WordPress/theme-test-data repository, and you can access it via its raw.githubusercontent.com address: https://raw.githubusercontent.com/WordPress/theme-test-data/master/themeunittestdata.wordpress.xml.

Here's what the final Blueprint looks like:

{
"$schema": "https://playground.wordpress.net/blueprint-schema.json",
"login": true,
"siteOptions": {
"blogname": "My first Blueprint"
},
"plugins": ["hello-dolly", "https://raw.githubusercontent.com/wordpress/blueprints/trunk/docs/assets/hello-from-the-dashboard.zip"],
"steps": [
{
"step": "installTheme",
"themeZipFile": {
"resource": "wordpress.org/themes",
"slug": "adventurer"
}
},
{
"step": "runPHP",
"code": "<?php\nrequire '/wordpress/wp-load.php';\n\n$posts = get_posts(array(\n 'numberposts' => -1,\n 'post_type' => array('post', 'page'),\n 'post_status' => 'any'\n));\n\nforeach ($posts as $post) {\n wp_delete_post($post->ID, true);\n}"
},
{
"step": "importWxr",
"file": {
"resource": "url",
"url": "https://raw.githubusercontent.com/WordPress/theme-test-data/master/themeunittestdata.wordpress.xml"
}
}
]
}

  Run Blueprint  

And that's it. Congratulations on creating your first Blueprint! 🥳