WP_Block_Processor::extract_full_block_and_advance(): array[]|null

In this article

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.

Description

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 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_full_block_and_advance();
$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 Array of block structures.
  • ...$0 array
    An associative array of a single parsed block object. See WP_Block_Parser_Block.
    • blockName string|null
      Name of block.
    • attrs array
      Attributes from block comment delimiters.
    • innerBlocks array[]
      List of inner blocks. An array of arrays that have the same structure as this one.
    • innerHTML string
      HTML from inside block comment delimiters.
    • innerContent array
      List of string fragments and null markers where inner blocks were found.

Source

public function extract_full_block_and_advance(): ?array {
	if ( $this->is_html() ) {
		$chunk = $this->get_html_content();

		return array(
			'blockName'    => null,
			'attrs'        => array(),
			'innerBlocks'  => array(),
			'innerHTML'    => $chunk,
			'innerContent' => array( $chunk ),
		);
	}

	$block = array(
		'blockName'    => $this->get_block_type(),
		'attrs'        => $this->allocate_and_return_parsed_attributes() ?? array(),
		'innerBlocks'  => array(),
		'innerHTML'    => '',
		'innerContent' => array(),
	);

	$depth = $this->get_depth();
	while ( $this->next_token() && $this->get_depth() > $depth ) {
		if ( $this->is_html() ) {
			$chunk                   = $this->get_html_content();
			$block['innerHTML']     .= $chunk;
			$block['innerContent'][] = $chunk;
			continue;
		}

		/**
		 * Inner blocks.
		 *
		 * @todo This is a decent place to call \render_block()
		 * @todo Use iteration instead of recursion, or at least refactor to tail-call form.
		 */
		if ( $this->opens_block() ) {
			$inner_block             = $this->extract_full_block_and_advance();
			$block['innerBlocks'][]  = $inner_block;
			$block['innerContent'][] = null;
		}

		/*
		 * Because the parser has advanced past the closing block token, it
		 * may be matched on an HTML span. This needs to be processed before
		 * moving on to the next token at the start of the next loop iteration.
		 */
		if ( $this->is_html() ) {
			$chunk                   = $this->get_html_content();
			$block['innerHTML']     .= $chunk;
			$block['innerContent'][] = $chunk;
		}
	}

	return $block;
}

Changelog

VersionDescription
6.9.0Introduced.

User Contributed Notes

You must log in before being able to contribute a note or feedback.