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’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Recursively add loop index to nested inner blocks #41

Merged
merged 1 commit into from
Sep 12, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 33 additions & 23 deletions inc/editor/block-bindings/block-bindings.php
Original file line number Diff line number Diff line change
Expand Up @@ -260,29 +260,10 @@ public static function loop_block_render_callback( array $attributes, string $co
// by the binding source to render the correct result.
foreach ( array_keys( $query_results['results'] ) as $index ) {

// Loop over the inner blocks of the template and update the bindings.
foreach ( $loop_template as $inner_block ) {
if ( ! isset( $inner_block['attrs']['metadata']['bindings'] ) ) {
// No bindings to update.
$block->parsed_block['innerBlocks'][] = $inner_block;
continue;
}

// Update bindings with the result index.
foreach ( $inner_block['attrs']['metadata']['bindings'] as $target => $binding ) {
if ( ! isset( $binding['source'] ) || $binding['source'] !== self::$binding_source ) {
// Not our binding.
continue;
}

// Add the result index to the binding args so that it can be read by
// our binding source.
$inner_block['attrs']['metadata']['bindings'][ $target ]['args']['index'] = $index;
}

// Push in the updated inner block.
$block->parsed_block['innerBlocks'][] = $inner_block;
}
// Loop over the inner blocks of the template and update the bindings to
// include the current index.
$updated_inner_blocks = self::add_loop_index_to_inner_blocks( $loop_template, $index );
$block->parsed_block['innerBlocks'] = array_merge( $block->parsed_block['innerBlocks'], $updated_inner_blocks );

// We don't care too much what the content is, we just need to make sure
// it's there so that it can be looped over by WP_Block#render.
Expand All @@ -297,6 +278,35 @@ public static function loop_block_render_callback( array $attributes, string $co
return $updated_block->render( [ 'dynamic' => false ] );
}

/**
* Recursively add the loop index to the bindings of the inner blocks.
*
* @param array $inner_blocks The inner blocks to update.
* @param int $index The loop index.
* @return array The updated inner blocks.
*/
private static function add_loop_index_to_inner_blocks( array $inner_blocks, int $index ): array {
foreach ( $inner_blocks as &$inner_block ) {
// Update bindings with the result index.
foreach ( $inner_block['attrs']['metadata']['bindings'] ?? [] as $target => $binding ) {
if ( ! isset( $binding['source'] ) || $binding['source'] !== self::$binding_source ) {
continue; // Not our binding.
}

// Add the loop index to the binding args so that it can be read by
// our binding source.
$inner_block['attrs']['metadata']['bindings'][ $target ]['args']['index'] = $index;
}

// If this block has inner blocks, recurse.
if ( isset( $inner_block['innerBlocks'] ) ) {
$inner_block['innerBlocks'] = self::add_loop_index_to_inner_blocks( $inner_block['innerBlocks'], $index );
}
}

return $inner_blocks;
}

public static function log_error( string $message, string $block_name, string $operation_name = 'unknown' ): void {
$logger = LoggerManager::instance();
$logger->error( sprintf( '%s %s (block: %s; operation: %s)', $message, self::$context_name, $block_name, $operation_name ) );
Expand Down