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

block.json: Allow passing filename as variations field #6668

Closed
Closed
Show file tree
Hide file tree
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
29 changes: 29 additions & 0 deletions src/wp-includes/blocks.php
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,7 @@ function get_block_metadata_i18n_schema() {
* @since 6.3.0 Added `selectors` field.
* @since 6.4.0 Added support for `blockHooks` field.
* @since 6.5.0 Added support for `allowedBlocks`, `viewScriptModule`, and `viewStyle` fields.
* @since 6.7.0 Allow PHP filename as `variations` argument.
*
* @param string $file_or_folder Path to the JSON file with metadata definition for
* the block or path to the folder where the `block.json` file is located.
Expand Down Expand Up @@ -522,6 +523,34 @@ function register_block_type_from_metadata( $file_or_folder, $args = array() ) {
}
}

// If `variations` is a string, it's the name of a PHP file that
// generates the variations.
if ( ! empty( $metadata['variations'] ) && is_string( $metadata['variations'] ) ) {
$variations_path = wp_normalize_path(
realpath(
dirname( $metadata['file'] ) . '/' .
remove_block_asset_path_prefix( $metadata['variations'] )
)
);
if ( $variations_path ) {
/**
* Generates the list of block variations.
*
* @since 6.7.0
*
* @return string Returns the list of block variations.
*/
$settings['variation_callback'] = static function () use ( $variations_path ) {
$variations = require $variations_path;
return $variations;
};
// The block instance's `variations` field is only allowed to be an array
// (of known block variations). We unset it so that the block instance will
// provide a getter that returns the result of the `variation_callback` instead.
unset( $settings['variations'] );
}
}

$settings = array_merge( $settings, $args );

$script_fields = array(
Expand Down
10 changes: 10 additions & 0 deletions tests/phpunit/data/blocks/notice/variations.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

return array(
array(
'name' => 'warning',
'title' => 'warning',
'description' => 'Shows warning.',
'keywords' => array( 'warning' ),
),
);
31 changes: 31 additions & 0 deletions tests/phpunit/tests/blocks/register.php
Original file line number Diff line number Diff line change
Expand Up @@ -957,6 +957,37 @@ public function data_register_block_registers_with_args_override_returns_false_w
);
}

/**
* Tests registering a block with variations from a PHP file.
*
* @ticket 61280
*
* @covers ::register_block_type_from_metadata
*/
public function test_register_block_type_from_metadata_with_variations_php_file() {
$filter_metadata_registration = static function ( $metadata ) {
$metadata['variations'] = 'file:./variations.php';
return $metadata;
};

add_filter( 'block_type_metadata', $filter_metadata_registration, 10, 2 );
$result = register_block_type_from_metadata(
DIR_TESTDATA . '/blocks/notice'
);
remove_filter( 'block_type_metadata', $filter_metadata_registration );

$this->assertInstanceOf( 'WP_Block_Type', $result, 'The block was not registered' );

$this->assertIsCallable( $result->variation_callback, 'The variation callback hasn\'t been set' );
$expected_variations = require DIR_TESTDATA . '/blocks/notice/variations.php';
$this->assertSame(
$expected_variations,
call_user_func( $result->variation_callback ),
'The variation callback hasn\'t been set correctly'
);
$this->assertSame( $expected_variations, $result->variations, 'The block variations are incorrect' );
}

/**
* Tests that the function returns the registered block when the `block.json`
* is found in the fixtures directory.
Expand Down
Loading