Version 0.24.0 released

As I mentioned in my WordCamp Europe talk:

Just like WordPress has plugins, the future of WP-CLIWP-CLI WP-CLI is the Command Line Interface for WordPress, used to do administrative and development tasks in a programmatic way. The project page is http://wp-cli.org/ https://make.wordpress.org/cli/ is packages of commands. For this future, I’m trying to proactively solve the problems WordPress has with plugins:

  • Where WordPress plugins are considered second-class to what’s included in coreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress., I’d like WP-CLI packages to be considered first-class citizens amongst the commands in WP-CLI.
  • All too often, WordPress plugins have just one author. I’d like for each WP-CLI package to have two or three active maintainers.

In this model, WP-CLI becomes the common interface, and supporting application layer, to a rich ecosystem of features. Doing so opens more frontiers for innovation, which leads to a greater selection of ideas to choose from. And because more people are involved in authoring packages, WP-CLI benefits from a larger contributor pool.

With this model, my focus shifts towards designing a world-class experience for WP-CLI package authorship. Read through the commands cookbook for a thorough introduction to creating a WP-CLI command. Check out wp scaffold package [repo] for the easiest way to generate the boilerplate for your new WP-CLI package. Weigh in with your thoughts on how we should evolve the WP-CLI package index. And follow @runcommand as I explore commercializing WP-CLI products and services — I hope that runcommand is just the first of several WP-CLI-based businesses.

One last ask: if you care about the WP-CLI release cycle, or dependencies and backwards compatibility, please let me know how often you think WP-CLI should be released.

Let’s get on with the show. Use wp cli update to install v0.24.0, representing 449 resolved issues and pull requests. Here’s what’s new.

Forked wp-settings.php no more

Every application has a bootstrap file which loads all of the requisite utilities needed to serve a request. In WordPress, this is called wp-settings.php.

Since v0.8.0 [#261], WP-CLI has used a forked version of this bootstrap file, called wp-settings-cli.php, to give it more control over the load process, providing features like --skip-plugins. But, because WordPress can require new files from wp-settings.php, maintaining a forked version has the unfortunate side effect of WP-CLI regularly breaking when a new version of WordPress is released.

Thanks to coordinated changes in the WordPress project, WP-CLI v0.24.0 returns to loading wp-settings.php for WordPress 4.6 and higher [#2278]. Doing so should make WP-CLI more future proof against new versions of WordPress.

More documentation in more languages

Thanks to tireless efforts by a solid group of contributors, WP-CLI now has more documentation in more languages.

Want to get involved with WP-CLI’s documentation? Check out the Github issues labeled “scope:documentation”.

Effortlessly use WP-CLI against any WordPress install

WP-CLI aliases are shortcuts you register in your wp-cli.yml or config.yml to effortlessly run commands against any WordPress install.

For instance, if I’m working locally on the runcommand theme, have registered a new rewrite rule, and need to flush rewrites inside my Vagrant-based virtual machine, I can run:

$ wp @dev rewrite flush
Success: Rewrite rules flushed.

Then, once the code goes to production, I can run:

$ wp @prod rewrite flush
Success: Rewrite rules flushed.

Look ma! No more SSHSSH Secure SHell - a protocol for securely connecting to a remote system in addition to or in place of a password.’ing into machines, changing directories, and generally spending a full minute to get to a given WordPress install.

Additionally, alias groups let you register groups of aliases. If I want to run a command against both runcommand WordPress instances, I can use @both:

$ wp @both core check-update
Success: WordPress is at the latest version.
Success: WordPress is at the latest version.

Aliases can be registered in your project’s wp-cli.yml file, or your user’s global ~/.wp-cli/config.yml file:

@prod:
  ssh: runcommand@runcommand.io~/webapps/production
@dev:
  ssh: vagrant@192.168.50.10/srv/www/runcommand.dev
@both:
  - @prod
  - @dev

But wait, what’s the ‘ssh’ in there?

WP-CLI now natively supports a --ssh=<host> global parameter for running a command against a remote WordPress install. Many thanks to XWP and their community for paving the way with WP-CLI SSH.

Under the hood, WP-CLI proxies commands to the ssh executable, which then passes them to WP-CLI installed on the remote machine. Your syntax for -ssh=<host> can be any of the following:

  • Just the host (e.g. wp --ssh=runcommand.io), which means the user will be inferred from your current system user, and the path will be the SSH user’s home directory.
  • The user and the host (e.g. wp --ssh=runcommand@runcommand.io).
  • The user, the host, and the path to the WordPress install (e.g. wp --ssh=runcommand@runcommand.io~/webapps/production). The path comes immediately after the TLD of the host.

Or, if you use a ~/.ssh/config, <host> can be any host alias stored in the SSH config (e.g. wp --ssh=rc for me).

Note you do need a copy of WP-CLI on the remote server, accessible as wp. Futhermore, --ssh=<host> won’t load your .bash_profile if you have a shell alias defined, or are extending the $PATH environment variable. If this affects you, here’s a more thorough explanation of how you can make wp accessible.

Relevant pull requests for aliases and SSH support include: #2755, #2974, #3012, #3013, #3014, #3016, #3026, #3040, #3070, #3093, #3100, #3117, #3134, #3135, #3145, #3161, #3180.

Everything else in 0.24.0

Command improvements:

  • Adds a newline when using the wp shell interactive prompt [#2601, #2659].
  • Improves formatting of scaffolded plugins [#2588, #2598].
  • Introduces --format=ids to wp (*) generate commands for easier chaining [2622].
  • Adds term recount command for trigger a recount of taxonomyTaxonomy A taxonomy is a way to group things together. In WordPress, some common taxonomies are category, link, tag, or post format. https://codex.wordpress.org/Taxonomies#Default_Taxonomies. terms assigned to posts [#2625, #2628].
  • Normalizes pluginPlugin A plugin is a piece of software containing a group of functions that can be added to a WordPress website. They can extend functionality or add new features to your WordPress websites. WordPress plugins are written in the PHP programming language and integrate seamlessly with WordPress. These can be free in the WordPress.org Plugin Directory https://wordpress.org/plugins/ or can be cost-based plugin from a third-party / theme version numbers and headerHeader The header of your site is typically the first thing people will experience. The masthead or header art located across the top of your page is part of the look and feel of your website. It can influence a visitor’s opinion about your content and you/ your organization’s brand. It may also look different on different screen sizes. formatting when scaffolding [#2644].
  • Introduces --due-now to run all cron events due or overdue [#2658].
  • Permits wp cron (event|schedule) list and wp option list to output a single field [#2657, #3033].
  • Adds field filtering in cron event list command [#2674].
  • Includes a .distignore file when scaffolding a new plugin, to define files and folders excluded from distributions [#2697, #2756, #3042, #3088].
  • Displays a summary success message when using --dry-run with wp search-replace [#2740].
  • Scaffolds plugin based on supported WordPress version [#2751].
  • Applies extended insert format to search-replace SQL export, for a substantial performance boost [#2745].
  • Warns with wp core verify-checksums when extra files exist in wp-admin or wp-includes [#2638].
  • Supports --format=<format> argument for wp cap list, wp user list-caps, and wp super-admin list [#2851, #2961, and #2949].
  • Accepts multiple term IDs with wp term url [#2865].
  • Supports PHPPHP PHP (recursive acronym for PHP: Hypertext Preprocessor) is a widely-used open source general-purpose scripting language that is especially suited for web development and can be embedded into HTML. http://php.net/manual/en/intro-whatis.php. 5.5 Memcache extension when checking cache type [#2945].
  • Uses WP_CLI::warning() when a theme is already active, to make behavior more consistent with plugin activation [#3015].
  • Adds --porcelain flag to wp db export [#3032].
  • Allow the author field to be selected in wp theme list --fields=<field> [#3043].
  • Introduces wp widget reset <sidebar>, for removing all widgets from a sidebarSidebar A sidebar in WordPress is referred to a widget-ready area used by WordPress themes to display information that is not a part of the main content. It is not always a vertical column on the side. It can be a horizontal rectangle below or above the content area, footer, header, or any where in the theme. and placing them in the inactive sidebar [#3077].
  • Supports ‘trunk’ and ‘nightly’ version arguments for wp core download [#3127].
  • Adds verbosity to wp role reset [#3132, #3141].
  • Adds --include-columns=<columns> argument to wp search-replace [#3142].
  • Adds --ci=<provider> argument for wp plugin test scaffold, which supports ‘travis’, ‘circle’, or ‘gitlab’ [#3144, #3163].

Framework enhancements:

  • Uses is_callable() in WP_CLI::add_command(), instead of custom logic [#2595].
  • Introduces CompositeCommand->remove_subcommand(), and modifies the bootstrap process to always register core commands [#2629].
  • Runs before_invoke and after_invoke callbacks on subcommands, such that you can hook into immediately before and after subcommand execution [#2647, #2686].
  • Introduces --debug=<group> to limit debug output to a particular group of debug calls [#2648].
  • Interacts with the Package Index over SSLSSL Secure Socket Layer - Encryption from the server to the browser and back. Prevents prying eyes from seeing what you are sending between your browser and the server. [#2720].
  • Supports CSV with spaces when using --fields=<fields> [#2750].
  • Disables WP cron when ALTERNATE_WP_CRON is defined [#3118].
  • Supports positional arguments defined in wp-cli.yml [#3120].
  • Introduces WP_CLI_STRICT_ARGS_MODE for dealing with arg ambiguity [#3128].
  • Registers --http=<url> global parameter for use with RESTful WP-CLI [#3130].
  • Introduces WP_CLI::add_wp_hook(), for adding actions and filters when you don’t yet have access to actions and filters [#3195].
  • Increases minimum supported PHP version to 5.3.29 [#2672].

Bug fixes across the board:

  • Mitigates a DateTime fatal when instantiating the Composer object [#2607].
  • Squashes wp export notice about skip_comments [#2620].
  • Avoids regex to fix greedy parsing of parameter arguments [#2587, #2717].
  • Ensures default and options are used when supplied as arg args [#2741].
  • Considers image sizes missing when using wp media regenerate and sizes doesn’t have registered sizes [#2645].
  • Catches WP_Error from translations_api() [#2671, #3179].
  • Doesn’t erroneously try to (de)activate plugins with --all flag [#2692].
  • Defines DOING_CRON before WordPress is loaded when running wp cron event run [#2691].
  • Only attempts to use add_user_to_blog() on multisiteMultisite Multisite is a WordPress feature which allows users to create a network of sites on a single WordPress installation. Available since WordPress version 3.0, Multisite is a continuation of WPMU or WordPress Multiuser project. WordPress MultiUser project was discontinued and its features were included into WordPress core.https://codex.wordpress.org/Create_A_Network. when importing users from CSV [#2690].
  • Fixes listing user metaMeta Meta is a term that refers to the inside workings of a group. For us, this is the team that works on internal WordPress sites like WordCamp Central and Make WordPress. associated with a given username [#2700].
  • Differentiates output when moving comments to trashTrash Trash in WordPress is like the Recycle Bin on your PC or Trash in your Macintosh computer. Users with the proper permission level (administrators and editors) have the ability to delete a post, page, and/or comments. When you delete the item, it is moved to the trash folder where it will remain for 30 days. from output when deleting comments [#2701].
  • Prevents runaway memory usage from wp export by clearing object cache after each file [#2716].
  • Ignores ambigious empty plugin and theme slugs when installing [#2715].
  • Takes all digits when running commands that use the comment id [#2714, #2901].
  • Only displays packages directory path when it exists [#2773].
  • Bails early in theme commands if theme is broken or has error [#2798].
  • Displays error if theme directory exists but is erred; permits force install [#2821].
  • Fixes PHP notice when installing a child themeChild theme A Child Theme is a customized theme based upon a Parent Theme. It’s considered best practice to create a child theme if you want to modify the CSS of your theme. https://developer.wordpress.org/themes/advanced-topics/child-themes/., and running wp theme status [#2976, #3047].
  • Ensures YAML formatter handles objects and --fields=<fields> arg [#3060].
  • Fixes exception in wp menu list if --format=ids [#3075].
  • Populates recently active plugins list when deactivating a plugin [#3068].
  • Respects wp-cli.yml default values when applying argument defaults [#3111].
  • Calls wp_slash() on data passed to post, comment, term, and user commands [#3156, #3157, #3158, #3159, #3167, #3173].
  • Appropriately lists duplicated cron events [#3175].

Contributors to this release: andyexeter, bordoni, danielbachhuber, diggy, enrico-sorcinelli, ernilambar, geo4orce, gedex, gilbitron, hideokamoto, apertureless, JRGould, johnbillion, kkoppenhaver, kouratoras, markjaquith, miya0001, mustafauysal, NateWr, Nikschavan, ocean90, petenelson, phh, rachelbaker, PatelUtkarsh, PeterDaveHello, robhenley rodrigoprimo, roelveldhuizen, ShinichiNishikawa, shulard, stephenharris, stevenkword, swissspidy, taianunes, villevuor, voldemortensen, wesm87, 8bitodyssey

You can browse the full list of resolved issues on GithubGitHub GitHub is a website that offers online implementation of git repositories that can easily be shared, copied and modified by other developers. Public repositories are free to host, private repositories require a paid subscription. GitHub introduced the concept of the ‘pull request’ where code changes done in branches by contributors can be reviewed and discussed before being merged be the repository owner. https://github.com/.

Back to work!

RESTful WP-CLI – The final update?

Last November, I published a Kickstarter, and was completely blown away by the support. This month, the funding ran out, so I thought I’d post one last RESTful WP-CLI update.

Actually, the story doesn’t end here. I’m writing a massive retrospective post about using Kickstarter to fund open sourceOpen Source Open Source denotes software for which the original source code is made freely available and may be redistributed and modified. Open Source **must be** delivered via a licensing model, see GPL., so keep an eye out for that. Also, WP-CLIWP-CLI WP-CLI is the Command Line Interface for WordPress, used to do administrative and development tasks in a programmatic way. The project page is http://wp-cli.org/ https://make.wordpress.org/cli/ v0.24.0 is due out a week from now, July 27th, and it’s looking to be the largest release ever. When you do a Kickstarter, it’s really just the beginning of something bigger.

Enough with the superlatives, let’s dive into some new features. Remember: RESTful WP-CLI features require under the hood changes to WP-CLI. You’ll want to wp cli update --nightly to play with this new functionality locally. Once you’ve done so, you can wp package install wp-cli/restful to install the latest.

Effortlessly use WP-CLI against any WordPress install

WP-CLI aliases are shortcuts you register in your wp-cli.yml or config.yml to effortlessly run commands against any WordPress install.

For instance, if I’m working locally on the runcommand theme, have registered a new rewrite rule, and need to flush rewrites inside my Vagrant-based virtual machine, I can run:

$ wp @dev rewrite flush
Success: Rewrite rules flushed.

Then, once the code goes to production, I can run:

$ wp @prod rewrite flush
Success: Rewrite rules flushed.

Look ma! No more SSHSSH Secure SHell - a protocol for securely connecting to a remote system in addition to or in place of a password.’ing into machines, changing directories, and generally spending a full minute to get to a given WordPress install.

Additionally, alias groups let you register groups of aliases. If I want to run a command against both runcommand WordPress instances, I can use @both:

$ wp @both core check-update
Success: WordPress is at the latest version.
Success: WordPress is at the latest version.

Aliases can be registered in your project’s wp-cli.yml file, or your user’s global ~/.wp-cli/config.yml file:

@prod:
  ssh: runcommand@runcommand.io~/webapps/production
@dev:
  ssh: vagrant@192.168.50.10/srv/www/runcommand.dev
@both:
  - @prod
  - @dev

But wait, what’s the ‘ssh’ in there?

WP-CLI now natively supports a --ssh=<host> global parameter for running a command against a remote WordPress install. Many thanks to XWP and their community for paving the way with WP-CLI SSH.

Under the hood, WP-CLI proxies commands to the ssh executable, which then passes them to WP-CLI installed on the remote machine. Your syntax for -ssh=<host> can be any of the following:

  • Just the host (e.g. wp --ssh=runcommand.io), which means the user will be inferred from your current system user, and the path will be the SSH user’s home directory.
  • The user and the host (e.g. wp --ssh=runcommand@runcommand.io).
  • The user, the host, and the path to the WordPress install (e.g. wp --ssh=runcommand@runcommand.io~/webapps/production). The path comes immediately after the TLD of the host.

Or, if you use a ~/.ssh/config, <host> can be any host alias stored in the SSH config (e.g. wp --ssh=rc for me).

Note you do need a copy of WP-CLI on the remote server, accessible as wp. Futhermore, --ssh=<host> won’t load your .bash_profile if you have a shell alias defined, or are extending the $PATH environment variable. If this affects you, here’s a more thorough explanation of how you can make wp accessible.

RESTful WP-CLI v0.2.0 and beyond

Today marks the release of RESTful WP-CLI v0.2.0. Among 43 closed issues and pull requests, I’d like to highlight two new features.

First, use wp rest (post|user|comment|*) generate to create an arbitrary number of any resource:

$ wp @wpdev rest post generate --count=50 --title="Test Post"
Generating items  100% [==============================================] 0:01 / 0:02

When working on a site locally, you often need dummy content to work with. There are a myriad of ways custom post types can store data in the database though, so generating dummy content can be a painstaking process. Because the WP REST APIREST API The REST API is an acronym for the RESTful Application Program Interface (API) that uses HTTP requests to GET, PUT, POST and DELETE data. It is how the front end of an application (think “phone app” or “website”) can communicate with the data store (think “database” or “file system”) https://developer.wordpress.org/rest-api/. represents a layer of abstraction between the client (e.g. WP-CLI in this case) and the database, it’s much easier to produce a general purpose content generation command.

In the future, I’d love to see dummy data generated for each field based on the resource schema.

Second, use wp rest (post|user|comment|*) diff to compare resources between two enviroments:

# "command" isn't a typo in this example; "command" is a content type expressed through the WP REST API on runcommand.io
$ wp @dev rest command diff @prod find-unused-themes --fields=title
(-) http://runcommand.dev/api/ (+) https://runcommand.io/api/
  command:
  + title: find-unused-themes

When working with multiple WordPress environments, you may want to know how these environments differ. Because the WP REST API represents a higher-level abstraction on top of WordPress, computing the difference between two environments becomes a matter of fetching the data and producing a comparison.

There are a number of ways the diff command could be improved, so consider this implementation to be the prototype.

What’s next?

More immediately, I’d like to start looking at how well RESTful WP-CLI works with plugins and themes. If you’ve written custom endpoints for the WP REST API, please weigh in on this Github issue so I can check it out.

Ultimately, the goal is for wp rest post to replace wp post, but there are many months between here and there. In this future where WP-CLI packages are first-class citizens amongst the commands in WP-CLI coreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress., RESTful WP-CLI gets to serve as a testbed for figuring out how that actually works. We shall see, we shall see.

As always, thanks for your support!

The future of WP-CLI

As you might be aware, WP-CLIWP-CLI WP-CLI is the Command Line Interface for WordPress, used to do administrative and development tasks in a programmatic way. The project page is http://wp-cli.org/ https://make.wordpress.org/cli/ is an indispensable tool for many individuals and companies. We very much appreciate our community of users (although we have no idea how many of you there actually are), and want to ensure our relationship is strong for the years to come.

Just over a month ago, I started a Github issue with this question:

how do I reduce WP-CLI’s bus factor, and more generally lay a foundation for WP-CLI’s long-term organizational stability?

Although things seem to be going reasonably well now, I want to make sure we’re taking steps towards ensuring the long-term continuity of the project. Today, Andreas (WP-CLI’s founder) and I sat down for breakfast to discuss our options and how we want to proceed.

Based on our conversation, we think the most important task is to reduce WP-CLI’s bus factor and onboard one or more additional maintainers to focus on a few non-code roles:

  • Documentation – Help ensure WP-CLI’s documentation is world-class.
  • Marketing / community management – Help spread the word about WP-CLI.
  • Support – Help WP-CLI users where they’re asking questions, let it be GithubGitHub GitHub is a website that offers online implementation of git repositories that can easily be shared, copied and modified by other developers. Public repositories are free to host, private repositories require a paid subscription. GitHub introduced the concept of the ‘pull request’ where code changes done in branches by contributors can be reviewed and discussed before being merged be the repository owner. https://github.com/, WordPress.orgWordPress.org The community site where WordPress code is created and shared by the users. This is where you can download the source code for WordPress core, plugins and themes as well as the central location for community conversations and organization. https://wordpress.org/, Stack Exchange, or elsewhere.

Contributions in these areas will always be welcome. Maintainership is a longer-term commitment to the project, focused on ongoing improvements to the specific area. WP-CLI expects its maintainers to commit a few hours per week to the project.

At this time, we don’t have plans to establish a legal WP-CLI organization. We’ve decided the operational complexities exceed the benefits. While many companies and individuals want to donate to WP-CLI, introducing money always has the possibility of causing more harm than good. Instead, we’ll use Kickstarter to fund larger endeavors (e.g. a logo and website redesign) on an as-needed basis.

If you would like to become a maintainer of WP-CLI in a non-code role, please email info@wp-cli.org. Expect to participate in a trial period of 2-3 months.

We have a Mailchimp mailing list now too. Sign up for email notifications of new versions and occasional announcements about the project.

Thanks,

Daniel Bachhuber, maintainer
Andreas Creten, founder

Version 0.23.1 released

WP-CLIWP-CLI WP-CLI is the Command Line Interface for WordPress, used to do administrative and development tasks in a programmatic way. The project page is http://wp-cli.org/ https://make.wordpress.org/cli/ v0.23.1 is a compatibility release for those who’ve installed WP-CLI with Composer and require a minimum-stability. See #2664 for related conversation.

If you’re using the Phar distribution of WP-CLI, you should wp cli update, but don’t need to prioritize it, as the release doesn’t change WP-CLI’s behavior in any significant way.

Contributors to this release: danielbachhuber

You can browse the full list of resolved issues on GithubGitHub GitHub is a website that offers online implementation of git repositories that can easily be shared, copied and modified by other developers. Public repositories are free to host, private repositories require a paid subscription. GitHub introduced the concept of the ‘pull request’ where code changes done in branches by contributors can be reviewed and discussed before being merged be the repository owner. https://github.com/.

RESTful WP-CLI – What I’ve been hacking on

Let me just say — Thursday, February 4th was pretty darn demoralizing. I spent a huge amount of time in January towards the WP REST APIREST API The REST API is an acronym for the RESTful Application Program Interface (API) that uses HTTP requests to GET, PUT, POST and DELETE data. It is how the front end of an application (think “phone app” or “website”) can communicate with the data store (think “database” or “file system”) https://developer.wordpress.org/rest-api/. in preparation for what I wanted to do on the command line, and a lot of momentum / inspiration / general good feelings were destroyed in that meeting. As such, I spent much of February and March working on WP-CLIWP-CLI WP-CLI is the Command Line Interface for WordPress, used to do administrative and development tasks in a programmatic way. The project page is http://wp-cli.org/ https://make.wordpress.org/cli/ features unrelated to the WP REST API (e.g. package management).

But, I’m back in the saddle. Because I’m 2/3 of the way through one of those fancy WP REST API + ReactReact React is a JavaScript library that makes it easy to reason about, construct, and maintain stateless and stateful user interfaces. https://reactjs.org/. WordPress applications, I’m running into dozens of ways I want to be able to make WordPress more efficiently. And of course, this means doing it on the command line.

Before we proceed: most of the, if not all, RESTful WP-CLI features have required under the hood changes to WP-CLI. You’ll want to wp cli update --nightly to play with this new functionality locally. Once you’ve done so, you can wp package install danielbachhuber/wp-rest-cli to install the latest.

Use --debug and --debug=rest to profile your REST endpoints

REST APIs are all about speed. Milliseconds matter, and every one you manage to shave off will have a real world impact on user experience.

To make it much, much easier to understand how many queries your endpoint is performing, and how long they take, I’ve added some lightweight profiling to RESTful WP-CLI.

Use --debug to get a summary of your queries for any command.

$ wp rest post list --debug
Debug (rest): REST command executed 7 queries in 0.001954 seconds. Use --debug=rest to see all queries. (1.446s)
+----+-----------------------------+
| id | title                       |
+----+-----------------------------+
| 1  | {"rendered":"Hello world!"} |
+----+-----------------------------+

Use --debug=rest to get the full list of queries executed.

$ wp rest post list --fields=id,title --debug=rest
Debug: REST command executed 7 queries in 0.001696 seconds. Ordered by slowness, the queries are:
1:
  - 0.000291 seconds
  - WP_REST_Posts_Controller->get_items, WP_Query->query, WP_Query->get_posts
  - SELECT SQL_CALC_FOUND_ROWS  wp_posts.ID FROM wp_posts  WHERE 1=1  AND wp_posts.post_type = 'post' AND (wp_posts.post_status = 'publish')  ORDER BY wp_posts.post_date DESC LIMIT 0, 10
2:
  - 0.000257 seconds
  - WP_REST_Posts_Controller->get_items, WP_Query->query, WP_Query->get_posts, WP_Query->set_found_posts
  - SELECT FOUND_ROWS()
3:
  - 0.000256 seconds
  - WP_REST_Posts_Controller->get_items, WP_REST_Posts_Controller->prepare_item_for_response, setup_postdata, WP_Query->setup_postdata, get_userdata, get_user_by, WP_User::get_data_by
  - SELECT * FROM wp_users WHERE ID = '1'
4:
  - 0.000244 seconds
  - WP_REST_Posts_Controller->get_items, WP_REST_Posts_Controller->prepare_item_for_response, setup_postdata, WP_Query->setup_postdata, get_userdata, get_user_by, WP_User->init, WP_User->for_blog, WP_User->_init_caps, get_user_meta, get_metadata, update_meta_cache
  - SELECT user_id, meta_key, meta_value FROM wp_usermeta WHERE user_id IN (1) ORDER BY umeta_id ASC
5:
  - 0.000233 seconds
  - WP_REST_Posts_Controller->get_items, WP_Query->query, WP_Query->get_posts, _prime_post_caches
  - SELECT wp_posts.* FROM wp_posts WHERE ID IN (1)
6:
  - 0.000209 seconds
  - WP_REST_Posts_Controller->get_items, WP_Query->query, WP_Query->get_posts, _prime_post_caches, update_post_caches, update_object_term_cache, wp_get_object_terms
  - SELECT t.*, tt.*, tr.object_id FROM wp_terms AS t INNER JOIN wp_term_taxonomy AS tt ON tt.term_id = t.term_id INNER JOIN wp_term_relationships AS tr ON tr.term_taxonomy_id = tt.term_taxonomy_id  WHERE tt.taxonomy IN ('category', 'post_tag', 'post_format') AND tr.object_id IN (1) ORDER BY t.name ASC
7:
  - 0.000206 seconds
  - WP_REST_Posts_Controller->get_items, WP_Query->query, WP_Query->get_posts, _prime_post_caches, update_post_caches, update_postmeta_cache, update_meta_cache
  - SELECT post_id, meta_key, meta_value FROM wp_postmeta WHERE post_id IN (1) ORDER BY meta_id ASC
 (1.598s)
+----+-----------------------------+
| id | title                       |
+----+-----------------------------+
| 1  | {"rendered":"Hello world!"} |
+----+-----------------------------+

Profiling works for any CRUD operation.

$ wp rest post create --title="Test post" --user=daniel --debug
Debug (rest): REST command executed 28 queries in 0.023962 seconds. Use --debug=rest to see all queries. (1.777s)
Success: Created post.
$ wp rest post update 3 --content="Foo bar" --user=daniel --debug
Debug (rest): REST command executed 31 queries in 0.023309 seconds. Use --debug=rest to see all queries. (1.634s)
Success: Updated post.

Hopefully this feature becomes an invaluable part of your REST endpoint development process, as it has mine. Hit me with feedback on its Github issue.

Use wp rest * edit to edit a resource in your system editor

Most people probably don’t know this, but you can use wp post edit <id> to edit post content in your system editor (e.g. vim). Now, with wp rest * edit, you can edit any REST resource in your system editor.

$ wp rest post edit 3 --user=daniel

When you run wp rest * edit, RESTful WP-CLI fetches the resource, transforms it into a YAML document, and puts it in your system editor:

---
date: 2016-04-14T14:02:57
date_gmt: null
password:
slug:
status: draft
title:
  raw: Test post
  rendered: Test post
content:
  raw: Foo bar
  rendered: |
    |
        Foo bar
excerpt:
  raw:
  rendered: |
    |
        Foo bar
author: 1
featured_media: 0
comment_status: open
ping_status: open
sticky: false
format: standard
categories:
  - 1
tags: [ ]

If you make changes to any of the fields, then the command sends it back to WordPress (through the WP REST API) to update.

On WordPress installs that support Basic Auth, editing also works over HTTPHTTP HTTP is an acronym for Hyper Text Transfer Protocol. HTTP is the underlying protocol used by the World Wide Web and this protocol defines how messages are formatted and transmitted, and what actions Web servers and browsers should take in response to various commands.:

$ wp --http=http://daniel:daniel@wordpress-develop.dev rest post edit 1

Et, voila.

Get involved!

I’d love your input on the dozens of ideas I have for a more RESTful WP-CLI:

  • Render the help docs in formats like APIAPI An API or Application Programming Interface is a software intermediary that allows programs to interact with each other and share data in limited, clearly defined ways. Blueprint and Swagger [#36]
  • Introduce wp rest * generate to generate mock data in the format your application expects [#55].
  • Introduce wp rest * diff to be able to diff the state of two different WordPresses, a la Dictator [#56].
  • Figure out an elegant aliases implementation, so --http=http://daniel:daniel@wordpress-develop.dev becomes @wpdev [#2039]

And I want to hear your ideas too! As well as any feedback, questions, or violent dissent. Let’s chat on Github.

Version 0.23.0 released

It’s hard to believe the last WP-CLIWP-CLI WP-CLI is the Command Line Interface for WordPress, used to do administrative and development tasks in a programmatic way. The project page is http://wp-cli.org/ https://make.wordpress.org/cli/ release was only two months ago because this is the longest release post I’ve ever written. My apologies in advance.

If you don’t make it all of the way through, here’s what you absolutely need to know about WP-CLI v0.23.0:

  • This release includes WordPress 4.5 compatibility. Older WP-CLI versions are incompatible with WordPress 4.5. If you’re planning to use WordPress 4.5 in the future, you’ll need to upgrade before you do.
  • You can now browse available packages with wp package browse, and install them with wp package install. Try wp package install runcommand/db-ack.
  • There are many new tools for registering commands. Ain’t no more need to extend WP_CLI_Command. See the commands cookbook to learn more.
  • All of the wiki pages moved to a documentation portal on the website, including new pages documenting internal APIs you can use in your own commands. Pull requests encouraged.

Now that I’ve given away all of the surpises, let’s get on with the release post.

Oh darn, I forgot two more things:

  • For those using the Phar file, which should be most of you, WP-CLI now automatically checks for updates, and will prompt you to update as applicable. It even works for those using the nightly build. This behavior is configurable, see below.
  • I’ve settled on runcommand as the name for my new WP-CLI venture. Sign up for email updates on the website, or follow @runcommand on Twitter.

And now, the release post.

WordPress 4.5 compatibility

WordPress 4.5 loads yet another file in wp-settings.php. Because WP-CLI has a custom wp-settings-cli.php (background), WP-CLI v0.23.0 is the only release compatible with WordPress 4.5.

Importantly, due to the nature of these changes, WP-CLI versions prior to 0.23.0 will be incompatible with WordPress 4.5.

Inspect the nature of the change in this pull request.

Want to help fix this? Refill your cup of coffee and dive into #34936 on WordPress TracTrac Trac is the place where contributors create issues for bugs or feature requests much like GitHub.https://core.trac.wordpress.org/..

Install community commands from the Package Index

Consider the following situation (#2523):

Using the theme list command without --url parameter shows if a theme is enabled for the network and active in the default site.

If you pass the --url of a site of the network, this command shows if a theme is active in that site.

But I can’t find a way to list which themes are inactive in every site of the network so I can safely disable and delete them, and i’d love to have this feature

If you had to complete this task using the WordPress network admin, it would take you hours, if not days. Simply writing the WP-CLI command for this issue took me only 3 minutes (runcommand/find-unused-themes). WP-CLI is genuinely the fastest interface to manage WordPress.

WP-CLI also generally follows the 80/20 rule when deciding whether to introduce a new feature. If the feature could be useful to most people, then maybe; otherwise, probably not. Those 20% shouldn’t be left with the short stick though, particularly when it comes to the really helpful commands.

Today, I’m proud to reintroduce the Package Index, a directory of community-maintained WP-CLI packages. Browse available packages to install with wp package browse (doc). Once you’ve found the solution you’re looking for, install it with wp package install (doc):

$ wp package install runcommand/find-unused-themes
Installing runcommand/find-unused-themes (dev-master)
Updating /home/vagrant/.wp-cli/packages/composer.json to require the package...
Using Composer to install the package...
---
Loading composer repositories with package information
Updating dependencies
Analyzed 2223 packages to resolve dependencies
Analyzed 29243 rules to resolve dependencies
 - Installing package
Writing lock file
Generating autoload files
---
Success: Package installed successfully.
$ wp find-unused-themes
Checking http://wordpress-develop.dev/ for unused themes...
Checking http://wordpress-develop.dev/foo/ for unused themes...
+----------------+---------+
| name           | version |
+----------------+---------+
| default        | 1.7.2   |
| mystore        | 1.0.6   |
| p2             | 1.5.5   |
| twentyeleven   | 2.3     |
| twentyfourteen | 1.6     |
| twentyten      | 2.1     |
| twentythirteen | 1.8     |
| twentytwelve   | 1.9     |
+----------------+---------+

Pretty cool, huh? Consider WP-CLI’s package management to be a betaBeta A pre-release of software that is given out to a large group of users to trial under real conditions. Beta versions have gone through alpha testing in-house and are generally fairly close in look, feel and function to the final product; however, design changes often occur as part of the process. feature at this time. You may run into one of the open issues, or find a bug that hasn’t been reported yet. If you’re keen to take a deep dive into Composer’s internals, helping to improve wp package would be a great way to start.

Relevant pull requests for wp package include #2442, #2460, #2491, #2512, #2514, #2533, #2534, #2537, #2540, #2543, #2546, #2547, #2555, #2561

Register more commands

Ever wonder why, when writing your own command, you had to extend WP_CLI_Command? Well, you didn’t need to, actually.

In fact, WP_CLI::add_command() (doc) now supports registering any arbitrary callable as a WP-CLI command. For instance, here’s a closure command to reset the passwords of one or more users (runcommand/reset-passwords):

/**
 * Reset passwords for one or more WordPress users.
 *
 * <user>...
 * : Specify one or more user logins or IDs.
 */
$reset_password_command = function( $args ) {
    $fetcher = new WP_CLIFetchersUser;
    $users = $fetcher->get_many( $args );
    foreach( $users as $user ) {
        wp_update_user( array( 'ID' => $user->ID, 'user_pass' => wp_generate_password() ) );
        WP_CLI::log( "Reset password for {$user->user_login}." );
    }
    WP_CLI::success( 'Passwords reset.' );
};
WP_CLI::add_command( 'user reset-passwords', $reset_password_command );

Want to reuse argument definition between commands? You can now register command synopsis as the third argument to WP_CLI::add_command() (runcommand/hook):

WP_CLI::add_command( 'hook', $hook_command, array(
    'shortdesc' => 'List callbacks registered to a given action or filter.',
    'synopsis' => array(
        array(
            'name'        => 'hook',
            'type'        => 'positional',
            'description' => 'The key for the action or filter.',
        ),
        array(
            'name'        => 'format',
            'type'        => 'assoc',
            'description' => 'List callbacks as a table, JSON, or CSV.',
            'optional'    => true,
            'options'     => array( 'table', 'json', 'csv' ),
            'default'     => 'table',
        ),
    ),
) );

Note the default argument attribute for format. WP-CLI accepts default and options as a part of argument registration to make it easier to process user input within your command. These attributes can be also defined in the callable’s PHPDoc:

/**
 * List callbacks registered to a given action or filter.
 *
 * <hook>
 * : The key for the action or filter.
 *
 * [--format=<format>]
 * : List callbacks as a table, JSON or CSV.
 * ---
 * options:
 *   - table
 *   - json
 *   - csv
 * default: table
 * ---
 */
$hook_command = function( $args, $assoc_args ) {

Check out the commands cookbook for a deep dive into command registration. Relevant pull requests for these improvements to WP_CLI::add_command() include #2373, #2389, #2398, #2409, #2556, #2559.

More, better, easier to find documentation

It’s actually hard to imagine how people got around previously. Here’s what’s changed in documentationland:

  • The wiki has been reincarnated as the documentation portal on the website. I spent time cleaning up the pages as I moved them over; hopefully you find the new commands cookbook quite helpful.
  • Internal APIs you can use in your own commands are now publicly documented. The internal APIAPI An API or Application Programming Interface is a software intermediary that allows programs to interact with each other and share data in limited, clearly defined ways. pages are generated from the codebase, which should greatly help maintenance efforts.
  • On each command page, there’s a “GithubGitHub GitHub is a website that offers online implementation of git repositories that can easily be shared, copied and modified by other developers. Public repositories are free to host, private repositories require a paid subscription. GitHub introduced the concept of the ‘pull request’ where code changes done in branches by contributors can be reviewed and discussed before being merged be the repository owner. https://github.com/ issues” link to make it easier to find both open and closed issues for a given command. For instance, here are all of the outstanding issues for wp package and its subcommands. Keep in mind this isn’t necessarily exact, because I didn’t go back through and label all issues of all time. This feature will become more useful as time goes forward.

Relevant pull requests include #2454, #2487, #2494, #2499, #2507, #2513, #2515.

Automatic update checks

For those using WP-CLI as a Phar file, which should be most of you, version 0.23.0 and later will automatically check for updates. If an update is found, you’ll be prompted to install it.

Automatic update checks even work for those using the nightly build! Use wp cli update --nightly to get back on the nightly track after each major releaseMajor Release A set of releases or versions having the same major version number may be collectively referred to as “X.Y” -- for example version 5.2.x to refer to versions 5.2, 5.2.1, and all other versions in the 5.2. (five dot two dot) branch of that software. Major Releases often are the introduction of new major features and functionality..

By default, the automatic update check will run once a day for users with a writable WP-CLI Phar file. Distribution file or directory not writable? Then the check won’t run. Automatic update checks are triggered when a user, not a script, runs wp help <some-command>. This frequency can be configured with the WP_CLI_AUTO_CHECK_UPDATE_DAYS environment variable, or disabled entirely with the WP_CLI_DISABLE_AUTO_CHECK_UPDATE environment variable.

Relevant pull requests for this feature includes #2536 and #2538.

Everything else in 0.23.0

Command improvements:

  • Better performance for wp (user|post) list --format=count by only fetching the data we need [#2370, #2387].
  • Prevents dupe builds with Travis default settings in wp scaffold plugin-tests [#2377].
  • Generate comments for a specific post with wp comment generate --post_id=<post-id> [#2388].
  • Cleans up files from the prior version when using wp core (update|download) --force [#2382, #2406, #2413, #2432].
  • Adds a timer to individual events in wp cron event run [#2437].
  • Introduces wp term meta for managing term metaMeta Meta is a term that refers to the inside workings of a group. For us, this is the team that works on internal WordPress sites like WordCamp Central and Make WordPress. [#2444].
  • Adds CSV and JSONJSON JSON, or JavaScript Object Notation, is a minimal, readable format for structuring data. It is used primarily to transmit data between a server and web application, as an alternative to XML. output format to wp (theme|plugin) update [#2452].
  • Verifies MD5 hash of downloaded archive file with wp core download [#2461]
  • Entirely avoids loading WordPress in wp core verify-checksums [#2459].
  • Supports emptying term meta with wp site empty [#2506].
  • Adds WP REST APIREST API The REST API is an acronym for the RESTful Application Program Interface (API) that uses HTTP requests to GET, PUT, POST and DELETE data. It is how the front end of an application (think “phone app” or “website”) can communicate with the data store (think “database” or “file system”) https://developer.wordpress.org/rest-api/. registration args to scaffold (post-type|taxonomy) [#2551].
  • Adds documentation to test-sample.php and bootstrap.php when running wp scaffold plugin-tests [#2577, #2578].

Framework enhancements:

  • Switches WP_CLI::confirm() to automatically lowercase the response, permitting use of Y or y [#2366].
  • Adds (before|after)_wp(_config)_load hooksHooks In WordPress theme and development, hooks are functions that can be applied to an action or a Filter in WordPress. Actions are functions performed when a certain event occurs in WordPress. Filters allow you to modify certain functions. Arguments used to hook both filters and actions look the same. in WP load process, permitting code injected via --require to make modifications during the bootstrap process [#2375].
  • Adds .editorconfig to project root based on WordPress Coding StandardsWordPress Coding Standards The Accessibility, PHP, JavaScript, CSS, HTML, etc. coding standards as published in the WordPress Coding Standards Handbook. May also refer to The collection of PHP_CodeSniffer rules (sniffs) used to format and validate PHP code developed for WordPress according to the PHP coding standards. [#2395].
  • Encodes WP_Error data as JSON in WP_CLI::error_to_string() so that the data is actually human-readable [#2397].
  • Supports custom exit codes in WP_CLI::error() [#2440].
  • Introduces --format=yaml for easily displaying data as YAML [#2453].
  • Supports config deep merging and inheritance [#2496].
  • Updates Composer dependencies [#2554]

Bug fixes across the board:

  • In bin/install-wp-tests.sh, don’t cd in WP_TESTS_DIR before dowloading and setting up wp-tests-config.php [#2371].
  • When using --prompt, now only prompts for the first command in the execution thread. Previously, any use of WP_CLI::run_command() within a command would cause the prompting UXUX UX is an acronym for User Experience - the way the user uses the UI. Think ‘what they are doing’ and less about how they do it. to appear again [#2400].
  • Removes unnecessary exit on premature success for wp theme activate [#2412].
  • Checks if a taxonomyTaxonomy A taxonomy is a way to group things together. In WordPress, some common taxonomies are category, link, tag, or post format. https://codex.wordpress.org/Taxonomies#Default_Taxonomies. exists before listing its terms [#2414].
  • When trying to update a version of coreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress. that doesn’t exist, check the HTTPHTTP HTTP is an acronym for Hyper Text Transfer Protocol. HTTP is the underlying protocol used by the World Wide Web and this protocol defines how messages are formatted and transmitted, and what actions Web servers and browsers should take in response to various commands. response code before trying to unzip an invalid archive [#2368].
  • Fixes use of wp server when the PHPPHP PHP (recursive acronym for PHP: Hypertext Preprocessor) is a widely-used open source general-purpose scripting language that is especially suited for web development and can be embedded into HTML. http://php.net/manual/en/intro-whatis.php. binary contains spaces [#2422].
  • Respects --skip_comments flag for wp export, which has been broken for quite a while [#2427]
  • Persists IPTC data in wp media import when missing a title or caption; removes extension from default title [#2438, #2466].
  • Disables check translation updates when updating themes or plugins [#2439].
  • Corrects parameter sequence order when creating a new user on multisiteMultisite Multisite is a WordPress feature which allows users to create a network of sites on a single WordPress installation. Available since WordPress version 3.0, Multisite is a continuation of WPMU or WordPress Multiuser project. WordPress MultiUser project was discontinued and its features were included into WordPress core.https://codex.wordpress.org/Create_A_Network. [#2443].
  • Disables automatic colorization when --format=table [#2458].
  • Uses core’s version check API for finding updates, which gives us exact URLs to download offers [#2469].
  • Uses more robust failed download checking in wp cli update [#2488].
  • Runs help early for wp core commands used when core isn’t yet installed [#2497].
  • Fixes formatting of GLOBAL PARAMETERS when command has subcommands [#2516].
  • Properly handles multi-column keys in wp search-replace [#2531].
  • Uses correct path to autoloader when WP-CLI is installed to a parent Composer project [#2550].
  • Properly passes wp plugin search fields to plugins_api() request; adds page parameter [#2570, #2571].
  • Add parent as a potential status in wp theme status [#2573]

Contributors to this release: anantshri, danielbachhuber, edueo, GaryJones, gilbitron, hina, hinoue-work, jacobischwartz, marco-c, markjaquith, markkimsal, mbovel, ottok, rodrigoprimo, sourcerer-mike, staude, szepeviktor, za-creature

You can browse the full list of resolved issues on Github.

RESTful WP-CLI – No rest for the weary

Like my title? Get the pun? Te he he.

I’m just back from A Day of REST, where I spoke about a more RESTful WP-CLI, and unlocking the potential of the WP REST APIREST API The REST API is an acronym for the RESTful Application Program Interface (API) that uses HTTP requests to GET, PUT, POST and DELETE data. It is how the front end of an application (think “phone app” or “website”) can communicate with the data store (think “database” or “file system”) https://developer.wordpress.org/rest-api/. at the command line. It was probably the best talk I’ve ever done. You can check out my annotated slides if you haven’t already.

The talk covered the progress I’ve already made, and the hypotheticals on my mind every day when I go for a swim.

wp-rest-cli v0.1.0

Today marks v0.1.0 for wp-rest-cli. This initial release makes WP REST API endpoints available as WP-CLIWP-CLI WP-CLI is the Command Line Interface for WordPress, used to do administrative and development tasks in a programmatic way. The project page is http://wp-cli.org/ https://make.wordpress.org/cli/ commands. It does so by:

  • Auto-discovering endpoints from any WordPress site running WordPress 4.4 or higher.
  • Registering WP-CLI commands for the endpoints it understands.

Warning: This project is at a very early stage. Treat it as an experiment, and understand that breaking changes will be made without warning. The sky may also fall on your head.

Here’s how it works:

$ wp rest
usage: wp rest attachment <command>
   or: wp rest category <command>
   or: wp rest comment <command>
   or: wp rest meta <command>
   or: wp rest page <command>
   or: wp rest pages-revision <command>
   or: wp rest post <command>
   or: wp rest posts-revision <command>
   or: wp rest status <command>
   or: wp rest tag <command>
   or: wp rest taxonomy <command>
   or: wp rest type <command>
   or: wp rest user <command>

$ wp --http=demo.wp-api.org rest tag get 65 --format=json
{
  "id": 65,
  "link": "http://demo.wp-api.org/tag/dolor-in-sunt-placeat-molestiae-ipsam/",
  "name": "Dolor in sunt placeat molestiae ipsam",
  "slug": "dolor-in-sunt-placeat-molestiae-ipsam",
  "taxonomy": "post_tag"
}

Notice how you can use --http=<domain> to interact with a remote WordPress site. --http=<domain> must be supplied as the second argument to be used. Without it, wp-rest-cli will look for endpoints of a WordPress site in a directory specified by --path=<path> (or the current directory, if --path=<path isn’t supplied).

Using wp-rest-cli requires the latest nightly build of WP-CLI, which you can install with wp cli update --nightly. Once you’ve done so, you can install wp-rest-cli with wp package install danielbachhuber/wp-rest-cli.

Unreleased WP-CLI improvements

Wait, wp package install. What in the?

That’s right, WP-CLI now has package management. Using wp cli update --nightly, you now can:

  • wp package browse to browse packages available for installation.
  • wp package install to install a given package.
  • wp package list to list packages installed locally.
  • wp package uninstall to uninstall a given package.

While I wasn’t planning to dive down this rabbit hole during the Kickstarter project, I was finally inspired on how to finish the feature, and took a couple hours yesterday to do so. It’s amazing how you can be mentally blocked on a problem for literally two years but then, once you’re unblocked, finish it up in a short period of time.

You’ll probably run into one or more bugs with wp package. When you do, please let me know on this issue. If the bugs get too hairy, I may pull the feature from the release and revisit. But, for now, you can much more easily install and use community packages.

wp-rest-cli also makes use of another new feature: register arbitrary functions, closures, and class methods as WP-CLI commands.

For instance, given a closure $hook_command:

$hook_command = function( $args, $assoc_args ) {
    // the meat of the command
};
WP_CLI::add_command( 'hook', $hook_command, array(
    'shortdesc' => 'List callbacks registered to a given action or filter.',
    'synopsis' => array(
        array(
            'name'        => 'hook',
            'type'        => 'positional',
            'description' => 'The key for the action or filter.',
        ),
        array(
            'name'        => 'format',
            'type'        => 'assoc',
            'description' => 'List callbacks as a table, JSON, or CSV. Default: table.',
            'optional'    => true,
        ),
    ),
) );

Then, when you run wp hook init, you’ll see:

$ wp hook init
+---------------------------------+----------+---------------+
| function                        | priority | accepted_args |
+---------------------------------+----------+---------------+
| create_initial_post_types       | 0        | 1             |
| create_initial_taxonomies       | 0        | 1             |
| wp_widgets_init                 | 1        | 1             |
| smilies_init                    | 5        | 1             |
| wp_cron                         | 10       | 1             |
| _show_post_preview              | 10       | 1             |
| rest_api_init                   | 10       | 1             |
| kses_init                       | 10       | 1             |
| wp_schedule_update_checks       | 10       | 1             |
| ms_subdomain_constants          | 10       | 1             |
| maybe_add_existing_user_to_blog | 10       | 1             |
| check_theme_switched            | 99       | 1             |
+---------------------------------+----------+---------------+

Want to use this command locally? Update to the nightly, and then run wp package install danielbachhuber/wp-hook-command.

What’s next

Well… I’ve spent a ton of hours over the last month on the WP REST API. 67.03 hours of 83 budgeted, to be precise. Given there doesn’t yet seem to be an end in sight, I may reallocate ~30 hours or so out of the WP-CLI budget for continued involvement with the WP REST API. But, I do need to slow down the pace of my involvement a bit, because it’s not sustainable.

On the wp-rest-cli front, the product problems at the top of my mind are authentication and aliases.

Instead of:

wp --http=demo.wp-api.org --user=daniel:daniel rest tag create

I’d much prefer:

wp @wpapi tag create

In the example preceeding, @wpapi is an alias for both the target and authentication.

In this hypothetical universe, aliases would also be injected into the WP-CLI runtime:

$ wp @wpapi
usage: wp @wpapi attachment <command>
   or: wp @wpapi category <command>
   or: wp @wpapi comment <command>
   or: wp @wpapi meta <command>
   or: wp @wpapi page <command>
   or: wp @wpapi pages-revision <command>
   or: wp @wpapi post <command>
   or: wp @wpapi posts-revision <command>
   or: wp @wpapi status <command>
   or: wp @wpapi tag <command>
   or: wp @wpapi taxonomy <command>
   or: wp @wpapi type <command>
   or: wp @wpapi user <command>

There’s a bit of thinking to do, and code to write, to get from here to there, though.

Feeling inspired? I want to hear from you! Particularly if you’ve written custom endpoints I can test against. Please open a Github issue with questions, feedback, and violent dissent, or email me directly.

RESTful WP-CLI – The journey begins

And so the journey begins. As with most journeys, I have a mixture of emotions: excitement, anticipation, trepidation, and eagerness. Although the destination may be far away, I know I can get there as long as I consistently take steps in the right direction.

Today marks the formal kickoff of my Kickstarter project, “A more RESTFul WP-CLI“. To celebrate the occasion, I’ve launched a project page to capture high-level goals and document my progress along the journey. I’ll keep it updated as I write blog posts every couple or few weeks. Consider these blog posts both a development log and an invitation to participate — I look forward to your comments, issues and pull requests.


For the past month or so, the question at the top of my mind has been: what does it mean to “unlock the potential of the WP REST APIREST API The REST API is an acronym for the RESTful Application Program Interface (API) that uses HTTP requests to GET, PUT, POST and DELETE data. It is how the front end of an application (think “phone app” or “website”) can communicate with the data store (think “database” or “file system”) https://developer.wordpress.org/rest-api/. at the command line”? Or, even more broadly, why do this project?

These are big questions, and I consider myself fortunate to be able to explore them over the next six months or so. Here’s how I’ve unpacked them so far, in a series of loosely connected ideas:

  • WP-CLIWP-CLI WP-CLI is the Command Line Interface for WordPress, used to do administrative and development tasks in a programmatic way. The project page is http://wp-cli.org/ https://make.wordpress.org/cli/’s goal is to be, quantitatively, the fastest interface for developers to manage WordPress. For anything you want to do with WordPress, using WP-CLI should save you multitudes of time over doing it some other way.
  • WP-CLI and WP REST API both offer CRUD interfaces to WordPress resources. wp post list is more or less GET /wp/v2/posts. But, wp widget list doesn’t yet have an equivalent in WP REST API. We still have a ton of work to do.
  • Building the WP REST API has been, and will continue to be, an exercise of modeling how WordPress works to a consistent (RESTful) interface. Furthermore, this model is declared in a common language for clients to interpret.
  • At some point in the future, WP-CLI will be able to ditch a substantial amount of its internals when it can use the WP REST API as its interface to WordPress. WP-CLI can continue to serve as the fastest way for developers to manage WordPress, offering higher-level metaMeta Meta is a term that refers to the inside workings of a group. For us, this is the team that works on internal WordPress sites like WordCamp Central and Make WordPress. operations like generate, (push|pull), and clone in addition to being a seamless command line interface to WordPress internals.
  • As WordPress developers write new endpoints for the WP REST API, it will be quite powerful to have those endpoints instantly accessible through the command line, and as accessible as coreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress. resources. For instance, where WP-CLI currently has the wp post * commands, WP-CLI requires Easy Digital Downloads to produce its own wp edd * commands.
  • It appears to be supremely possible to deliver this project as a series of improvements to WP-CLI, shipped over one or more versions in the next couple of quarters.

Lots of threads to pull on.


I’m starting development by working towards making wp tag list work interchangably with local and remote sites. Doing so already raises a few issues:

  • WP-CLI needs to be easier to register commands on the fly. In my prototype, I had to eval() a dynamically generated class. It would be much nicer to be able to register an arbitrary function, closure, or method as a WP-CLI command.
  • When we register REST endpoints to WP-CLI on the fly, there’s the potential for them to conflict with existing commands. Furthermore, the endpoints will vary from site to site. Ideally, the commands you see should represent the commands available on the target site. I think site aliases may offer us a backwards-compatible implementation; for instance, specifying an alias like wp @prod would only expose commands available on production.
  • Remote calls will need authentication. Ideally, it should be possible to authenticate once through a supported protocol (basic, oAuth1, APIAPI An API or Application Programming Interface is a software intermediary that allows programs to interact with each other and share data in limited, clearly defined ways. key, etc.), and store these authentication details somewhere on the file server. This is potential rationale for a config management command. If you aren’t blocking web requests to wp-cli.yml and wp-cli.local.yml already, you should be.

This project is made possible thanks to the backing of many generous organizations and individuals. Thank you again for supporting me on this journey.

Platinum

Pressed offers white-label, fully managed, WordPress hosting, built on Amazon’s cloud infrastructure. Launch your own managed WordPress hosting brand and let us handle all the maintenance, updates, customer support and billing while building a new recurring revenue stream for your business.

Gold

Chris Lema is the CTO & Chief Strategist at Crowd Favorite. He’s also a WordPress evangelist, public speaker & advisor to product companies. Human Made is a leading WordPress Development, Hosting and Consultancy Firm with a global team covering Europe, The USA, and Asia/Australia.
Pagely® is the World’s first and most scalable WordPress Hosting platform: We help the biggest brands scale and secure WordPress. Pantheon is a website management platform used to build, launch, and run awesome Drupal & WordPress websites.

Silver

Individual

Aaron Jorbin, Aki Björklund, Anu Gupta, Bjørn Ensover Johansen, Brian Krogsgard, Bronson Quick, Chuck Reynolds, Corey McKrill, Daniel Hüsken, Dave McDonald, Dave Wardle, Eli Silverman, Felix Arntz, Howard Jacobson, Japh Thomson, Jason Resnick, Jeremy Felt, Justin Kopepasah, Kailey Lampert, Kevin Cristiano, Max Cutler, Mike Little, Mike Waggoner, Nate Wright, Pippin Williamson, Quasel, Ralf Hortt, Richard Aber, Richard Wiggins, Ryan Duff, Scott Kingsley Clark, Shinichi Nishikawa, Sven Hofmann, Takayuki Miyauchi, Tom McFarlin, rtCamp


Let’s go!

Version 0.22.0 released

Happy 2016! I thought you might enjoy a new WP-CLIWP-CLI WP-CLI is the Command Line Interface for WordPress, used to do administrative and development tasks in a programmatic way. The project page is http://wp-cli.org/ https://make.wordpress.org/cli/ release before I dive into the RESTful CLICLI Command Line Interface. Terminal (Bash) in Mac, Command Prompt in Windows, or WP-CLI for WordPress. project.

Use wp cli update to install v0.22.0, representing 137 resolved issues and pull requests. Here’s what’s new.

search-replace for love and profit

Last month, Pantheon generously sponsored 15 hours of my time to address some of the long-standing bugs in the backlog, and make a few substantial enhancements too.

Let’s start with the good stuff:

  • Performance boost! Instead of running a MYSQLMySQL MySQL is a relational database management system. A database is a structured collection of data where content, configuration and other options are stored. https://www.mysql.com/. LIKE statement every 1000 rows, WP-CLI now just runs it once [#2304]. On a post metaMeta Meta is a term that refers to the inside workings of a group. For us, this is the team that works on internal WordPress sites like WordCamp Central and Make WordPress. table of ~3.5 million rows where 75,610 rows were affected, this change improved execution time from 734.926s to 225.509s (3.3x faster).
  • Use the --export=<filename> argument to create a SQL file of your transformed data, instead of making updates to the database [#2254]. This is a helpful feature when you want to prepare a database for a new environment without having to import and then run search-replace.
  • Wildcards can be used in table names [#2233]. search-replace against just meta tables with wp search-replace <old-string> <new-string> '*meta*'. Note: the pattern needs to be quoted, as * is a special character in Bash.

I also landed a number of search-replace bug fixes and minor enhancements:

  • Recurses objects by default when replacing inside of serialized data [#2222]. Among other things, this ensures theme mods are transformed as expected. You can disable the behavior with --no-recurse-objects. But, if you do disable the behavior, I’d like to hear from you. I think this is an unnecessary option we could remove at a later date.
  • Properly escapes quotes used in search or replace strings [#2230].
  • Lets users know to flush their persistent object cache after a search-replace procedure is performed [#2236].
  • Bails early when the replacement string is the same as the search string [#2235].
  • Indicates execution time when running search/replace with --verbose [#2242].
  • Prevents unnecessary calls to $wpdb->update() when there are no replacements to be made [#2245].
  • Drops unnecessary REGEXP query when in regex mode [#2305].

Changes to supported versions

WP-CLI’s minimum supported WordPress version is now 3.7 [#2261].

We also officially support PHPPHP PHP (recursive acronym for PHP: Hypertext Preprocessor) is a widely-used open source general-purpose scripting language that is especially suited for web development and can be embedded into HTML. http://php.net/manual/en/intro-whatis.php. 7 [#2330].

Everything else in v0.22.0

Improvements to wp scaffold (plugin|plugin-tests):

  • Makes Travis less noisy by only sending email notifications on the initial build failure for a branch [#2194].
  • PluginPlugin A plugin is a piece of software containing a group of functions that can be added to a WordPress website. They can extend functionality or add new features to your WordPress websites. WordPress plugins are written in the PHP programming language and integrate seamlessly with WordPress. These can be free in the WordPress.org Plugin Directory https://wordpress.org/plugins/ or can be cost-based plugin from a third-party headerHeader The header of your site is typically the first thing people will experience. The masthead or header art located across the top of your page is part of the look and feel of your website. It can influence a visitor’s opinion about your content and you/ your organization’s brand. It may also look different on different screen sizes. follows WordPress’ PHPDoc standards [#2197].
  • Adds .dist extension to PHPUnit config file to permit overriding with a local config file [#2247]
  • Parses readme.txt to find WordPress versions to use as Travis tested versions [#2255].
  • Includes a default .gitignore [#2297].

New flags for existing commands:

  • wp core update --minor to only perform minor updates [#2256].
  • wp (post|comment|user) meta delete <id> --all to delete all meta values on a given object [#2265].
  • wp core update-db --dry-run to see whether a database needs an upgrade [#2293].
  • wp media regenerate --only-missing for faster performance on sites with lots of images where only a small number are missing sizes [#2292].
  • wp cron event run --all to execute all registered cron events [#2323].
  • wp site empty --uploads to empty a site and delete its uploads directory too [#2339].
  • wp core install --skip-email to install without email notifications [#2345].
  • wp transient (get|set|delete) --network to manage site transients [#2351].

Framework enhancements:

  • Introduces wp_version_compare() when comparing WordPress versions [#2237]. SVNSVN Apache Subversion (often abbreviated SVN, after its command name svn) is a software versioning and revision control system. Software developers use Subversion to maintain current and historical versions of files such as source code, web pages, and documentation. Its goal is to be a mostly compatible successor to the widely used Concurrent Versions System (CVS). WordPress core and the wordpress.org released code are all centrally managed through SVN. https://subversion.apache.org/. and GitGit Git is a free and open source distributed version control system designed to handle everything from small to very large projects with speed and efficiency. Git is easy to learn and has a tiny footprint with lightning fast performance. Most modern plugin and theme development is being done with this version control system. https://git-scm.com/. tags include -src in $wp_version, which
    version_compare() doesn’t like.
  • Defers to the $PAGER environment variable when set [#2264].
  • Introduces a composer.lock file to the project, to fix dependencies to specific hashes [#2280].
  • Magically globalizes any new variables defined in wp-config.php, as they’re expected to be global [#2318].
  • If a --require=<file> is missing, specifies the context of where the missing file is referenced for easier debugging [#2336].
  • Use mustangostang/spyc instead of bundling our own copy [#2350]. The Spyc class is still available in the global namespace.
  • Introduces WP_CLIUtilsget_temp_dir() for safer temp directories [#2353].

Improvements to other commands:

  • Includes not_found label when scaffolding a custom taxonomyTaxonomy A taxonomy is a way to group things together. In WordPress, some common taxonomies are category, link, tag, or post format. https://codex.wordpress.org/Taxonomies#Default_Taxonomies. [#2196].
  • Permits installing remote plugin files without .zip in filename [#2193].
  • Warns when adding a user as a super admin when the user is already a super admin [#2202].
  • Uses WP_CLI::log() instead of WP_CLI::line() in wp import, so --quiet flag is respected [#2234].
  • Adds support to wp db tables for wildcard tables (e.g. *meta*), --all-tables-with-prefix, and --format=csv [#2250].
  • Improves error message when installing a plugin or theme and the resource isn’t found [#2253,#2267].
  • Supports custom wp export filename formats with --filename_format=<format> [#2230]
  • Assumes db errors during wp install to be installation failures, and reports accordingly [#2337].
  • Exposes plugin header details at runtime for wp scaffold plugin [#2338].
  • Includes ci/behat-tags.php in wp scaffold package-tests [#2342].

Bug fixes across the board:

  • Lets help run early when WP is detected, but not installed (e.g. wp core config --help) [#2190]. Bug was introduced in v0.20.0.
  • When scaffolding a child themeChild theme A Child Theme is a customized theme based upon a Parent Theme. It’s considered best practice to create a child theme if you want to modify the CSS of your theme. https://developer.wordpress.org/themes/advanced-topics/child-themes/., creates a safe version of the parent theme slug for the child enqueue function [#2203]. Previously, if the parent slug included dashes, an invalid enqueue function would be scaffolded.
  • Suppresses error notices when looking for wp-config.php and PHP’s open_basedir is in effect [#2211].
  • Fixes error notice in WP_CLILoggersQuiet [#2210].
  • Fixes all_items label in custom post typeCustom Post Type WordPress can hold and display many different types of content. A single item of such a content is generally called a post, although post is also a specific post type. Custom Post Types gives your site the ability to have templated posts, to simplify the concept. scaffolding [#2213].
  • Ensures install-package-tests.sh actually downloads the nightly WP-CLI Phar build, and not a redirect [#2214].
  • Sets the upload_space_check_disabled to 1 when installing multisiteMultisite Multisite is a WordPress feature which allows users to create a network of sites on a single WordPress installation. Available since WordPress version 3.0, Multisite is a continuation of WPMU or WordPress Multiuser project. WordPress MultiUser project was discontinued and its features were included into WordPress core.https://codex.wordpress.org/Create_A_Network. [#2238]. This mirrors coreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress.’s behavior on new installs.
  • Provides a more helpful message when image regeneration fails [#2239].
  • Properly updates menu sub-item parent when parent is deleted [#2262].
  • Stops prefixing rewrite rules with index.php when using wp rewrite structure [#2279].
  • Fixes typo in wp transient set synopsis [#2282].
  • Restores wp core verify-checksums for non-US English locales [#2287]. Bug was introduced in v0.21.0.
  • Switches to the readline library, when available, for better support of arrow keys using --prompt [#2325].
  • WP_CLIFormatter properly checks for null values on objects [#2322].
  • In wp media import, uses host instead of scheme to determine whether a file is remote or local, for Windows compatibility [#2324].
  • Ensures updating a plugin with an invalid --version=<version> specified doesn’t delete the plugin [#2346].

Contributors to this release: 2ndkauboy, coreyworrell, danielbachhuber, davidleach, duncanjbrown, ernilambar, fjarrett, gilbitron, greg-1-anderson, iandunn, jjeaton, modelm, rodrigoprimo, ryanshoover, stevector, szepeviktor, tristanpenman, x1024

You can browse the full list of resolved issues on GithubGitHub GitHub is a website that offers online implementation of git repositories that can easily be shared, copied and modified by other developers. Public repositories are free to host, private repositories require a paid subscription. GitHub introduced the concept of the ‘pull request’ where code changes done in branches by contributors can be reviewed and discussed before being merged be the repository owner. https://github.com/.

What the survey said, 2015 edition

Many thanks to the 206 (!!!) people who took our second user survey. We appreciate your time in helping us to understand how WP-CLIWP-CLI WP-CLI is the Command Line Interface for WordPress, used to do administrative and development tasks in a programmatic way. The project page is http://wp-cli.org/ https://make.wordpress.org/cli/ is being adopted by the community.

Curious as to how the numbers have changed? Take a look at the summary of the first user survey from April 2014.

By the numbers

85% of respondents use WP-CLI regularly

Of this 85%, 48% use WP-CLI multiple times per day. 37% use it a couple or few times per week. Only 15% of respondents use WP-CLI infrequently or rarely.

94% of respondents use WP-CLI interactively at the command line, 66% have incorporated it into bash scripts, and 23% are using WP-CLI with Puppet, Chef, or another provisioning system. Other tools mentioned include: Capistrano, Codeception, EasyEngine, Fabric, Grunt, and SaltStack.

Most users keep WP-CLI up to date

Over 70% of respondents keep WP-CLI up to date. Here’s how the numbers break down:

  • 13% run the latest alpha. You can too with wp cli update --nightly.
  • 58% use the latest stable release (v0.20.x at time of survey).
  • 24% are using one or two versions below the latest stable. Only 5% use a very old version of WP-CLI.

Good news — if you’re writing custom commands, you can reasonably assume it’s safe to use the latest features in WP-CLI.

WP-CLI is used for an increasing variety of tasks

Like last year, the survey included “What do you use WP-CLI for?” as a free-form field. To produce a statistical summary, I tagged each response with keywords. Of 170 interpreted values:

  • 38% (65) use WP-CLI for updating WordPress coreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress., themes, or plugins.
  • 22% (38) transform their database in some way using wp search-replace.
  • 17% (29) rely upon WP-CLI when performing migrations.
  • 15% (26) make use of WP-CLI’s database management features: wp db export, wp db import and wp db optimize.
  • 11% (18) depend upon WP-CLI in provisioning scripts.
  • 10% (17) scaffold new themes and plugins with wp scaffold.
  • 9% (16) write custom commands for their own needs.
  • 6% (10) generate mock posts, users and comments.
  • 3% (5) are hearty souls who use wp shell, wp eval, and wp eval-file for debugging and quick scripts.

In no particular order, here are some third-party commands and workflows mentioned: Jetpack CLI, WP Parser, ElasticPress, WP Migrate DB Pro, WP CFM, BackWPUp, wp-cli-ssh, wp-instant-setup, project-template-wordpress, and provisioning a new WordPress.org Theme Review environment.

One person said they use WP-CLI to make coffee. On behalf of everyone, I look forward to the day I can install this command from the package directory.

Feature requests

Feel like contributing to WP-CLI over the holidays? Here’s a grab bag of enhancements you could work on:

  • Better documentation (internals, extending, common workflows).
  • One single uber-command to install WordPress, including downloading files, creating the MySQLMySQL MySQL is a relational database management system. A database is a structured collection of data where content, configuration and other options are stored. https://www.mysql.com/. database, setting up wp-config.php, and populating database tables.
  • Suggest correct syntax when a command is incorrectly entered (e.g. git staus).
  • Improved support for managing multiple networks: wp network list, wp network create.
  • Install plugins favorited by a given WordPress.orgWordPress.org The community site where WordPress code is created and shared by the users. This is where you can download the source code for WordPress core, plugins and themes as well as the central location for community conversations and organization. https://wordpress.org/ user.
  • Verify theme and pluginPlugin A plugin is a piece of software containing a group of functions that can be added to a WordPress website. They can extend functionality or add new features to your WordPress websites. WordPress plugins are written in the PHP programming language and integrate seamlessly with WordPress. These can be free in the WordPress.org Plugin Directory https://wordpress.org/plugins/ or can be cost-based plugin from a third-party checksums.
  • Report when extra files are present in wp-admin or wp-includes (e.g. checksums of directories)
  • Save a template of a WordPress setup (similar to grunt {my-task}).
  • Disable all plugins except for a specific one. Or, load WP-CLI with only a given plugin active.
  • Install WordPress nightly builds without needing the betaBeta A pre-release of software that is given out to a large group of users to trial under real conditions. Beta versions have gone through alpha testing in-house and are generally fairly close in look, feel and function to the final product; however, design changes often occur as part of the process. plugin.
  • Provide a command to execute WP-Cron without requiring a HTTPHTTP HTTP is an acronym for Hyper Text Transfer Protocol. HTTP is the underlying protocol used by the World Wide Web and this protocol defines how messages are formatted and transmitted, and what actions Web servers and browsers should take in response to various commands. request.
  • Define custom scaffolds for themes and plugins.
  • Generate posts, pages from a sitemap CSV.
  • Magically migrate data between environments (production -> staging).
  • Add option to exclude specific tables in wp search-replace.
  • Provide a way to log in with a one-time link.

If you can’t find an existing Github issue, please create one and we can begin discussing implementation.

Thanks again to everyone who took the time to complete our user survey! May WP-CLI continue to be a shining light for your WordPress development needs.