функция since 6.8.0

apply_block_hooks_to_content_from_post_object()

Проверено на WordPress 6.9, обновлено Источник: WordPress Developer Resources.

Сигнатура

apply_block_hooks_to_content_from_post_object( string $content, WP_Post|null $post = null, callable $callback = 'insert_hooked_blocks', array|null $ignored_hooked_blocks_at_root = null ): string

Описание

Эта функция отличается от apply_block_hooks_to_content тем, что учитывает информацию об игнорируемых подключённых блоках из метаданных записи. Это гарантирует корректную обработку блоков, подключённых как первый или последний дочерний элемент блока, соответствующего типу записи.

Оригинал (английский)

This function is different from apply_block_hooks_to_content in that it takes ignored hooked block information from the post’s metadata into account. This ensures that any blocks hooked as first or last child of the block that corresponds to the post type are handled correctly.

Параметры

$content string обязательный
Сериализованное содержимое.
$post WP_Post|null необязательный = null
Объект записи, которому принадлежит содержимое. Если задано null, будет вызвана get_post() для использования текущей записи в качестве контекста. Значение по умолчанию: null.
$callback callable необязательный = 'insert_hooked_blocks'
Функция, которая будет вызываться для каждого блока, чтобы сформировать разметку для заданного списка блоков, подключённых к нему. Значение по умолчанию: 'insert_hooked_blocks'.
$ignored_hooked_blocks_at_root array|null необязательный = null
Ссылка на массив, который будет заполнен игнорируемыми подключёнными блоками на корневом уровне. Значение по умолчанию: null.

Возвращаемое значение

string

Исходный код

wp-includes/blocks.php:1214

function apply_block_hooks_to_content_from_post_object(
	$content,
	$post = null,
	$callback = 'insert_hooked_blocks',
	&$ignored_hooked_blocks_at_root = null
) {
	// Default to the current post if no context is provided.
	if ( null === $post ) {
		$post = get_post();
	}

	if ( ! $post instanceof WP_Post ) {
		return apply_block_hooks_to_content( $content, $post, $callback );
	}

	/*
	 * If the content was created using the classic editor or using a single Classic block
	 * (`core/freeform`), it might not contain any block markup at all.
	 * However, we still might need to inject hooked blocks in the first child or last child
	 * positions of the parent block. To be able to apply the Block Hooks algorithm, we wrap
	 * the content in a `core/freeform` wrapper block.
	 */
	if ( ! has_blocks( $content ) ) {
		$original_content = $content;

		$content_wrapped_in_classic_block = get_comment_delimited_block_content(
			'core/freeform',
			array(),
			$content
		);

		$content = $content_wrapped_in_classic_block;
	}

	$attributes = array();

	// If context is a post object, `ignoredHookedBlocks` information is stored in its post meta.
	$ignored_hooked_blocks = get_post_meta( $post->ID, '_wp_ignored_hooked_blocks', true );
	if ( ! empty( $ignored_hooked_blocks ) ) {
		$ignored_hooked_blocks  = json_decode( $ignored_hooked_blocks, true );
		$attributes['metadata'] = array(
			'ignoredHookedBlocks' => $ignored_hooked_blocks,
		);
	}

	/*
	 * We need to wrap the content in a temporary wrapper block with that metadata
	 * so the Block Hooks algorithm can insert blocks that are hooked as first or last child
	 * of the wrapper block.
	 * To that end, we need to determine the wrapper block type based on the post type.
	 */
	if ( 'wp_navigation' === $post->post_type ) {
		$wrapper_block_type = 'core/navigation';
	} elseif ( 'wp_block' === $post->post_type ) {
		$wrapper_block_type = 'core/block';
	} else {
		$wrapper_block_type = 'core/post-content';
	}

	$content = get_comment_delimited_block_content(
		$wrapper_block_type,
		$attributes,
		$content
	);

	/*
	 * We need to avoid inserting any blocks hooked into the `before` and `after` positions
	 * of the temporary wrapper block that we create to wrap the content.
	 * See https://core.trac.wordpress.org/ticket/63287 for more details.
	 */
	$suppress_blocks_from_insertion_before_and_after_wrapper_block = static function ( $hooked_block_types, $relative_position, $anchor_block_type ) use ( $wrapper_block_type ) {
		if (
			$wrapper_block_type === $anchor_block_type &&
			in_array( $relative_position, array( 'before', 'after' ), true )
		) {
			return array();
		}
		return $hooked_block_types;
	};

	// Apply Block Hooks.
	add_filter( 'hooked_block_types', $suppress_blocks_from_insertion_before_and_after_wrapper_block, PHP_INT_MAX, 3 );
	$content = apply_block_hooks_to_content( $content, $post, $callback );
	remove_filter( 'hooked_block_types', $suppress_blocks_from_insertion_before_and_after_wrapper_block, PHP_INT_MAX );

	if ( null !== $ignored_hooked_blocks_at_root ) {
		// Check wrapper block's metadata for ignored hooked blocks at the root level, and populate the reference parameter if needed.
		$wrapper_block_markup = extract_serialized_parent_block( $content );
		$wrapper_block        = parse_blocks( $wrapper_block_markup )[0];

		if ( ! empty( $wrapper_block['attrs']['metadata']['ignoredHookedBlocks'] ) ) {
			$ignored_hooked_blocks_at_root = $wrapper_block['attrs']['metadata']['ignoredHookedBlocks'];
		}
	}

	// Finally, we need to remove the temporary wrapper block.
	$content = remove_serialized_parent_block( $content );

	// If we wrapped the content in a `core/freeform` block, we also need to remove that.
	if ( ! empty( $content_wrapped_in_classic_block ) ) {
		/*
		 * We cannot simply use remove_serialized_parent_block() here,
		 * as that function assumes that the block wrapper is at the top level.
		 * However, there might now be a hooked block inserted next to it
		 * (as first or last child of the parent).
		 */
		$content = str_replace( $content_wrapped_in_classic_block, $original_content, $content );
	}

	return $content;
}

История изменений

ВерсияОписание
7.0.0 Added the $ignored_hooked_blocks_at_root parameter.
6.8.0 Introduced.

Что будем искать? Например,Продвижение

Этот сайт использует куки-файлы. Оставаясь на сайте, Вы соглашаетесь на их использование. Для получения дополнительной информации, пожалуйста, ознакомьтесь с политикой в отношении персональных данных.