Skip to content

Add wp post convert-to-blocks for server-side block conversion - #655

Draft
swissspidy wants to merge 1 commit into
mainfrom
feature/post-convert-to-blocks
Draft

swissspidy wants to merge 1 commit into
mainfrom
feature/post-convert-to-blocks

Conversation

@swissspidy

Copy link
Copy Markdown
Member

Adds a wp post convert-to-blocks <id>... [--dry-run] subcommand that converts classic (non-block) post content to block markup.

Depends on WordPress/gutenberg#82013. The command calls gutenberg_html_to_block_markup(), which only exists while a Gutenberg build from that PR (branch try/13163-php-block-conversion) is active. Until WordPress core ships an equivalent, the command checks function_exists() and fails with Error: Server-side block conversion is not available. Activate the Gutenberg plugin from https://github.com/WordPress/gutenberg/pull/82013. on any other site. That is why this PR is a draft.

What the command does

For each ID, in order:

  1. Missing post: warning, counted as a failure, continues.
  2. Empty post_content: warning Post <id> has no content to convert., counted as skipped.
  3. Content that already contains blocks: warning Post <id> already contains blocks., counted as skipped.
  4. Otherwise the content is converted with gutenberg_html_to_block_markup(). With --dry-run it logs Would convert post <id>. and saves nothing. Without it, the markup is saved with wp_update_post(); a WP_Error is a warning and a failure, otherwise Converted post <id>. is logged.

The run ends with the usual batch summary from report_batch_operation_results() (Success: Converted 3 of 4 posts (1 skipped)., or Error: Only converted ... with a non-zero exit when any post failed). Dry runs use the same shape with Would convert ... wording, following the wp term prune --dry-run precedent in this repository.

The docblock notes that the conversion itself does not sanitise: saving goes through the usual kses filtering for the current user, so a run without --user is filtered as an untrusted author would be, and --user=<administrator> keeps markup that needs unfiltered_html.

Changes

  • src/Post_Command.php: new convert_to_blocks() subcommand (docblock, get_flag_value, the existing post fetcher, Block_Processor_Helper::has_blocks() and report_batch_operation_results()).
  • composer.json: registers post convert-to-blocks in extra.commands.
  • README.md: regenerated with wp scaffold package-readme (additions only).
  • features/post-convert-to-blocks.feature: new feature file.

Tests

Runs in CI today: the first scenario runs on a plain Given a WP install and asserts the "not available" error on STDERR with exit code 1.

Needs the Gutenberg build from PR 82013 (tagged @broken, so CI skips them): a real conversion of <h2>Title</h2><p>Text</p> into <!-- wp:heading --> / <!-- wp:paragraph --> markup, --dry-run leaving the content untouched, skipping posts that already contain blocks, skipping empty content, and a missing post reported as a failure with exit code 1. The feature file's header comment explains how to run them locally: build the plugin ZIP from that branch, remove the @broken tags, and add And I run \wp plugin install /path/to/gutenberg.zip --activate`afterGiven a WP install`.

Validation

  • composer lint, composer phpcs and composer lint-gherkin: clean.
  • composer phpstan: no findings in the changed files. The two pre-existing ignore.unmatchedIdentifier reports in src/User_Session_Command.php also appear on main in my environment and are unrelated.
  • Behat: no MySQL was available, so I ran the suite with WP_CLI_TEST_DBTYPE=sqlite against WordPress 7.1. The CI-safe scenario passes.
  • The five @broken scenarios were also exercised locally against the PHP from PR 82013 (its lib/experimental/block-transforms/ and lib/compat/wordpress-7.2/block-type-transforms.php loaded through an mu-plugin, with the transforms from the PR's block.json files applied to the registered core block types, since a JS build was not possible in my environment). All five pass that way; the "not available" scenario correctly fails under that harness because the function then exists.

🤖 Generated with Claude Code

https://claude.ai/code/session_01ECHX5L8q3jXJTxQqX94rH7


Generated by Claude Code

Adds a `post convert-to-blocks <id>... [--dry-run]` subcommand that turns
classic post content into block markup using the server-side conversion
from WordPress/gutenberg#82013 (`gutenberg_html_to_block_markup()`).

Posts that cannot be found count as failures, posts without content or
that already contain blocks are skipped, and the run ends with the usual
batch summary. Without that Gutenberg build active, the command fails
with a clear error pointing at the pull request.

Only the "not available" scenario runs in CI; the scenarios that need
the Gutenberg build are tagged @broken with instructions for running
them locally.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ECHX5L8q3jXJTxQqX94rH7
@coderabbitai

coderabbitai Bot commented Sep 14, 2026

Copy link
Copy Markdown

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added the command:post Related to 'post' command label Sep 14, 2026
@codecov

codecov Bot commented Sep 14, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 6.25000% with 45 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/Post_Command.php 6.25% 45 Missing ⚠️

📢 Thoughts on this report? Let us know!

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants