Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Try: Make gallery randomization work when nested #58733

Merged
merged 7 commits into from Feb 7, 2024
Merged
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
79 changes: 58 additions & 21 deletions packages/block-library/src/gallery/index.php
Expand Up @@ -33,32 +33,18 @@ function block_core_gallery_data_id_backcompatibility( $parsed_block ) {
add_filter( 'render_block_data', 'block_core_gallery_data_id_backcompatibility' );

/**
* Filter to randomize the order of image blocks.
*
* @param array $parsed_block The block being rendered.
* @return array The block object with randomized order of image blocks.
*/
function block_core_gallery_random_order( $parsed_block ) {
if ( 'core/gallery' === $parsed_block['blockName'] && ! empty( $parsed_block['attrs']['randomOrder'] ) ) {
shuffle( $parsed_block['innerBlocks'] );
}
return $parsed_block;
}

add_filter( 'render_block_data', 'block_core_gallery_random_order' );

/**
* Adds a style tag for the --wp--style--unstable-gallery-gap var.
*
* The Gallery block needs to recalculate Image block width based on
* the current gap setting in order to maintain the number of flex columns
* so a css var is added to allow this.
* Renders the `core/gallery` block on the server.
*
* @param array $attributes Attributes of the block being rendered.
* @param string $content Content of the block being rendered.
* @return string The content of the block being rendered.
*/
function block_core_gallery_render( $attributes, $content ) {
// Adds a style tag for the --wp--style--unstable-gallery-gap var.
// The Gallery block needs to recalculate Image block width based on
// the current gap setting in order to maintain the number of flex columns
// so a css var is added to allow this.

$gap = $attributes['style']['spacing']['blockGap'] ?? null;
// Skip if gap value contains unsupported characters.
// Regex for CSS value borrowed from `safecss_filter_attr`, and used here
Expand Down Expand Up @@ -130,7 +116,58 @@ function block_core_gallery_render( $attributes, $content ) {
'context' => 'block-supports',
)
);
return (string) $processed_content;

// Randomize the order of image blocks. Ideally we should shuffle
// the `$parsed_block['innerBlocks']` via the `render_block_data` hook.
// However, this hook doesn't apply inner block updates when blocks are
// nested.
// TODO: In the future, if this hook supports updating innerBlocks in
// nested blocks, it should be refactored.
// See: https://github.com/WordPress/gutenberg/pull/58733
aaronrobertshaw marked this conversation as resolved.
Show resolved Hide resolved
if ( empty( $attributes['randomOrder'] ) ) {
return $processed_content;
}

$processor = new WP_HTML_Tag_Processor( (string) $processed_content );

// Add an index to each figure tag to uniquely identify each Image block.
$i = 0;
while ( $processor->next_tag( array( 'class_name' => 'wp-block-image' ) ) ) {
$processor->set_attribute( 'data-image-index', $i );
++$i;
}
$content = $processor->get_updated_html();

$pattern = '/<figure[^>]*\bdata-image-index\b[^>]*>.*?<\/figure>/';
aaronrobertshaw marked this conversation as resolved.
Show resolved Hide resolved

// Find all Image blocks.
preg_match_all( $pattern, $content, $matches );
if ( ! $matches ) {
return $content;
}
aaronrobertshaw marked this conversation as resolved.
Show resolved Hide resolved
$image_blocks = $matches[0];

// Randomize the order of Image blocks.
shuffle( $image_blocks );
$i = 0;
$content = preg_replace_callback(
$pattern,
static function () use ( $image_blocks, &$i ) {
$new_image_block = $image_blocks[ $i ];
++$i;
return $new_image_block;
},
$content
t-hamano marked this conversation as resolved.
Show resolved Hide resolved
);

// Remove the index from each Image block.
$processor = new WP_HTML_Tag_Processor( $content );
while ( $processor->next_tag( array( 'class_name' => 'wp-block-image' ) ) ) {
$processor->remove_attribute( 'data-image-index' );
}
$content = $processor->get_updated_html();
aaronrobertshaw marked this conversation as resolved.
Show resolved Hide resolved

return $content;
}
/**
* Registers the `core/gallery` block on server.
Expand Down