[ Index ] |
PHP Cross Reference of WordPress Trunk (Updated Daily) |
[Source view] [Print] [Project Stats]
Efficiently scan through block structure in document without parsing the entire block tree and all of its JSON attributes into memory.
File Size: | 1983 lines (69 kb) |
Included or required: | 0 times |
Referenced: | 0 times |
Includes or requires: | 0 files |
WP_Block_Processor:: (24 methods):
__construct()
next_block()
next_delimiter()
next_token()
get_breadcrumbs()
get_depth()
extract_block()
find_html_comment_end()
get_last_error()
get_last_json_error()
get_delimiter_type()
has_closing_flag()
is_block_type()
are_equal_block_types()
opens_block()
is_html()
is_non_whitespace_html()
get_html_content()
get_block_type()
get_printable_block_type()
normalize_block_type()
get_attributes()
allocate_and_return_parsed_attributes()
get_span()
Class: WP_Block_Processor - X-Ref
Class for efficiently scanning through block structure in a document__construct( string $source_text ) X-Ref |
Creates a new block processor. Example: $processor = new WP_Block_Processor( $post_content ); if ( $processor->next_block( 'core/image' ) ) { echo "Found an image!\n"; } param: string $source_text Input document potentially containing block content. |
next_block( ?string $block_type = null ) X-Ref |
Advance to the next block delimiter which opens a block, indicating if one was found. Delimiters which open blocks include opening and void block delimiters. To visit freeform HTML content, pass the wildcard “*” as the block type. Use this function to walk through the blocks in a document, pausing where they open. Example blocks: // The first delimiter opens the paragraph block. <⃨!⃨-⃨-⃨ ⃨w⃨p⃨:⃨p⃨a⃨r⃨a⃨g⃨r⃨a⃨p⃨h⃨ ⃨-⃨-⃨>⃨<p>Content</p><!-- /wp:paragraph--> // The void block is the first opener in this sequence of closers. <!-- /wp:group --><⃨!⃨-⃨-⃨ ⃨w⃨p⃨:⃨s⃨p⃨a⃨c⃨e⃨r⃨ ⃨{⃨"⃨h⃨e⃨i⃨g⃨h⃨t⃨"⃨:⃨"⃨2⃨0⃨0⃨p⃨x⃨"⃨}⃨ ⃨/⃨-⃨-⃨>⃨<!-- /wp:group --> // If, however, `*` is provided as the block type, freeform content is matched. <⃨h⃨2⃨>⃨M⃨y⃨ ⃨s⃨y⃨n⃨o⃨p⃨s⃨i⃨s⃨<⃨/⃨h⃨2⃨>⃨\⃨n⃨<!-- wp:my/table-of-contents /--> // Inner HTML is never freeform content, and will not be matched even with the wildcard. <!-- /wp:list-item --></ul><!-- /wp:list --><⃨!⃨-⃨-⃨ ⃨w⃨p⃨:⃨p⃨a⃨r⃨a⃨g⃨r⃨a⃨p⃨h⃨ ⃨-⃨>⃨<p> Example: // Find all textual ranges of image block opening delimiters. $images = array(); $processor = new WP_Block_Processor( $html ); while ( $processor->next_block( 'core/image' ) ) { $images[] = $processor->get_span(); } In some cases it may be useful to conditionally visit the implicit freeform blocks, such as when determining if a post contains freeform content that isn’t purely whitespace. Example: $seen_block_types = []; $block_type = '*'; $processor = new WP_Block_Processor( $html ); while ( $processor->next_block( $block_type ) { // Stop wasting time visiting freeform blocks after one has been found. if ( '*' === $block_type && null === $processor->get_block_type() && $processor->is_non_whitespace_html() ) { $block_type = null; $seen_block_types['core/freeform'] = true; continue; } $seen_block_types[ $processor->get_block_type() ] = true; } param: string|null $block_type Optional. If provided, advance until a block of this type is found. return: bool Whether an opening delimiter for a block was found. |
next_delimiter( ?string $block_name = null ) X-Ref |
Advance to the next block delimiter in a document, indicating if one was found. Delimiters may include invalid JSON. This parser does not attempt to parse the JSON attributes until requested; when invalid, the attributes will be null. This matches the behavior of {@see \parse_blocks()}. To visit freeform HTML content, pass the wildcard “*” as the block type. Use this function to walk through the block delimiters in a document. Example delimiters: <!-- wp:paragraph {"dropCap": true} --> <!-- wp:separator /--> <!-- /wp:paragraph --> // If the wildcard `*` is provided as the block type, freeform content is matched. <⃨h⃨2⃨>⃨M⃨y⃨ ⃨s⃨y⃨n⃨o⃨p⃨s⃨i⃨s⃨<⃨/⃨h⃨2⃨>⃨\⃨n⃨<!-- wp:my/table-of-contents /--> // Inner HTML is never freeform content, and will not be matched even with the wildcard. ...</ul><⃨!⃨-⃨-⃨ ⃨/⃨w⃨p⃨:⃨l⃨i⃨s⃨t⃨ ⃨-⃨-⃨>⃨<!-- wp:paragraph --><p> Example: $html = '<!-- wp:void /-->\n<!-- wp:void /-->'; $processor = new WP_Block_Processor( $html ); while ( $processor->next_delimiter() { // Runs twice, seeing both void blocks of type “core/void.” } $processor = new WP_Block_Processor( $html ); while ( $processor->next_delimiter( '*' ) ) { // Runs thrice, seeing the void block, the newline span, and the void block. } param: string|null $block_name Optional. Keep searching until a block of this name is found. return: bool Whether a block delimiter was matched. |
next_token() X-Ref |
Advance to the next block delimiter or HTML span in a document, indicating if one was found. This function steps through every syntactic chunk in a document. This includes explicit block comment delimiters, freeform non-block content, and inner HTML segments. Example tokens: <!-- wp:paragraph {"dropCap": true} --> <!-- wp:separator /--> <!-- /wp:paragraph --> <p>Normal HTML content</p> Plaintext content too! Example: // Find span containing wrapping HTML element surrounding inner blocks. $processor = new WP_Block_Processor( $html ); if ( ! $processor->next_block( 'gallery' ) ) { return null; } $containing_span = null; while ( $processor->next_token() && $processor->is_html() ) { $containing_span = $processor->get_span(); } This method will visit all HTML spans including those forming freeform non-block content as well as those which are part of a block’s inner HTML. return: bool Whether a token was matched or the end of the document was reached without finding any. |
get_breadcrumbs() X-Ref |
Returns an array containing the names of the currently-open blocks, in order from outermost to innermost, with HTML spans indicated as “#html”. Example: // Freeform HTML content is an HTML span. $processor = new WP_Block_Processor( 'Just text' ); $processor->next_token(); array( '#text' ) === $processor->get_breadcrumbs(); $processor = new WP_Block_Processor( '<!-- wp:a --><!-- wp:b --><!-- wp:c /--><!-- /wp:b --><!-- /wp:a -->' ); $processor->next_token(); array( 'core/a' ) === $processor->get_breadcrumbs(); $processor->next_token(); array( 'core/a', 'core/b' ) === $processor->get_breadcrumbs(); $processor->next_token(); // Void blocks are only open while visiting them. array( 'core/a', 'core/b', 'core/c' ) === $processor->get_breadcrumbs(); $processor->next_token(); // Blocks are closed before visiting their closing delimiter. array( 'core/a' ) === $processor->get_breadcrumbs(); $processor->next_token(); array() === $processor->get_breadcrumbs(); // Inner HTML is also an HTML span. $processor = new WP_Block_Processor( '<!-- wp:a -->Inner HTML<!-- /wp:a -->' ); $processor->next_token(); $processor->next_token(); array( 'core/a', '#html' ) === $processor->get_breadcrumbs(); return: string[] |
get_depth() X-Ref |
Returns the depth of the open blocks where the processor is currently matched. Depth increases before visiting openers and void blocks and decreases before visiting closers. HTML spans behave like void blocks. return: int |
extract_block() X-Ref |
Extracts a block object, and all inner content, starting at a matched opening block delimiter, or at a matched top-level HTML span as freeform HTML content. Use this function to extract some blocks within a document, but not all. For example, one might want to find image galleries, parse them, modify them, and then reserialize them in place. Once this function returns, the parser will be matched on token following the close of the given block. The return type of this method is compatible with the return of {@see \parse_blocks()}. Example: $processor = new WP_Block_Processor( $post_content ); if ( ! $processor->next_block( 'gallery' ) ) { return $post_content; } $gallery_at = $processor->get_span()->start; $gallery = $processor->extract_block(); $ends_before = $processor->get_span(); $ends_before = $ends_before->start ?? strlen( $post_content ); $new_gallery = update_gallery( $gallery ); $new_gallery = serialize_block( $new_gallery ); return ( substr( $post_content, 0, $gallery_at ) . $new_gallery . substr( $post_content, $ends_before ) ); return: array[]|null { |
find_html_comment_end( int $comment_starting_at, int $search_end ) X-Ref |
Returns the byte-offset after the ending character of an HTML comment, assuming the proper starting byte offset. param: int $comment_starting_at Where the HTML comment started, the leading `<`. param: int $search_end Last offset in which to search, for limiting search span. return: int Offset after the current HTML comment ends, or `$search_end` if no end was found. |
get_last_error() X-Ref |
Indicates if the last attempt to parse a block comment delimiter failed, if set, otherwise `null` if the last attempt succeeded. return: string|null Error from last attempt at parsing next block delimiter, |
get_last_json_error() X-Ref |
Indicates if the last attempt to parse a block’s JSON attributes failed. return: int JSON_ERROR_ code from last attempt to parse block JSON attributes. |
get_delimiter_type() X-Ref |
Returns the type of the block comment delimiter. One of: - {@see self::OPENER} - {@see self::CLOSER} - {@see self::VOID} - `null` return: string|null type of the block comment delimiter, if currently matched. |
has_closing_flag() X-Ref |
Returns whether the delimiter contains the closing flag. This should be avoided except in cases of custom error-handling with block closers containing the void flag. For normative use, {@see self::get_delimiter_type()}. return: bool Whether the currently-matched block delimiter contains the closing flag. |
is_block_type( string $block_type ) X-Ref |
Indicates if the block delimiter represents a block of the given type. Since the “core” namespace may be implicit, it’s allowable to pass either the fully-qualified block type with namespace and block name as well as the shorthand version only containing the block name, if the desired block is in the “core” namespace. Since freeform HTML content is non-block content, it has no block type. Passing the wildcard “*” will, however, return true for all block types, even the implicit freeform content, though not for spans of inner HTML. Example: $is_core_paragraph = $processor->is_block_type( 'paragraph' ); $is_core_paragraph = $processor->is_block_type( 'core/paragraph' ); $is_formula = $processor->is_block_type( 'math-block/formula' ); param: string $block_type Block type name for the desired block. return: bool Whether this delimiter represents a block of the given type. |
are_equal_block_types( string $a_text, int $a_at, int $a_length, string $b_text, int $b_at, int $b_length ) X-Ref |
Given two spans of text, indicate if they represent identical block types. This function normalizes block types to account for implicit core namespacing. Note! This function only returns valid results when the complete block types are represented in the span offsets and lengths. This means that the full optional namespace and block name must be represented in the input arguments. Example: 0 5 10 15 20 25 30 35 40 $text = '<!-- wp:block --><!-- /wp:core/block -->'; true === WP_Block_Processor::are_equal_block_types( $text, 9, 5, $text, 27, 10 ); false === WP_Block_Processor::are_equal_block_types( $text, 9, 5, 'my/block', 0, 8 ); param: string $a_text Text in which first block type appears. param: int $a_at Byte offset into text in which first block type starts. param: int $a_length Byte length of first block type. param: string $b_text Text in which second block type appears (may be the same as the first text). param: int $b_at Byte offset into text in which second block type starts. param: int $b_length Byte length of second block type. return: bool Whether the spans of text represent identical block types, normalized for namespacing. |
opens_block( string ...$block_type ) X-Ref |
Indicates if the matched delimiter is an opening or void delimiter of the given type, if a type is provided, otherwise if it opens any block or implicit freeform HTML content. This is a helper method to ease handling of code inspecting where blocks start, and for checking if the blocks are of a given type. The function is variadic to allow for checking if the delimiter opens one of many possible block types. To advance to the start of a block {@see self::next_block()}. Example: $processor = new WP_Block_Processor( $html ); while ( $processor->next_delimiter() ) { if ( $processor->opens_block( 'core/code', 'syntaxhighlighter/code' ) ) { echo "Found code!"; continue; } if ( $processor->opens_block( 'core/image' ) ) { echo "Found an image!"; continue; } if ( $processor->opens_block() ) { echo "Found a new block!"; } } param: string[] $block_type Optional. Is the matched block type one of these? return: bool Whether the matched block delimiter opens a block, and whether it |
is_html() X-Ref |
Indicates if the matched delimiter is an HTML span. return: bool Whether the processor is matched on an HTML span. |
is_non_whitespace_html() X-Ref |
Indicates if the matched delimiter is an HTML span and comprises more than whitespace characters, i.e. contains real content. Many block serializers introduce newlines between block delimiters, so the presence of top-level non-block content does not imply that there are “real” freeform HTML blocks. Checking if there is content beyond whitespace is a more certain check, such as for determining whether to load CSS for the freeform or fallback block type. return: bool Whether the currently-matched delimiter is an HTML |
get_html_content() X-Ref |
Returns the string content of a matched HTML span, or `null` otherwise. return: string|null Raw HTML content, or `null` if not currently matched on HTML. |
get_block_type() X-Ref |
Allocates a substring for the block type and returns the fully-qualified name, including the namespace, if matched on a delimiter, otherwise `null`. This function is like {@see self::get_printable_block_type()} but when paused on a freeform HTML block, will return `null` instead of “core/freeform”. The `null` behavior matches what {@see \parse_blocks()} returns but may not be as useful as having a string value. This function allocates a substring for the given block type. This allocation will be small and likely fine in most cases, but it's preferable to call {@see self::is_block_type()} if only needing to know whether the delimiter is for a given block type, as that function is more efficient for this purpose and avoids the allocation. Example: // Avoid. 'core/paragraph' = $processor->get_block_type(); // Prefer. $processor->is_block_type( 'core/paragraph' ); $processor->is_block_type( 'paragraph' ); $processor->is_block_type( 'core/freeform' ); // Freeform HTML content has no block type. $processor = new WP_Block_Processor( 'non-block content' ); $processor->next_token(); null === $processor->get_block_type(); return: string|null Fully-qualified block namespace and type, e.g. "core/paragraph", |
get_printable_block_type() X-Ref |
Allocates a printable substring for the block type and returns the fully-qualified name, including the namespace, if matched on a delimiter or freeform block, otherwise `null`. This function is like {@see self::get_block_type()} but when paused on a freeform HTML block, will return “core/freeform” instead of `null`. The `null` behavior matches what {@see \parse_blocks()} returns but may not be as useful as having a string value. This function allocates a substring for the given block type. This allocation will be small and likely fine in most cases, but it's preferable to call {@see self::is_block_type()} if only needing to know whether the delimiter is for a given block type, as that function is more efficient for this purpose and avoids the allocation. Example: // Avoid. 'core/paragraph' = $processor->get_printable_block_type(); // Prefer. $processor->is_block_type( 'core/paragraph' ); $processor->is_block_type( 'paragraph' ); $processor->is_block_type( 'core/freeform' ); // Freeform HTML content is given an implicit type. $processor = new WP_Block_Processor( 'non-block content' ); $processor->next_token(); 'core/freeform' === $processor->get_printable_block_type(); return: string|null Fully-qualified block namespace and type, e.g. "core/paragraph", |
normalize_block_type( string $block_type ) X-Ref |
Normalizes a block name to ensure that missing implicit “core” namespaces are present. Example: 'core/paragraph' === WP_Block_Processor::normalize_block_byte( 'paragraph' ); 'core/paragraph' === WP_Block_Processor::normalize_block_byte( 'core/paragraph' ); 'my/paragraph' === WP_Block_Processor::normalize_block_byte( 'my/paragraph' ); param: string $block_type Valid block name, potentially without a namespace. return: string Fully-qualified block type including namespace. |
get_attributes() X-Ref |
Returns a lazy wrapper around the block attributes, which can be used for efficiently interacting with the JSON attributes. This stub hints that there should be a lazy interface for parsing block attributes but doesn’t define it. It serves both as a placeholder for one to come as well as a guard against implementing an eager function in its place. return: never |
allocate_and_return_parsed_attributes() X-Ref |
Attempts to parse and return the entire JSON attributes from the delimiter, allocating memory and processing the JSON span in the process. This does not return any parsed attributes for a closing block delimiter even if there is a span of JSON content; this JSON is a parsing error. Consider calling {@see static::get_attributes()} instead if it's not necessary to read all the attributes at the same time, as that provides a more efficient mechanism for typical use cases. Since the JSON span inside the comment delimiter may not be valid JSON, this function will return `null` if it cannot parse the span and set the {@see static::get_last_json_error()} to the appropriate JSON_ERROR_ constant. If the delimiter contains no JSON span, it will also return `null`, but the last error will be set to {@see \JSON_ERROR_NONE}. Example: $processor = new WP_Block_Processor( '<!-- wp:image {"url": "https://wordpress.org/favicon.ico"} -->' ); $processor->next_delimiter(); $memory_hungry_and_slow_attributes = $processor->allocate_and_return_parsed_attributes(); $memory_hungry_and_slow_attributes === array( 'url' => 'https://wordpress.org/favicon.ico' ); $processor = new WP_Block_Processor( '<!-- /wp:image {"url": "https://wordpress.org/favicon.ico"} -->' ); $processor->next_delimiter(); null = $processor->allocate_and_return_parsed_attributes(); JSON_ERROR_NONE = $processor->get_last_json_error(); $processor = new WP_Block_Processor( '<!-- wp:separator {} /-->' ); $processor->next_delimiter(); array() === $processor->allocate_and_return_parsed_attributes(); $processor = new WP_Block_Processor( '<!-- wp:separator /-->' ); $processor->next_delimiter(); null = $processor->allocate_and_return_parsed_attributes(); $processor = new WP_Block_Processor( '<!-- wp:image {"url} -->' ); $processor->next_delimiter(); null = $processor->allocate_and_return_parsed_attributes(); JSON_ERROR_CTRL_CHAR = $processor->get_last_json_error(); return: array|null Parsed JSON attributes, if present and valid, otherwise `null`. |
get_span() X-Ref |
Returns the span representing the currently-matched delimiter, if matched, otherwise `null`. Example: $processor = new WP_Block_Processor( '<!-- wp:void /-->' ); null === $processor->get_span(); $processor->next_delimiter(); WP_HTML_Span( 0, 17 ) === $processor->get_span(); return: WP_HTML_Span|null Span of text in source text spanning matched delimiter. |
Generated : Fri Oct 17 08:20:04 2025 | Cross-referenced by PHPXref |