Skip to content

Conversation

@schlessera
Copy link
Member

Add block-related post commands

This PR adds comprehensive block manipulation capabilities to WP-CLI through a new post block command group and two new wp post commands.

New Commands

post block <subcommand> - A new command group for managing blocks within post content:

  • get - Retrieve a single block by index
  • list - List all blocks in a post with filtering options
  • parse - Parse and output the full block structure
  • render - Render blocks to HTML
  • insert - Insert a new block at a specific position
  • update - Update block attributes or content
  • remove - Remove a block by index
  • replace - Replace a block with a different block type
  • move - Move a block to a different position
  • clone - Clone a block to the same or different post
  • extract - Extract blocks to a separate file
  • import - Import blocks from a file
  • export - Export blocks to JSON/YAML
  • count - Count blocks by type

post has-blocks - Check if a post contains any blocks
post has-block <block-name> - Check if a post contains a specific block type

Use Cases

  • Inspect and debug block content in posts
  • Programmatically modify block-based content
  • Migrate or transform block content between posts
  • Script block operations in deployment/maintenance workflows
  • Validate block usage across a site

@schlessera schlessera requested a review from a team as a code owner December 10, 2025 03:39
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @schlessera, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly expands WP-CLI's functionality by introducing a comprehensive suite of commands for interacting with Gutenberg blocks in post content. These new tools empower developers and administrators to programmatically inspect, modify, and manage block-based content, streamlining tasks such as content migration, debugging, and automated content transformations. The additions provide granular control over individual blocks, their attributes, and their placement within posts.

Highlights

  • New post block Command Group: A comprehensive new command group has been added, offering extensive capabilities for managing Gutenberg blocks. This includes subcommands like get, list, parse, render, insert, update, remove, replace, move, clone, extract, import, export, and count.
  • New post has-blocks Command: A new command post has-blocks allows users to quickly check if a given post contains any Gutenberg blocks.
  • New post has-block <block-name> Command: A new command post has-block <block-name> enables checking for the presence of a specific block type within a post.
  • WordPress Version Requirement: All new post block commands are conditional and require WordPress version 5.0 or greater to function, ensuring compatibility with the block editor.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@schlessera schlessera added command:post Related to 'post' command command:post-block Related to 'post block' command labels Dec 10, 2025
@schlessera schlessera added this to the 2.9.0 milestone Dec 10, 2025
Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a comprehensive and powerful set of commands for managing post blocks via WP-CLI. The code is well-structured, and the feature tests provide excellent coverage. I've identified a few issues, primarily related to edge cases and consistency in how block indices are handled across different commands. Specifically, the import command fails on empty block arrays, and the remove command's index handling is inconsistent with other commands and misses some error validation required by the tests. Addressing these will improve the robustness and predictability of the new commands. I've also included a minor suggestion for composer.json to improve maintainability.

@swissspidy
Copy link
Member

swissspidy commented Dec 10, 2025

I like the idea of wp post block for dealing with blocks within posts, in addition to https://github.com/wp-cli/block-command


#555 has a some other things that we should also cover here:

  • Adding block_version to wp post get

update - Update block attributes or content

How does this work when block attributes are actually mapped to HTML attributes?


We should leverage https://make.wordpress.org/core/2025/11/19/introducing-the-streaming-block-parser-in-wordpress-6-9/ if available

@swissspidy swissspidy linked an issue Dec 10, 2025 that may be closed by this pull request
@codecov
Copy link

codecov bot commented Dec 11, 2025

@swissspidy
Copy link
Member

Let's add a codecov.yml config file to improve the coverage report:

ignore:
  - "src/Compat"

@schlessera
Copy link
Member Author

schlessera commented Dec 11, 2025

How does this work when block attributes are actually mapped to HTML attributes?

I'm adding an implementation for this now that will work in the following way:

  • The code that runs the update includes the following filter:
      /**
       * Filters a block after attribute updates to sync HTML with attributes.
       *
       * Allows custom handlers to update block HTML when attributes change.
       *
       * @param array  $block      The block structure with updated attrs.
       * @param array  $new_attrs  The newly applied attributes.
       * @param string $block_name The block type name (e.g., 'core/button').
       */
      return apply_filters( 'wp_cli_post_block_update_html', $block, $new_attrs, $block_name );

You can then include custom logic with WP-CLI when you are running an update operation:

wp --require=./my-block-handlers.php post block update 123 0 --attrs='{"url":"https://new.url"}'
// In a file loaded via: wp --require=./my-handlers.php post block update
  add_filter( 'wp_cli_post_block_update_html', function( $block, $new_attrs,
  $block_name ) {
      if ( 'core/button' === $block_name && isset( $new_attrs['url'] ) ) {
          $block['innerHTML'] = preg_replace(
              '/href="[^"]*"/',
              'href="' . esc_url( $new_attrs['url'] ) . '"',
              $block['innerHTML']
          );
          $block['innerContent'] = [ $block['innerHTML'] ];
      }
      return $block;
  }, 10, 3 );

What's more, we can then include a few default handlers as shipped filters for this for the most common use cases:

  // Built-in handlers registered as filters
  add_filter( 'wp_cli_post_block_update_html', [ $this, 'sync_heading_level' ], 10, 3 );
  add_filter( 'wp_cli_post_block_update_html', [ $this, 'sync_list_type' ], 10, 3 );

Also, this then allows the ecosystem to pick this up. Handlers like that can be in a theme's functions.php or in custom plugins, and some plugins can even ship with handlers for the blocks they provide.

@swissspidy
Copy link
Member

Soubds good. I suppose that's the best we can do until core provides a solution for this.

@swissspidy swissspidy merged commit c23487e into main Dec 12, 2025
53 of 54 checks passed
@swissspidy swissspidy deleted the feature/block-content-commands branch December 12, 2025 16:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

command:post Related to 'post' command command:post-block Related to 'post block' command

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Initial set of block-related commands

3 participants