Skip to content

Commit

Permalink
Create Block: Simplify the process of defining a config for templates (
Browse files Browse the repository at this point in the history
…#22235)

* Create Block: Use glob to find all template files

* Create block: Refactor template handling

* Move output files templates to getBlockTemplate

* Add CHANGELOG entry

* Apply suggestions from code review

Co-authored-by: Andrew Duthie <andrew@andrewduthie.com>

Co-authored-by: Andrew Duthie <andrew@andrewduthie.com>
  • Loading branch information
gziolo and aduth authored May 13, 2020
1 parent 731378d commit f13c1d2
Show file tree
Hide file tree
Showing 7 changed files with 99 additions and 87 deletions.
1 change: 1 addition & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions packages/create-block/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Unreleased

### Internal

- Refactored handling of predefined block templates [#22235](https://github.com/WordPress/gutenberg/pull/22235).

## 0.12.0 (2020-04-30)

### New Features
Expand Down
2 changes: 1 addition & 1 deletion packages/create-block/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ $ npm init @wordpress/block [options] [slug]
Options:
```
-V, --version output the version number
-t, --template <name> template type name, allowed values: "es5", "esnext" (default: "esnext")
-t, --template <name> block template type name, allowed values: "es5", "esnext" (default: "esnext")
--namespace <value> internal namespace for the block name
--title <value> display title for the block
--short-description <value> short description for the block
Expand Down
31 changes: 21 additions & 10 deletions packages/create-block/lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@ const CLIError = require( './cli-error' );
const log = require( './log' );
const { engines, version } = require( '../package.json' );
const scaffold = require( './scaffold' );
const { getDefaultValues, getPrompts } = require( './templates' );
const {
getBlockTemplate,
getDefaultValues,
getPrompts,
} = require( './templates' );

const commandName = `wp-create-block`;
program
Expand All @@ -24,13 +28,13 @@ program
'it is used as the block slug used for its identification, the output ' +
'location for scaffolded files, and the name of the WordPress plugin.' +
'The rest of the configuration is set to all default values unless ' +
'overriden with some of the options listed below.'
'overridden with some of the options listed below.'
)
.version( version )
.arguments( '[slug]' )
.option(
'-t, --template <name>',
'template type name, allowed values: "es5", "esnext"',
'block template type name, allowed values: "es5", "esnext"',
'esnext'
)
.option( '--namespace <value>', 'internal namespace for the block name' )
Expand All @@ -41,14 +45,21 @@ program
.action(
async (
slug,
{ category, namespace, shortDescription, template, title }
{
category,
namespace,
shortDescription: description,
template: templateName,
title,
}
) => {
await checkSystemRequirements( engines );
try {
const defaultValues = getDefaultValues( template );
const blockTemplate = await getBlockTemplate( templateName );
const defaultValues = getDefaultValues( blockTemplate );
const optionsValues = pickBy( {
category,
description: shortDescription,
description,
namespace,
title,
} );
Expand All @@ -60,14 +71,14 @@ program
title: startCase( slug ),
...optionsValues,
};
await scaffold( template, answers );
await scaffold( blockTemplate, answers );
} else {
const propmpts = getPrompts( template ).filter(
const prompts = getPrompts( blockTemplate ).filter(
( { name } ) =>
! Object.keys( optionsValues ).includes( name )
);
const answers = await inquirer.prompt( propmpts );
await scaffold( template, {
const answers = await inquirer.prompt( prompts );
await scaffold( blockTemplate, {
...defaultValues,
...optionsValues,
...answers,
Expand Down
31 changes: 14 additions & 17 deletions packages/create-block/lib/scaffold.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
/**
* External dependencies
*/
const { dirname, join } = require( 'path' );
const { writeFile } = require( 'fs' ).promises;
const { snakeCase } = require( 'lodash' );
const makeDir = require( 'make-dir' );
const { readFile, writeFile } = require( 'fs' ).promises;
const { render } = require( 'mustache' );
const { snakeCase } = require( 'lodash' );
const { dirname } = require( 'path' );

/**
* Internal dependencies
*/
const initWPScripts = require( './init-wp-scripts' );
const { code, info, success } = require( './log' );
const { hasWPScriptsEnabled, getOutputFiles } = require( './templates' );
const { hasWPScriptsEnabled } = require( './templates' );

module.exports = async function(
templateName,
blockTemplate,
{
namespace,
slug,
Expand All @@ -35,6 +35,7 @@ module.exports = async function(
info( '' );
info( `Creating a new WordPress block in "${ slug }" folder.` );

const { outputTemplates } = blockTemplate;
const view = {
namespace,
namespaceSnakeCase: snakeCase( namespace ),
Expand All @@ -51,33 +52,29 @@ module.exports = async function(
textdomain: namespace,
};
await Promise.all(
getOutputFiles( templateName ).map( async ( file ) => {
const template = await readFile(
join(
__dirname,
`templates/${ templateName }/${ file }.mustache`
),
'utf8'
);
Object.keys( outputTemplates ).map( async ( outputFile ) => {
// Output files can have names that depend on the slug provided.
const outputFilePath = `${ slug }/${ file.replace(
const outputFilePath = `${ slug }/${ outputFile.replace(
/\$slug/g,
slug
) }`;
await makeDir( dirname( outputFilePath ) );
writeFile( outputFilePath, render( template, view ) );
writeFile(
outputFilePath,
render( outputTemplates[ outputFile ], view )
);
} )
);

if ( hasWPScriptsEnabled( templateName ) ) {
if ( hasWPScriptsEnabled( blockTemplate ) ) {
await initWPScripts( view );
}

info( '' );
success(
`Done: block "${ title }" bootstrapped in the "${ slug }" folder.`
);
if ( hasWPScriptsEnabled( templateName ) ) {
if ( hasWPScriptsEnabled( blockTemplate ) ) {
info( '' );
info( 'Inside that directory, you can run several commands:' );
info( '' );
Expand Down
116 changes: 57 additions & 59 deletions packages/create-block/lib/templates.js
Original file line number Diff line number Diff line change
@@ -1,91 +1,89 @@
/**
* External dependencies
*/
const glob = require( 'fast-glob' );
const { readFile } = require( 'fs' ).promises;
const { fromPairs } = require( 'lodash' );
const { join } = require( 'path' );

/**
* Internal dependencies
*/
const CLIError = require( './cli-error' );
const prompts = require( './prompts' );

const namespace = 'create-block';
const dashicon = 'smiley';
const category = 'widgets';
const author = 'The WordPress Contributors';
const license = 'GPL-2.0-or-later';
const licenseURI = 'https://www.gnu.org/licenses/gpl-2.0.html';
const version = '0.1.0';

const templates = {
const predefinedBlockTemplates = {
es5: {
defaultValues: {
namespace,
slug: 'es5-example',
title: 'ES5 Example',
description:
'Example block written with ES5 standard and no JSX – no build step required.',
dashicon,
category,
author,
license,
licenseURI,
version,
},
outputFiles: [
'.editorconfig',
'editor.css',
'index.js',
'$slug.php',
'style.css',
'readme.txt',
],
wpScripts: false,
},
esnext: {
defaultValues: {
namespace,
slug: 'esnext-example',
title: 'ESNext Example',
description:
'Example block written with ESNext standard and JSX support – build step required.',
dashicon,
category,
author,
license,
licenseURI,
version,
},
outputFiles: [
'.editorconfig',
'.gitignore',
'editor.css',
'src/edit.js',
'src/index.js',
'src/save.js',
'$slug.php',
'style.css',
'readme.txt',
],
wpScriptsEnabled: true,
},
};

const getTemplate = ( templateName ) => {
if ( ! templates[ templateName ] ) {
const getOutputTemplates = async ( name ) => {
const outputTemplatesPath = join( __dirname, 'templates', name );
const outputTemplatesFiles = await glob( '**/*.mustache', {
cwd: outputTemplatesPath,
dot: true,
} );
return fromPairs(
await Promise.all(
outputTemplatesFiles.map( async ( outputTemplateFile ) => {
const outputFile = outputTemplateFile.replace(
/\.mustache$/,
''
);
const outputTemplate = await readFile(
join( outputTemplatesPath, outputTemplateFile ),
'utf8'
);
return [ outputFile, outputTemplate ];
} )
)
);
};

const getBlockTemplate = async ( templateName ) => {
if ( ! predefinedBlockTemplates[ templateName ] ) {
throw new CLIError(
`Invalid template type name. Allowed values: ${ Object.keys(
templates
`Invalid block template type name. Allowed values: ${ Object.keys(
predefinedBlockTemplates
).join( ', ' ) }.`
);
}
return templates[ templateName ];
};

const getDefaultValues = ( templateName ) => {
return getTemplate( templateName ).defaultValues;
return {
...predefinedBlockTemplates[ templateName ],
outputTemplates: await getOutputTemplates( templateName ),
};
};

const getOutputFiles = ( templateName ) => {
return getTemplate( templateName ).outputFiles;
const getDefaultValues = ( blockTemplate ) => {
return {
namespace: 'create-block',
dashicon: 'smiley',
category: 'widgets',
author: 'The WordPress Contributors',
license: 'GPL-2.0-or-later',
licenseURI: 'https://www.gnu.org/licenses/gpl-2.0.html',
version: '0.1.0',
...blockTemplate.defaultValues,
};
};

const getPrompts = ( templateName ) => {
const defaultValues = getDefaultValues( templateName );
const getPrompts = ( blockTemplate ) => {
const defaultValues = getDefaultValues( blockTemplate );
return Object.keys( prompts ).map( ( promptName ) => {
return {
...prompts[ promptName ],
Expand All @@ -94,13 +92,13 @@ const getPrompts = ( templateName ) => {
} );
};

const hasWPScriptsEnabled = ( templateName ) => {
return getTemplate( templateName ).wpScriptsEnabled || false;
const hasWPScriptsEnabled = ( blockTemplate ) => {
return blockTemplate.wpScripts !== false;
};

module.exports = {
getBlockTemplate,
getDefaultValues,
getOutputFiles,
getPrompts,
hasWPScriptsEnabled,
};
1 change: 1 addition & 0 deletions packages/create-block/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"check-node-version": "^3.1.1",
"commander": "^4.1.0",
"execa": "^4.0.0",
"fast-glob": "^2.2.7",
"inquirer": "^7.1.0",
"lodash": "^4.17.15",
"make-dir": "^3.0.0",
Expand Down

0 comments on commit f13c1d2

Please sign in to comment.