Skip to content

Commit

Permalink
Create Block: Refactor handling for template variants (#43481)
Browse files Browse the repository at this point in the history
  • Loading branch information
gziolo authored Aug 23, 2022
1 parent 3a54b7d commit 6b393f8
Show file tree
Hide file tree
Showing 13 changed files with 92 additions and 103 deletions.
4 changes: 4 additions & 0 deletions packages/create-block-tutorial-template/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Unreleased

### Enhancement

- Add support to the `dynamic` variant ([#41289](https://github.com/WordPress/gutenberg/pull/41289), [#43481](https://github.com/WordPress/gutenberg/pull/43481)).

## 2.3.0 (2022-06-01)

### Enhancement
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ registerBlockType( metadata.name, {
*/
edit: Edit,
{{#isStaticVariant}}

/**
* @see ./save.js
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{{#isDynamicVariant}}
<p <?php echo get_block_wrapper_attributes(); ?>>
<?php echo esc_html( $atts['message']) ?>
<?php echo esc_html( $attributes['message'] ); ?>
</p>
{{/isDynamicVariant}}
Original file line number Diff line number Diff line change
Expand Up @@ -37,33 +37,32 @@
*
* @see https://developer.wordpress.org/reference/functions/register_block_type/
*/
{{#isStaticVariant}}
function {{namespaceSnakeCase}}_{{slugSnakeCase}}_block_init() {
{{#isStaticVariant}}
register_block_type( __DIR__ . '/build' );
}
add_action( 'init', '{{namespaceSnakeCase}}_{{slugSnakeCase}}_block_init' );
{{/isStaticVariant}}
{{#isDynamicVariant}}
function {{namespaceSnakeCase}}_{{slugSnakeCase}}_block_init() {
{{/isStaticVariant}}
{{#isDynamicVariant}}
register_block_type(
__DIR__ . '/build',
array(
'render_callback' => '{{namespaceSnakeCase}}_{{slugSnakeCase}}_render_callback',
)
);
{{/isDynamicVariant}}
}
add_action( 'init', '{{namespaceSnakeCase}}_{{slugSnakeCase}}_block_init' );
{{#isDynamicVariant}}

/**
* Render callback function
* Render callback function.
*
* @param array $attributes The block attributes.
* @param string $content The block content.
* @param WP_Block $block Block instance.
*
* @return string The rendered output.
*/
function {{namespaceSnakeCase}}_{{slugSnakeCase}}_render_callback( $atts, $content, $block) {
function {{namespaceSnakeCase}}_{{slugSnakeCase}}_render_callback( $atts, $content, $block ) {
ob_start();
require plugin_dir_path( __FILE__ ) . 'build/template.php';
return ob_get_clean();
Expand Down
2 changes: 1 addition & 1 deletion packages/create-block/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
### New Feature

- Add `--no-plugin` flag to allow scaffolding of a block in an existing plugin ([#41642](https://github.com/WordPress/gutenberg/pull/41642))
- Introduce the `--variant` flag to allow selection of a variant as defined in the template ([#41289](https://github.com/WordPress/gutenberg/pull/41289)).
- Introduce the `--variant` flag to allow selection of a variant as defined in the template ([#41289](https://github.com/WordPress/gutenberg/pull/41289), [#43481](https://github.com/WordPress/gutenberg/pull/43481)).

## 3.6.0 (2022-07-13)

Expand Down
58 changes: 39 additions & 19 deletions packages/create-block/lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,22 @@ program
await checkSystemRequirements( engines );
try {
const pluginTemplate = await getPluginTemplate( templateName );
const defaultValues = getDefaultValues(
pluginTemplate,
variant
const availableVariants = Object.keys(
pluginTemplate.variants
);
if ( variant && ! availableVariants.includes( variant ) ) {
if ( ! availableVariants.length ) {
throw new CLIError(
`"${ variant }" variant was selected. This template does not have any variants!`
);
}
throw new CLIError(
`"${ variant }" is not a valid variant for this template. Available variants are: ${ availableVariants.join(
', '
) }.`
);
}

const optionsValues = Object.fromEntries(
Object.entries( {
plugin,
Expand All @@ -90,11 +102,14 @@ program
title,
wpScripts,
wpEnv,
variant,
} ).filter( ( [ , value ] ) => value !== undefined )
);

if ( slug ) {
const defaultValues = getDefaultValues(
pluginTemplate,
variant
);
const answers = {
...defaultValues,
slug,
Expand All @@ -111,19 +126,24 @@ program
: "Let's add a new block to your existing WordPress plugin:"
);

const filterOptionsProvided = ( { name } ) =>
! Object.keys( optionsValues ).includes( name );
if ( ! variant && availableVariants.length > 1 ) {
const result = await inquirer.prompt( {
type: 'list',
name: 'variant',
message:
'The template variant to use for this block:',
choices: availableVariants,
} );
variant = result.variant;
}

// Get the variant prompt first. This will help get the default values
const variantPrompt =
Object.keys( pluginTemplate.variants )?.length > 1
? getPrompts( pluginTemplate, [ 'variant' ] )
: false;

const variantSelection = variantPrompt
? await inquirer.prompt( variantPrompt )
: false;
const defaultValues = getDefaultValues(
pluginTemplate,
variant
);

const filterOptionsProvided = ( { name } ) =>
! Object.keys( optionsValues ).includes( name );
const blockPrompts = getPrompts(
pluginTemplate,
[
Expand All @@ -134,9 +154,8 @@ program
'dashicon',
'category',
],
variantSelection.variant
variant
).filter( filterOptionsProvided );

const blockAnswers = await inquirer.prompt( blockPrompts );

const pluginAnswers = plugin
Expand All @@ -163,7 +182,8 @@ program
'licenseURI',
'domainPath',
'updateURI',
]
],
variant
).filter( filterOptionsProvided );
const result = await inquirer.prompt(
pluginPrompts
Expand All @@ -175,8 +195,8 @@ program
await scaffold( pluginTemplate, {
...defaultValues,
...optionsValues,
variant,
...blockAnswers,
...variantSelection,
...pluginAnswers,
} );
}
Expand Down
8 changes: 0 additions & 8 deletions packages/create-block/lib/prompts.js
Original file line number Diff line number Diff line change
Expand Up @@ -134,16 +134,8 @@ const updateURI = {
message: 'A custom update URI for the plugin (optional):',
};

const variant = {
type: 'list',
name: 'variant',
message: 'The template variant to use for this block:',
choices: [],
};

module.exports = {
slug,
variant,
namespace,
title,
description,
Expand Down
8 changes: 3 additions & 5 deletions packages/create-block/lib/scaffold.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,9 @@ const initWPScripts = require( './init-wp-scripts' );
const initWPEnv = require( './init-wp-env' );
const { code, info, success, error } = require( './log' );
const { writeOutputAsset, writeOutputTemplate } = require( './output' );
const { getTemplateVariantVars } = require( './templates' );

module.exports = async (
{ blockOutputTemplates, pluginOutputTemplates, outputAssets, variants },
{ blockOutputTemplates, pluginOutputTemplates, outputAssets },
{
$schema,
apiVersion,
Expand Down Expand Up @@ -44,7 +43,7 @@ module.exports = async (
editorScript,
editorStyle,
style,
variant,
variantVars,
}
) => {
slug = slug.toLowerCase();
Expand Down Expand Up @@ -100,8 +99,7 @@ module.exports = async (
editorScript,
editorStyle,
style,
...getTemplateVariantVars( variants, variant ),
...variants[ variant ],
...variantVars,
};

if ( plugin ) {
Expand Down
57 changes: 19 additions & 38 deletions packages/create-block/lib/templates.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,9 @@ const externalTemplateExists = async ( templateName ) => {
const configToTemplate = async ( {
pluginTemplatesPath,
blockTemplatesPath,
defaultValues = {},
assetsPath,
variants,
defaultValues = {},
variants = {},
...deprecated
} ) => {
if ( defaultValues === null || typeof defaultValues !== 'object' ) {
Expand All @@ -140,9 +140,9 @@ const configToTemplate = async ( {
blockOutputTemplates: blockTemplatesPath
? await getOutputTemplates( blockTemplatesPath )
: {},
defaultValues,
outputAssets: assetsPath ? await getOutputAssets( assetsPath ) : {},
pluginOutputTemplates: await getOutputTemplates( pluginTemplatesPath ),
outputAssets: assetsPath ? await getOutputAssets( assetsPath ) : {},
defaultValues,
variants,
};
};
Expand Down Expand Up @@ -231,60 +231,41 @@ const getDefaultValues = ( pluginTemplate, variant ) => {
editorStyle: 'file:./index.css',
style: 'file:./style-index.css',
...pluginTemplate.defaultValues,
...pluginTemplate.variants[ variant ],
...pluginTemplate.variants?.[ variant ],
variantVars: getVariantVars( pluginTemplate.variants, variant ),
};
};

const getPrompts = ( pluginTemplate, keys, variant ) => {
const defaultValues = getDefaultValues( pluginTemplate );
const variantData = pluginTemplate.variants[ variant ] ?? false;
const defaultValues = getDefaultValues( pluginTemplate, variant );
return keys.map( ( promptName ) => {
if ( promptName === 'variant' ) {
prompts[ promptName ].choices = Object.keys(
pluginTemplate.variants
);
}
if ( variantData && variantData[ promptName ] ) {
return {
...prompts[ promptName ],
default: variantData[ promptName ],
};
}
return {
...prompts[ promptName ],
default: defaultValues[ promptName ],
};
} );
};

const getTemplateVariantVars = ( variants, variant ) => {
const getVariantVars = ( variants, variant ) => {
const variantVars = {};
if ( variants ) {
const variantNames = Object.keys( variants );
const chosenVariant = variant ?? variantNames[ 0 ]; // If no variant is passed, use the first in the array as the default
const variantNames = Object.keys( variants );
if ( variantNames.length === 0 ) {
return variantVars;
}

if ( variantNames.includes( chosenVariant ) ) {
for ( const variantName of variantNames ) {
const key =
variantName.charAt( 0 ).toUpperCase() +
variantName.slice( 1 );
variantVars[ `is${ key }Variant` ] =
chosenVariant === variantName ?? false;
}
} else {
throw new CLIError(
`"${ chosenVariant }" is not a valid variant for this template. Available variants are: ${ variantNames.join(
', '
) }`
);
}
const currentVariant = variant ?? variantNames[ 0 ];
for ( const variantName of variantNames ) {
const key =
variantName.charAt( 0 ).toUpperCase() + variantName.slice( 1 );
variantVars[ `is${ key }Variant` ] =
currentVariant === variantName ?? false;
}

return variantVars;
};

module.exports = {
getPluginTemplate,
getDefaultValues,
getPrompts,
getTemplateVariantVars,
};
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ registerBlockType( metadata.name, {
*/
edit: Edit,
{{#isStaticVariant}}

/**
* @see ./save.js
*/
Expand Down
20 changes: 6 additions & 14 deletions packages/create-block/lib/templates/es5/$slug.php.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -68,40 +68,32 @@ function {{namespaceSnakeCase}}_{{slugSnakeCase}}_block_init() {
array(),
filemtime( "$dir/$style_css" )
);
{{^isDynamicVariant}}
register_block_type(
'{{namespace}}/{{slug}}',
array(
'editor_script' => '{{namespace}}-{{slug}}-block-editor',
'editor_style' => '{{namespace}}-{{slug}}-block-editor',
'style' => '{{namespace}}-{{slug}}-block',
)
);
{{/isDynamicVariant}}
{{#isDynamicVariant}}
register_block_type(
'{{namespace}}/{{slug}}',
array(
'editor_script' => '{{namespace}}-{{slug}}-block-editor',
'editor_style' => '{{namespace}}-{{slug}}-block-editor',
'style' => '{{namespace}}-{{slug}}-block',
{{#isDynamicVariant}}
'render_callback' => '{{namespaceSnakeCase}}_{{slugSnakeCase}}_render_callback',
{{/isDynamicVariant}}
)
);
{{/isDynamicVariant}}
}
add_action( 'init', '{{namespaceSnakeCase}}_{{slugSnakeCase}}_block_init' );
{{#isDynamicVariant}}

/**
* Render callback function
* Render callback function.
*
* @param array $attributes The block attributes.
* @param string $content The block content.
* @param WP_Block $block Block instance.
*
* @return string The rendered output.
*/
function {{namespaceSnakeCase}}_{{slugSnakeCase}}_render_callback( $atts, $content, $block) {
function {{namespaceSnakeCase}}_{{slugSnakeCase}}_render_callback( $attributes, $content, $block ) {
ob_start();
require plugin_dir_path( __FILE__ ) . '/template.php';
return ob_get_clean();
Expand Down
4 changes: 3 additions & 1 deletion packages/create-block/lib/templates/es5/index.js.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,9 @@
useBlockProps(),
__( '{{title}} – hello from the editor!', '{{textdomain}}' )
);
}{{#isStaticVariant}},
},
{{#isStaticVariant}}

/**
* The save function defines the way in which the different attributes should be combined
* into the final markup, which is then serialized by the block editor into `post_content`.
Expand Down
Loading

0 comments on commit 6b393f8

Please sign in to comment.