---
slug: /blueprints/steps
description: The main API reference for the steps property.
---
# Steps
The `steps` property of a Blueprint is an array of steps to run. For example, this Blueprint logs the user in as an admin:
```json
{
"steps": [
{
"step": "login",
"username": "admin",
"password": "password"
}
]
}
```
Each step is an object that contains a `step` property that specifies the type of step to run. The rest of the properties depend on the type of step. Learn each step type below.
- [Resources References](/blueprints/steps/resources) describe external files in Blueprints.
- Some steps have a shorthand version. See [Shorthands](/blueprints/steps/shorthands).
- See [API Consistency](/blueprints/steps/api-consistency) for the Blueprint API and Function API.
- The [WordPress Playground Step Library](https://akirk.github.io/playground-step-library/#) offers a visual Blueprint editor.
## activatePlugin
Activates a WordPress plugin (if it's installed).
### Parameters
- **pluginName** (string) (optional) – Optional. Plugin name to display in the progress bar.
- **pluginPath** (string) – Path to the plugin directory as absolute path
(/wordpress/wp-content/plugins/plugin-name); or the plugin entry file
relative to the plugins directory (plugin-name/plugin-name.php).
### Blueprint API example
```json
{
"step": "activatePlugin",
"pluginName": "Gutenberg",
"pluginPath": "/wordpress/wp-content/plugins/gutenberg"
}
```
### Function API
`activatePlugin(playground, args, progress)`
```ts
import { activatePlugin } from '@wp-playground/blueprints';
activatePlugin(
playground,
{
pluginName: 'Gutenberg',
pluginPath: '/wordpress/wp-content/plugins/gutenberg',
},
progress
);
```
---
## activateTheme
Activates a WordPress theme (if it's installed).
### Parameters
- **themeFolderName** (string) – The name of the theme folder inside wp-content/themes/
### Blueprint API example
```json
{
"step": "activateTheme",
"themeFolderName": "storefront"
}
```
### Function API
`activateTheme(playground, args, progress)`
```ts
import { activateTheme } from '@wp-playground/blueprints';
activateTheme(
playground,
{
themeFolderName: 'storefront',
},
progress
);
```
---
## cp
Copies a file from one path to another.
### Parameters
- **fromPath** (string) – Source path
- **toPath** (string) – Target path
### Blueprint API example
```json
{
"step": "cp",
"fromPath": "/wordpress/index.php",
"toPath": "/wordpress/index2.php"
}
```
### Function API
`cp(playground, args, progress)`
```ts
import { cp } from '@wp-playground/blueprints';
cp(
playground,
{
fromPath: '/wordpress/index.php',
toPath: '/wordpress/index2.php',
},
progress
);
```
---
## defineSiteUrl
Sets [`WP_HOME`](https://developer.wordpress.org/advanced-administration/wordpress/wp-config/#blog-address-url) and [`WP_SITEURL`](https://developer.wordpress.org/advanced-administration/wordpress/wp-config/#wp-siteurl) constants for the WordPress installation.
Using this step on playground.wordpress.net is moot.
It is useful when building a custom Playground-based tool, like [`wp-now`](https://www.npmjs.com/package/@wp-now/wp-now),
or deploying Playground on a custom domain.
### Parameters
- **siteUrl** (string) – The URL
### Function API
`defineSiteUrl(playground, args, progress)`
---
## defineWpConfigConsts
Defines constants in a [`wp-config.php`](https://developer.wordpress.org/advanced-administration/wordpress/wp-config/) file.
This step can be called multiple times, and the constants will be merged.
### Parameters
- **consts** (Record) – The constants to define
- **method** (optional) – The method of defining the constants in wp-config.php. Possible values are:
- rewrite-wp-config: Default. Rewrites the wp-config.php file to
explicitly call define() with the requested
name and value. This method alters the file
on the disk, but it doesn't conflict with
existing define() calls in wp-config.php.
- define-before-run: Defines the constant before running the requested
script. It doesn't alter any files on the disk, but
constants defined this way may conflict with existing
define() calls in wp-config.php.
- **virtualize** (boolean) (optional)
### Blueprint API example
```json
{
"step": "defineWpConfigConsts",
"consts": {
"WP_DEBUG": true
}
}
```
### Function API
`defineWpConfigConsts(playground, args, progress)`
```ts
import { defineWpConfigConsts } from '@wp-playground/blueprints';
defineWpConfigConsts(
playground,
{
consts: {
WP_DEBUG: true,
},
},
progress
);
```
---
## enableMultisite
Defines the [Multisite](https://developer.wordpress.org/advanced-administration/multisite/create-network/) constants in a `wp-config.php` file.
This step can be called multiple times, and the constants will be merged.
### Parameters
- **wpCliPath** (string) (optional) – wp-cli.phar path
### Blueprint API example
```json
{
"step": "enableMultisite"
}
```
### Function API
`enableMultisite(playground, args, progress)`
```ts
import { enableMultisite } from '@wp-playground/blueprints';
enableMultisite(playground, {}, progress);
```
---
## importThemeStarterContent
Imports a theme's starter content into WordPress and publishes it.
The theme must already be installed. If it has no starter content, this step does nothing.
To import starter content when installing a theme, use `installTheme` with
`options.importStarterContent` set to `true`. Use this standalone step when you need to
add or modify starter content after installing the theme and before importing it.
For example, this complete Blueprint writes and activates a plugin that registers a
Home page as starter content for the active theme, then imports it and sets it as the
site's front page. The plugin runs on `after_setup_theme` at priority 100, after callbacks
with lower priorities, and replaces previously registered starter content. Callbacks
registered later at priority 100, or at a higher priority, can replace this content again
before it is imported. All plugin code is included inline; no external PHP file is needed.
```json
{
"steps": [
{
"step": "writeFile",
"path": "/wordpress/wp-content/plugins/theme-starter-content.php",
"data": " array(\n 'home' => array(\n 'post_type' => 'page',\n 'post_title' => 'Home',\n 'post_content' => 'Welcome to my Playground!'\n )\n ),\n 'options' => array(\n 'show_on_front' => 'page',\n 'page_on_front' => '{{home}}'\n )\n ) );\n}, 100 );"
},
{
"step": "activatePlugin",
"pluginPath": "theme-starter-content.php"
},
{
"step": "importThemeStarterContent"
}
]
}
```
Learn more about supported content and placeholders in
[Starter content for themes in 4.7](https://make.wordpress.org/core/2016/11/30/starter-content-for-themes-in-4-7/).
### Parameters
- **themeSlug** (string) (optional) – The slug of an installed theme to import content from. Defaults to the active theme.
### Blueprint API example
```json
{
"step": "importThemeStarterContent"
}
```
### Function API
`importThemeStarterContent(playground, args, progress)`
```ts
import { importThemeStarterContent } from '@wp-playground/blueprints';
importThemeStarterContent(playground, {}, progress);
```
---
## importWordPressFiles
Imports top-level WordPress files from a given zip file into
the `documentRoot`. For example, if a zip file contains the
`wp-content` and `wp-includes` directories, they will replace
the corresponding directories in Playground's `documentRoot`.
Imported copies of Playground-owned runtime artifacts are discarded. For
example, an archive cannot replace `mu-plugins/sqlite-database-integration`,
`mu-plugins/0-playground.php`, or a Playground-generated `db.php`. If those
paths still exist in the importing document root, its copies are retained.
An unmarked custom `db.php` remains part of the imported site.
A `formatVersion: 2` archive is otherwise authoritative for user-owned
`wp-content`: a customized Twenty Twenty-Five theme replaces the boot
default, while an absent theme remains deleted. For an older archive, stock
paths omitted by the exporter, such as `plugins/akismet`, `plugins/hello.php`,
and `themes/twentytwentyfive`, are restored from the importing document root
only when absent from the archive.
### Parameters
- **pathInZip** (string) (optional) – The path inside the zip file where the WordPress files are.
- **wordPressFilesZip** (ResourceType) – The zip file containing the top-level WordPress files and
directories.
### Blueprint API example
```json
{
"step": "importWordPressFiles",
"wordPressFilesZip": {
"resource": "url",
"url": "https://mysite.com/import.zip"
}
}
```
### Function API
`importWordPressFiles(playground, args, progress)`
```ts
import { importWordPressFiles } from '@wp-playground/blueprints';
importWordPressFiles(
playground,
{
wordPressFilesZip: {
resource: 'url',
url: 'https://mysite.com/import.zip',
},
},
progress
);
```
---
## importWxr
Imports a WXR file into WordPress.
### Parameters
- **authorsMap** (Record) (optional) – Remote WXR author usernames keyed to existing local usernames.
- **authorsMode** (optional) – How to assign imported WXR authors to local WordPress users.
- **defaultAuthorUsername** (string) (optional) – The fallback local user for imported authors that cannot be mapped.
- **fetchAttachments** (boolean) (optional) – Whether to fetch and import attachment files referenced by the WXR file.
- **file** (ResourceType) – The file to import
- **importComments** (boolean) (optional) – Whether to import comments from the WXR file.
- **importUsers** (boolean) (optional) – Whether to create local users for imported WXR authors.
- **importer** (optional) – The importer to use. Possible values:
- `default`: The importer from https://github.com/humanmade/WordPress-Importer
- `data-liberation`: The experimental Data Liberation WXR importer developed at
https://github.com/WordPress/wordpress-playground/issues/1894
This option is deprecated. The syntax will not be removed, but once the
Data Liberation importer matures, it will become the only supported
importer and the `importer` option will be ignored.
- **rewriteUrls** (boolean) (optional) – Whether to rewrite imported URLs to the current site URL.
- **urlMapping** (Record) (optional) – Explicit URL replacements to apply when URL rewriting is enabled.
### Blueprint API example
```json
{
"step": "importWxr",
"file": {
"resource": "url",
"url": "https://your-site.com/starter-content.wxr"
}
}
```
### Function API
`importWxr(playground, args, progress)`
```ts
import { importWxr } from '@wp-playground/blueprints';
importWxr(
playground,
{
file: {
resource: 'url',
url: 'https://your-site.com/starter-content.wxr',
},
},
progress
);
```
---
## installPlugin
Installs a WordPress plugin in the Playground.
### Parameters
- **ifAlreadyInstalled** (optional) – What to do if the asset already exists.
- **options** (InstallPluginOptions) (optional) – Optional installation options.
- **pluginData** – The plugin files to install. It can be a plugin zip file, a single PHP
file, or a directory containing all the plugin files at its root.
- **pluginZipFile** (FileResource) (optional) – @deprecated. Use 'pluginData' instead.
### Blueprint API example
```json
{
"step": "installPlugin",
"pluginData": {
"resource": "wordpress.org/plugins",
"slug": "gutenberg"
},
"options": {
"activate": true
}
}
```
```json
{
"step": "installPlugin",
"pluginData": {
"resource": "git:directory",
"url": "https://github.com/wordpress/wordpress-playground.git",
"ref": "HEAD",
"path": "wp-content/plugins/hello-dolly"
},
"options": {
"activate": true
}
}
```
### Function API
`installPlugin(playground, args, progress)`
```ts
import { installPlugin } from '@wp-playground/blueprints';
installPlugin(
playground,
{
pluginData: {
resource: 'wordpress.org/plugins',
slug: 'gutenberg',
},
options: {
activate: true,
},
},
progress
);
```
---
## installTheme
Installs a WordPress theme in the Playground.
### Parameters
- **ifAlreadyInstalled** (optional) – What to do if the asset already exists.
- **options** (InstallThemeOptions) (optional) – Optional installation options.
- **themeData** – The theme files to install. It can be either a theme zip file, or a
directory containing all the theme files at its root.
- **themeZipFile** (FileResource) (optional) – @deprecated. Use 'themeData' instead.
### Blueprint API example
```json
{
"step": "installTheme",
"themeData": {
"resource": "wordpress.org/themes",
"slug": "pendant"
},
"options": {
"activate": true,
"importStarterContent": true
}
}
```
### Function API
`installTheme(playground, args, progress)`
```ts
import { installTheme } from '@wp-playground/blueprints';
installTheme(
playground,
{
themeData: {
resource: 'wordpress.org/themes',
slug: 'pendant',
},
options: {
activate: true,
importStarterContent: true,
},
},
progress
);
```
---
## login
Logs in to Playground.
Under the hood, this function sets the `PLAYGROUND_AUTO_LOGIN_AS_USER` constant.
The `0-auto-login.php` mu-plugin uses that constant to log in the user on the first load.
This step depends on the `@wp-playground/wordpress` package because
the plugin is located in and loaded automatically by the `@wp-playground/wordpress` package.
### Parameters
- **password** (string) (optional)
- **username** (string) (optional) – The user to log in as. Defaults to 'admin'.
### Blueprint API example
```json
{
"step": "login",
"username": "admin"
}
```
### Function API
`login(playground, args, progress)`
```ts
import { login } from '@wp-playground/blueprints';
login(
playground,
{
username: 'admin',
},
progress
);
```
---
## mkdir
Creates a directory at the specified path.
### Parameters
- **path** (string) – The path of the directory you want to create
### Blueprint API example
```json
{
"step": "mkdir",
"path": "/wordpress/my-new-folder"
}
```
### Function API
`mkdir(playground, args, progress)`
```ts
import { mkdir } from '@wp-playground/blueprints';
mkdir(
playground,
{
path: '/wordpress/my-new-folder',
},
progress
);
```
---
## mv
Moves a file or directory from one path to another.
### Parameters
- **fromPath** (string) – Source path
- **toPath** (string) – Target path
### Blueprint API example
```json
{
"step": "mv",
"fromPath": "/wordpress/index.php",
"toPath": "/wordpress/index2.php"
}
```
### Function API
`mv(playground, args, progress)`
```ts
import { mv } from '@wp-playground/blueprints';
mv(
playground,
{
fromPath: '/wordpress/index.php',
toPath: '/wordpress/index2.php',
},
progress
);
```
---
## resetData
Deletes the selected WordPress content through WordPress APIs so dependent
records are removed with it. Empty tables have their sequences reset so
later imports receive the identifiers they would on a site without the
removed content.
### Parameters
- **contentTypes** (optional) – Content types to remove. When omitted, all posts, pages, custom post
types, and comments are removed.
### Blueprint API example
```json
{
"step": "resetData"
}
```
### Function API
`resetData(playground, args, progress)`
```ts
import { resetData } from '@wp-playground/blueprints';
resetData(playground, {}, progress);
```
---
## rm
Removes a file at the specified path.
### Parameters
- **path** (string) – The path to remove
### Blueprint API example
```json
{
"step": "rm",
"path": "/wordpress/index.php"
}
```
### Function API
`rm(playground, args, progress)`
```ts
import { rm } from '@wp-playground/blueprints';
rm(
playground,
{
path: '/wordpress/index.php',
},
progress
);
```
---
## rmdir
Removes a directory at the specified path.
### Parameters
- **path** (string) – The path to remove
### Blueprint API example
```json
{
"step": "rmdir",
"path": "/wordpress/wp-admin"
}
```
### Function API
`rmdir(playground, args, progress)`
```ts
import { rmdir } from '@wp-playground/blueprints';
rmdir(
playground,
{
path: '/wordpress/wp-admin',
},
progress
);
```
---
## runPHP
Runs PHP code.
When running WordPress functions, the `code` key must first load [`wp-load.php`](https://github.com/WordPress/WordPress/blob/master/wp-load.php) and start with `" 'wp-load.php required for WP functionality', 'post_status' => 'publish')); ?>"
}
```
### Function API
`runPHP(playground, args, progress)`
```ts
import { runPHP } from '@wp-playground/blueprints';
runPHP(
playground,
{
code: " 'wp-load.php required for WP functionality', 'post_status' => 'publish')); ?>",
},
progress
);
```
---
## runPHPWithOptions
Runs PHP code.
When running WordPress functions, the `code` key must first load [`wp-load.php`](https://github.com/WordPress/WordPress/blob/master/wp-load.php) and start with `"",
"body": "Site Name Modified by runPHPWithOptions"
}
}
```
### Function API
`runPHPWithOptions(playground, args, progress)`
```ts
import { runPHPWithOptions } from '@wp-playground/blueprints';
runPHPWithOptions(
playground,
{
options: {
code: "",
body: 'Site Name Modified by runPHPWithOptions',
},
},
progress
);
```
---
## runSql
Run one or more SQL queries.
This step uses WP_MySQL_Naive_Query_Stream to parse and execute SQL queries using
streaming semantics. It supports multiline queries, comments, and queries
separated by semicolons. Each query is executed using `$wpdb`. This step assumes
a presence of the `sqlite-database-integration` plugin that ships the required
query tokenizer classes.
### Parameters
- **sql** (ResourceType) – The SQL to run. Each non-empty line must contain a valid SQL query.
### Blueprint API example
```json
{
"step": "runSql",
"sql": {
"resource": "literal",
"name": "schema.sql",
"contents": "DELETE FROM wp_posts"
}
}
```
### Function API
`runSql(playground, args, progress)`
```ts
import { runSql } from '@wp-playground/blueprints';
runSql(
playground,
{
sql: {
resource: 'literal',
name: 'schema.sql',
contents: 'DELETE FROM wp_posts',
},
},
progress
);
```
---
## setSiteLanguage
Sets the site language and download translations.
### Parameters
- **language** (string) – The language to set, e.g. 'en_US'
### Blueprint API example
```json
{
"step": "setSiteLanguage",
"language": "en_US"
}
```
### Function API
`setSiteLanguage(playground, args, progress)`
```ts
import { setSiteLanguage } from '@wp-playground/blueprints';
setSiteLanguage(
playground,
{
language: 'en_US',
},
progress
);
```
---
## setSiteOptions
Sets site options. This is equivalent to calling [`update_option`](https://developer.wordpress.org/reference/functions/update_option/) for each
option in the [`options`](https://developer.wordpress.org/apis/options/#available-options-by-category) object.
### Parameters
- **options** (Record) – The options to set on the site.
### Blueprint API example
```json
{
"step": "setSiteOptions",
"options": {
"blogname": "My Blog",
"blogdescription": "A great blog"
}
}
```
### Function API
`setSiteOptions(playground, args, progress)`
```ts
import { setSiteOptions } from '@wp-playground/blueprints';
setSiteOptions(
playground,
{
options: {
blogname: 'My Blog',
blogdescription: 'A great blog',
},
},
progress
);
```
---
## unzip
Unzip a zip file.
### Parameters
- **extractToPath** (string) – The path to extract the zip file to
- **zipFile** (ResourceType) (optional) – The zip file to extract
- **zipPath** (string) (optional) – The path of the zip file to extract
### Blueprint API example
```json
{
"step": "unzip",
"zipFile": {
"resource": "vfs",
"path": "/wordpress/data.zip"
},
"extractToPath": "/wordpress"
}
```
### Function API
`unzip(playground, args, progress)`
```ts
import { unzip } from '@wp-playground/blueprints';
unzip(
playground,
{
zipFile: {
resource: 'vfs',
path: '/wordpress/data.zip',
},
extractToPath: '/wordpress',
},
progress
);
```
---
## updateUserMeta
Updates user meta. This is equivalent to calling [`update_user_meta`](https://developer.wordpress.org/reference/functions/update_user_meta/) for each
meta value in the `meta` object.
### Parameters
- **meta** (Record) – An object of user meta values to set, e.g. { "first_name": "John" }
- **userId** (number) – User ID
### Blueprint API example
```json
{
"step": "updateUserMeta",
"meta": {
"first_name": "John",
"last_name": "Doe"
},
"userId": 1
}
```
### Function API
`updateUserMeta(playground, args, progress)`
```ts
import { updateUserMeta } from '@wp-playground/blueprints';
updateUserMeta(
playground,
{
meta: {
first_name: 'John',
last_name: 'Doe',
},
userId: 1,
},
progress
);
```
---
## wp-cli
Runs PHP code using [WP-CLI](https://developer.wordpress.org/cli/commands/).
### Parameters
- **command** – The WP CLI command to run.
- **wpCliPath** (string) (optional) – wp-cli.phar path
### Blueprint API example
```json
{
"step": "wp-cli",
"command": "wp post create --post_title='Test post' --post_excerpt='Some content'"
}
```
### Function API
`wpCLI(playground, args, progress)`
```ts
import { wpCLI } from '@wp-playground/blueprints';
wpCLI(
playground,
{
command: "wp post create --post_title='Test post' --post_excerpt='Some content'",
},
progress
);
```
---
## writeFile
Writes data to a file at the specified path.
### Parameters
- **data** – The data to write
- **path** (string) – The path of the file to write to
### Blueprint API example
```json
{
"step": "writeFile",
"path": "/wordpress/test.php",
"data": ""
}
```
### Function API
`writeFile(playground, args, progress)`
```ts
import { writeFile } from '@wp-playground/blueprints';
writeFile(
playground,
{
path: '/wordpress/test.php',
data: "",
},
progress
);
```
---
## writeFiles
Writes multiple files to a specified directory in the Playground
filesystem.
```
my-plugin/
├── index.php
└── public/
└── style.css
```
### Parameters
- **filesTree** – The 'filesTree' defines the directory structure. Inline directories can provide 'name' and
'files' without a 'resource' property. Explicit 'literal:directory' and 'git:directory'
resources are also supported. The 'name' represents the root directory, while 'files' maps
file paths to contents or nested subdirectories.
- **writeToPath** (string) – The path of the file to write to
### Blueprint API example
```json
{
"step": "writeFiles",
"writeToPath": "/wordpress/wp-content/plugins/my-plugin",
"filesTree": {
"name": "my-plugin",
"files": {
"index.php": "Hello World!'; ?>",
"public": {
"style.css": "a { color: red; }"
}
}
}
}
```
### Function API
`writeFiles(playground, args, progress)`
```ts
import { writeFiles } from '@wp-playground/blueprints';
writeFiles(
playground,
{
writeToPath: '/wordpress/wp-content/plugins/my-plugin',
filesTree: {
name: 'my-plugin',
files: {
'index.php': "Hello World!'; ?>",
public: {
'style.css': 'a { color: red; }',
},
},
},
},
progress
);
```