Skip to content

Docs: Improve wording and accuracy of block asset registration docblocks in blocks.php - #11851

Closed
deepakrohillas wants to merge 107 commits into
WordPress:trunkfrom
deepakrohillas:typo_wp_includes_blocks_dot_php
Closed

deepakrohillas wants to merge 107 commits into
WordPress:trunkfrom
deepakrohillas:typo_wp_includes_blocks_dot_php

Conversation

@deepakrohillas

@deepakrohillas deepakrohillas commented May 18, 2026 •

Copy link
Copy Markdown

Trac ticket: https://core.trac.wordpress.org/ticket/65259

Reworks the docblocks for the three block asset registration functions in src/wp-includes/blocks.php, corrects two descriptions that no longer matched the code, and fixes the before hand typo in build_query_vars_from_query_block() that this ticket was originally filed for.

Wording

Per the inline documentation standards, the summary belongs on its own line separated from the description by a blank line, and the description should not open with "It". Applied to register_block_script_module_id(), register_block_script_handle(), and register_block_style_handle().

Missing articles are added in the same three descriptions: "a path to file" becomes "a path to a file", and "returns unprocessed x handle" becomes "returns the unprocessed x handle".

Accuracy

Two of the descriptions no longer described what the functions do:

  • register_block_script_handle() said the script is registered "under an automatically generated handle name". Since 6.5.0 the handle is taken from the asset file when it provides one — $script_asset['handle'] ?? generate_block_asset_handle( … ) — which the function's own @since 6.5.0 line already documents. Automatic generation is now described as the fallback it is.
  • register_block_style_handle() said it "returns unprocessed style handle otherwise". That does not hold for the first style of a core block, which is registered from the bundled style.min.css / editor.min.css even when a plain handle was given. Core blocks also return false outright when given a path rather than a handle.

register_block_script_module_id() was checked against its implementation and needed no accuracy change — it always generates the module ID.

Typo

In build_query_vars_from_query_block(), "before hand" becomes "beforehand".


🤖 This PR title and description were rewritten by Claude Code (Claude Opus 5) to reflect the changes as they now stand. The original is preserved below.

Original title and description

Title: Docs: Fix inline comment typos in build_query_vars_from_query_block() in blocks.php

https://core.trac.wordpress.org/ticket/65259
In src/wp-includes/blocks.php, the inline comment inside build_query_vars_from_query_block() contains two errors: (1) "before hand" should be "beforehand" (compound adverb), and It detects when a path to file was provided from this "It" should be removed.

WordPress inline documentation standards, especially for DocBlocks.
In WordPress coding standards:
The description section should continue naturally and should not start with “It”.

… add_action()

`error.message` LIKE 'Uncaught exception 'Error' with message 'Call to undefined function add_action()' in /var/www/wp-content/plugins/hello.php:69%' AND `error.class` = 'Error' AND transactionUiName = '/wp-content/plugins/hello.php'

'request_uri': '/wp-content/plugins/hello.php'
…dolly_uncaught_exception

Fix Uncaught exception Error with message 'Call to undefined function…
Plugin URI http to https change
Comment thread src/wp-includes/blocks.php Outdated
westonruter and others added 3 commits August 1, 2026 09:26
Relax the metadata version key from non-falsy-string to non-empty-string,
since a block.json version of "0" is legal and would be a falsy string.
The value only ever flows to a $ver parameter that accepts any string.

Add the non-falsy-string|false return to register_block_style_handle(),
which the other two registration functions already carry. Every return
path is false, a handle taken from the metadata, or one generated by
generate_block_asset_handle(), so PHPStan verifies it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The narrowed non-falsy-string was added as a second plain return tag,
leaving the function with two of them.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: Aki Hamano <54422211+t-hamano@users.noreply.github.com>
@westonruter

Copy link
Copy Markdown
Member

Note: Ignore the changes I've made outside of src/wp-includes/blocks.php. I'll commit those separately. As part of reviewing the docs, I've been improving the documented types for the touched functions.

westonruter and others added 11 commits August 1, 2026 19:20
…id()

The block.json schema does not set `additionalProperties: false` on the
`supports.interactivity` object, so a block may legitimately declare keys
beyond `interactive` and `clientNavigation`. Sealing the shape asserted
otherwise.

This matches `supports` itself, which the schema explicitly marks as
`additionalProperties: true` and which was already unsealed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…core blocks

The description had the two cases inverted. When
wp_should_load_separate_core_block_assets() returns true, the style is
registered from the block's own stylesheet, resolved from the block
directory as dirname( $metadata['file'] ) . '/style.min.css'. The single
combined 'wp-block-library' stylesheet is what serves core block styles in
the opposite case, where the function returns false and registers nothing.

This matches wp_should_load_separate_core_block_assets() itself, which
documents that a true return makes core blocks use their own separate
stylesheets, as well as the inline comment contrasting individual styles
with the bundled version.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The `file` key is not a block.json field but is injected by
register_block_type_from_metadata(), which assigns null whenever the block
has no metadata file:

    $metadata['file'] = $metadata_file_exists ? wp_normalize_path( realpath( $metadata_file ) ) : null;

That branch is reachable from an ordinary call, because the guard above it
accepts a name supplied through `$args` when the metadata itself has none.
Registering a folder without a block.json then reaches dirname( null ) in all
three functions, which is deprecated as of PHP 8.1:

    Deprecated: dirname(): Passing null to parameter #1 ($path) of type string
    is deprecated in blocks.php on line 187

The functions were already inconsistent about this: register_block_style_handle()
guards the key with isset(), then dereferences it unguarded 23 lines later.

Declaring the key nullable surfaces the three dirname() call sites rather than
asserting they cannot happen. Fixing them is left for a separate change, since
the same call path also leaves `name` undefined.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…hapes

The guard in register_block_type_from_metadata() only requires that one of
the two possible sources supplies a name:

    if ( ! is_array( $metadata ) || ( empty( $metadata['name'] ) && empty( $args['name'] ) ) ) {

So a block named through `$args` alone gets past it with no name in the
metadata itself. The two are reconciled, but not until after the three asset
functions have already run:

    $metadata['name'] = ! empty( $settings['name'] ) ? $settings['name'] : $metadata['name'];

The asset loops copy `$args`-supplied values into `$metadata` for the asset
fields only, never for the name, so all three functions can be reached with
the key absent:

    Warning: Undefined array key "name" in blocks.php on line 189

The consequence is not only a warning. generate_block_asset_handle() then
produces '-script', '-style' and '-view-script-module', which every nameless
block shares, so the second such block matches the wp_script_is() check and
silently adopts the first one's registration.

This describes the behavior as it currently stands. Reordering the
reconciliation would make the key genuinely required, but that changes which
name the generated handles reflect when the block_type_metadata_settings
filter renames a block, so it is left for a separate change.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The block.json schema constrains only `name`, whose pattern
`^[a-z][a-z0-9-]*/[a-z][a-z0-9-]*$` rules out a falsy value. The seven asset
fields are `oneOf` a string or an array of strings, and `version` and
`textdomain` are plain strings, none of them carrying a pattern or a
minLength. Declaring them as non-falsy claimed a guarantee the schema does
not make.

An empty value is also not hypothetical. Published plugins ship it at the top
level of block.json, for example:

    "textdomain": "omnisend-checkout-block",
    "editorStyle": ""

Core ignores those silently, since register_block_type_from_metadata() only
calls the three functions when the field passes ! empty(). The narrowing was
therefore load-bearing for nothing: the empty() guards that open each
function already establish the non-falsy return type, so relaxing these
eleven declarations leaves the error count unchanged at 282.

`name` keeps its non-falsy-string, both because the schema pattern
establishes it and because generate_block_asset_handle() requires it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Core defines the constant as `__DIR__ . '/'` everywhere it appears, and the
separator is load-bearing rather than incidental. The comment core attaches
to the very next constant makes that explicit:

    define( 'WP_CONTENT_DIR', ABSPATH . 'wp-content' ); // No trailing slash, full paths only

Without it the bootstrap produced `…/srcwp-content`, and the error carried
into WP_PLUGIN_DIR, WPMU_PLUGIN_DIR, TEMPLATEPATH, STYLESHEETPATH and
BLOGUPLOADDIR, as well as into every `ABSPATH . WPINC` in the analysed code.

Nothing is reported differently as a result, since PHPStan does not resolve
these paths on disk: the five files that exercise them report 1351 errors
either way. The value was simply wrong.

Also give the WP_Filesystem() reference its parentheses, matching the other
`@see` tags in the file and distinguishing the function from a class that
does not exist.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Deriving the constant from __DIR__ gave it the developer's own checkout
location, which PHPStan then folded into the text of any error mentioning a
path built from it:

    Binary operation "." between '/Users/westonruter…' and mixed results in an error.

Three messages across the analysed files carried that prefix, so output was
not reproducible between machines and a generated baseline would not have
been portable.

Nothing resolves files through the constant, so a fixed path serves the same
purpose. The same three messages now read '/var/www/html/wp…' and the error
count is unchanged.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…strap

These were the last placeholders left over from the surrounding constants
being made realistic. All of them now match what core would define:

- WP_LANG_DIR follows the first branch of wp_set_lang_dir(), which is the
  common case. The other branch builds on WPINC, which the bootstrap never
  defines, so it is not available here.
- FS_CONNECT_TIMEOUT and FS_TIMEOUT are 30 seconds in WP_Filesystem().
- FS_CHMOD_DIR and FS_CHMOD_FILE are computed there from fileperms(), which
  cannot run against a fictional ABSPATH. The literals are the floor those
  expressions guarantee through `| 0755` and `| 0644`.

The values are documentation rather than input to the analysis. WP_LANG_DIR
is listed in dynamicConstantNames so PHPStan discards it, and the FS_*
constants are integers either way. Across the twenty-two files that reference
any of them, the results are byte for byte identical.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
PHPStan reads the value the bootstrap actually produces, so microtime( true )
gave the constant a different literal type on every run:

    Dumped type: 1785652449.138539
    Dumped type: 1785652451.311018

It is read at functions.php:9014 and class-wp-debug-data.php:2012, both
subtracting it from microtime( true ) to measure elapsed time. A fixed value
serves that just as well and keeps the analysis reproducible, for the same
reason ABSPATH no longer derives from __DIR__.

Both consuming files report 658 errors either way.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
pento pushed a commit that referenced this pull request Aug 2, 2026
Many constants were defined as empty strings, including ones that never hold an empty value in a real install. Realistic values are provided for those, matching what wp-settings.php and default-constants.php would produce, so that functions building on them can be given narrower types without the placeholder itself violating them. Constants core itself defines as empty, such as WP_DEVELOPMENT_MODE and COOKIE_DOMAIN, are left as they were.

Developed as subset of #11851.

See #64898.


git-svn-id: https://develop.svn.wordpress.org/trunk@62965 602fd350-edb4-49c9-b593-d223f7449a82
markjaquith pushed a commit to markjaquith/WordPress that referenced this pull request Aug 2, 2026
Many constants were defined as empty strings, including ones that never hold an empty value in a real install. Realistic values are provided for those, matching what wp-settings.php and default-constants.php would produce, so that functions building on them can be given narrower types without the placeholder itself violating them. Constants core itself defines as empty, such as WP_DEVELOPMENT_MODE and COOKIE_DOMAIN, are left as they were.

Developed as subset of WordPress/wordpress-develop#11851.

See #64898.

Built from https://develop.svn.wordpress.org/trunk@62965


git-svn-id: http://core.svn.wordpress.org/trunk@62206 1a063a9b-81f0-0310-95a4-ce76da25c4cd
pento pushed a commit that referenced this pull request Aug 2, 2026
Per the inline documentation standards, a docblock's summary belongs on its own line separated from the description, and the description should not open with "It". This is applied to `register_block_script_module_id()`, `register_block_script_handle()`, and `register_block_style_handle()`, together with some missing articles in the same descriptions.

Two of those descriptions no longer matched the code. `register_block_script_handle()` said the script is registered under an automatically generated handle, but since 6.5.0 the handle is taken from the asset file whenever one provides it, and generation is only the fallback. `register_block_style_handle()` said it returns the unprocessed style handle otherwise, which does not hold for the first style of a core block: that one is registered from the block's own stylesheet when separate core block assets are loaded, and skipped entirely when they are not.

The same functions gain `@phpstan-` annotations describing the shape of the `$metadata` they accept and the narrower strings they return. The shapes follow the `block.json` schema, which constrains only `name`, so the remaining fields stay plain strings; `file` is nullable and `name` optional because `register_block_type_from_metadata()` can reach all three functions with neither present.

Developed in #11851.
Follow-up to r48141, r55447, r57559, r57565.

Props deepakrohilla, westonruter, sabernhardt, wildworks, audrasjb.
See #64898.
Fixes #65259.


git-svn-id: https://develop.svn.wordpress.org/trunk@62966 602fd350-edb4-49c9-b593-d223f7449a82
@github-actions

github-actions Bot commented Aug 2, 2026

Copy link
Copy Markdown

A commit was made that fixes the Trac ticket referenced in the description of this pull request.

SVN changeset: 62966
GitHub commit: 29fe42e

This PR will be closed, but please confirm the accuracy of this and reopen if there is more work to be done.

@github-actions github-actions Bot closed this Aug 2, 2026
markjaquith pushed a commit to markjaquith/WordPress that referenced this pull request Aug 2, 2026
Per the inline documentation standards, a docblock's summary belongs on its own line separated from the description, and the description should not open with "It". This is applied to `register_block_script_module_id()`, `register_block_script_handle()`, and `register_block_style_handle()`, together with some missing articles in the same descriptions.

Two of those descriptions no longer matched the code. `register_block_script_handle()` said the script is registered under an automatically generated handle, but since 6.5.0 the handle is taken from the asset file whenever one provides it, and generation is only the fallback. `register_block_style_handle()` said it returns the unprocessed style handle otherwise, which does not hold for the first style of a core block: that one is registered from the block's own stylesheet when separate core block assets are loaded, and skipped entirely when they are not.

The same functions gain `@phpstan-` annotations describing the shape of the `$metadata` they accept and the narrower strings they return. The shapes follow the `block.json` schema, which constrains only `name`, so the remaining fields stay plain strings; `file` is nullable and `name` optional because `register_block_type_from_metadata()` can reach all three functions with neither present.

Developed in WordPress/wordpress-develop#11851.
Follow-up to r48141, r55447, r57559, r57565.

Props deepakrohilla, westonruter, sabernhardt, wildworks, audrasjb.
See #64898.
Fixes #65259.

Built from https://develop.svn.wordpress.org/trunk@62966


git-svn-id: http://core.svn.wordpress.org/trunk@62207 1a063a9b-81f0-0310-95a4-ce76da25c4cd
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants