Skip to content

Commit

Permalink
Create Block: Improve project template configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
gziolo committed Feb 24, 2022
1 parent 139c160 commit 1bfc038
Show file tree
Hide file tree
Showing 13 changed files with 83 additions and 59 deletions.
57 changes: 31 additions & 26 deletions packages/create-block/README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
# Create Block

Create Block is an officially supported way to create blocks for registering a block for a WordPress plugin. It offers a modern build setup with no configuration. It generates PHP, JS, CSS code, and everything else you need to start the project.
Create Block is an officially supported tool for scaffolding WordPress plugins with blocks. It generates PHP, JS, CSS code, and everything you need to start the project. It integrates a modern build setup with no configuration.

It is largely inspired by [create-react-app](https://create-react-app.dev/docs/getting-started). Major kudos to [@gaearon](https://github.com/gaearon), the whole Facebook team, and the React community.

## Description

Blocks are the fundamental element of the WordPress block editor. They are the primary way in which plugins and themes can register their own functionality and extend the capabilities of the editor.
Blocks are the fundamental element of the WordPress block editor. They are the primary way in which plugins and themes can register their functionality and extend the editor's capabilities.

Visit the [Gutenberg handbook](https://developer.wordpress.org/block-editor/developers/block-api/block-registration/) to learn more about Block API.

## Quick start

You just need to provide the `slug` which is the target location for scaffolded plugin files and the internal block name.
You only need to provide the `slug` the target location for scaffolded plugin files and the internal block name.

```bash
$ npx @wordpress/create-block todo-list
Expand All @@ -26,24 +26,24 @@ It creates a WordPress plugin that you need to [install manually](https://wordpr

## Usage

The following command generates PHP, JS and CSS code for registering a block.
The following command generates a project with PHP, JS, and CSS code for registering a block with a WordPress plugin.

```bash
$ npx @wordpress/create-block [options] [slug]
```

![Demo](https://user-images.githubusercontent.com/699132/103872910-4de15f00-50cf-11eb-8c74-67ca91a8c1a4.gif)

`[slug]` is optional. When provided it triggers the quick mode where 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 overridden with some of the options listed below.
`[slug]` is optional. When provided, it triggers the quick mode where 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 overridden with some options listed below.

Options:

```bash
-V, --version output the version number
-t, --template <name> plugin template type name, allowed values: "es5", "esnext", the name of an external npm package (default: "esnext"), or the path to a local directory.
-t, --template <name> project template type name; allowed values: "static" (default), "es5", the name of an external npm package, or the path to a local directory
--namespace <value> internal namespace for the block name
--title <value> display title for the plugin/block
--short-description <value> short description for the plugin/block
--title <value> display title for the block and the WordPress plugin
--short-description <value> short description for the block and the WordPress plugin
--category <name> category name for the block
--wp-scripts enable integration with `@wordpress/scripts` package
--no-wp-scripts disable integration with `@wordpress/scripts` package
Expand All @@ -59,16 +59,16 @@ More examples:
$ npx @wordpress/create-block
```

2. ES5 template – it is also possible to pick ES5 template when you don't want to deal with a build step (`npm start`) which enables ESNext and JSX support.
2. External npm package – it is also possible to select an external npm package as a template.

```bash
$ npx @wordpress/create-block --template es5
$ npx @wordpress/create-block --template my-template-package
```

3. Local template directory – it is also possible to pick a local directory as a template.

```bash
$ npx @wordpress/create-block --template ./path/to/template
$ npx @wordpress/create-block --template ./path/to/template-directory
```

4. Help – you need to use `npx` to output usage information.
Expand All @@ -77,11 +77,11 @@ $ npx @wordpress/create-block --template ./path/to/template
$ npx @wordpress/create-block --help
```

When you scaffold a block, you must provide at least a `slug` name, the `namespace` which usually corresponds to either the `theme` or `plugin` name, and the `category`. In most cases, we recommended pairing blocks with plugins rather than themes, because only using plugin ensures that all blocks still work when your theme changes.
When you scaffold a block, you must provide at least a `slug` name, the `namespace` which usually corresponds to either the `theme` or `plugin` name. In most cases, we recommended pairing blocks with WordPress plugins rather than themes, because only using plugin ensures that all blocks still work when your theme changes.

## Available Commands

When bootstrapped with the `esnext` template (or any external template with `wpScripts` flag enabled), you can run several commands inside the directory:
When bootstrapped with the `static` template (or any other project template with `wpScripts` flag enabled), you can run several commands inside the directory:

```bash
$ npm start
Expand Down Expand Up @@ -113,6 +113,12 @@ $ npm run lint:js

Lints JavaScript files. [Learn more](https://github.com/WordPress/gutenberg/tree/HEAD/packages/scripts#lint-js).

```bash
$ npm run plugin-zip
```

Creates a zip file for a WordPress plugin. [Learn more](https://github.com/WordPress/gutenberg/tree/HEAD/packages/scripts#plugin-zip).

```bash
$ npm run packages-update
```
Expand All @@ -121,31 +127,31 @@ Updates WordPress packages to the latest version. [Learn more](https://github.co

_Note: You don’t need to install or configure tools like [webpack](https://webpack.js.org), [Babel](https://babeljs.io) or [ESLint](https://eslint.org) yourself. They are preconfigured and hidden so that you can focus on coding._

## External Templates
## External Project Templates

Since version `0.19.0` it is possible to use external templates hosted on npm. These packages need to contain `.mustache` files that will be used during the block scaffolding process.
Since version `3.0.0` it is possible to use an external project template hosted on npm or located in a local directory. These npm packages can provide custom `.mustache` files that replace default files included in the tool for the WordPress plugin or/and the block. It's also possible to override default configuration values used during the scaffolding process.

### Template Configuration
### Project Templates Configuration

It is mandatory to provide the main file (`index.js` by default) for the package that returns a configuration object. It must contain at least the `templatesPath` field.
Providing the main file (`index.js` by default) for the package that returns a configuration object is mandatory. Several options allow customizing the scaffolding process.

#### `templatesPath`
#### `pluginTemplatesPath`

A mandatory field with the path pointing to the location where plugin template files live (nested folders are also supported). All files without the `.mustache` extension will be ignored.
This optional field allows overriding file templates related to **the WordPress plugin shell**. The path points to a location with template files ending with the `.mustache` extension (nested folders are also supported). When not set, the tool uses its own set of templates.

_Example:_

```js
const { join } = require( 'path' );

module.exports = {
templatesPath: join( __dirname, 'plugin-templates' ),
pluginTemplatesPath: join( __dirname, 'plugin-templates' ),
};
```

#### `blockTemplatesPath`

An optional field with the path pointing to the location where template files for the individual block live (nested folders are also supported). All files without the `.mustache` extension will be ignored.
This optional field allows overriding file templates related to **the individual block**. The path points to a location with template files ending with the `.mustache` extension (nested folders are also supported). When not set, the tool uses its own set of templates.

_Example:_

Expand All @@ -159,7 +165,7 @@ module.exports = {

#### `assetsPath`

This setting is useful when your template scaffolds a plugin that uses static assets like images or fonts, which should not be processed. It provides the path pointing to the location where assets are located. They will be copied to the `assets` subfolder in the generated plugin.
This setting is useful when your template scaffolds a WordPress plugin that uses static assets like images or fonts, which should not be processed. It provides the path pointing to the location where assets are located. They will be copied to the `assets` subfolder in the generated plugin.

_Example:_

Expand All @@ -185,7 +191,6 @@ module.exports = {
dashicon: 'palmtree',
version: '1.2.3',
},
templatesPath: __dirname,
};
```

Expand All @@ -210,9 +215,9 @@ The following configurable variables are used with the template files. Template
- `npmDependencies` (default: `[]`) – the list of remote npm packages to be installed in the project with [`npm install`](https://docs.npmjs.com/cli/v8/commands/npm-install) when `wpScripts` is enabled.
`customScripts` (default: {}) - the list of custom scripts to add to `package.json`. It also allows overriding default scripts.
- `folderName` (default: `.`) – the location for the `block.json` file and other optional block files generated from block templates included in the folder set with the `blockTemplatesPath` setting.
- `editorScript` (default: `'file:./build/index.js'`)
- `editorStyle` (default: `'file:./build/index.css'`)
- `style` (default: `'file:./build/style-index.css'`)
- `editorScript` (default: `'file:./index.js'`)
- `editorStyle` (default: `'file:./index.css'`)
- `style` (default: `'file:./style-index.css'`)

## Contributing to this package

Expand Down
21 changes: 13 additions & 8 deletions packages/create-block/lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,26 +23,29 @@ const commandName = `wp-create-block`;
program
.name( commandName )
.description(
'Generates PHP, JS and CSS code for registering a block for a WordPress plugin.\n\n' +
'[slug] is optional. When provided it triggers the quick mode where ' +
'Generates PHP, JS and CSS code for registering a WordPress plugin with blocks.\n\n' +
'[slug] is optional. When provided, it triggers the quick mode where ' +
'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 ' +
'overridden with some of the options listed below.'
'overridden with some options listed below.'
)
.version( version )
.arguments( '[slug]' )
.option(
'-t, --template <name>',
'plugin template type name, allowed values: "es5", "esnext", or the name of an external npm package',
'esnext'
'project template type name; allowed values: "static", "es5", the name of an external npm package, or the path to a local directory',
'static'
)
.option( '--namespace <value>', 'internal namespace for the block name' )
.option( '--title <value>', 'display title for the plugin/block' )
.option(
'--title <value>',
'display title for the block and the WordPress plugin'
)
// The name "description" is used internally so it couldn't be used.
.option(
'--short-description <value>',
'short description for the plugin/block'
'short description for the block and the WordPress plugin'
)
.option( '--category <name>', 'category name for the block' )
.option(
Expand Down Expand Up @@ -98,7 +101,9 @@ program
! Object.keys( optionsValues ).includes( name )
);
log.info( '' );
log.info( "Let's customize your WordPress plugin:" );
log.info(
"Let's customize your WordPress plugin with blocks:"
);
const answers = await inquirer.prompt( prompts );
await scaffold( pluginTemplate, {
...defaultValues,
Expand Down
17 changes: 10 additions & 7 deletions packages/create-block/lib/scaffold.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const { code, info, success } = require( './log' );
const { writeOutputAsset, writeOutputTemplate } = require( './output' );

module.exports = async (
{ blockOutputTemplates, outputTemplates, outputAssets },
{ blockOutputTemplates, pluginOutputTemplates, outputAssets },
{
$schema,
apiVersion,
Expand Down Expand Up @@ -44,7 +44,7 @@ module.exports = async (
namespace = namespace.toLowerCase();

info( '' );
info( `Creating a new WordPress plugin in "${ slug }" folder.` );
info( `Creating a new WordPress plugin in the "${ slug }" directory.` );

const view = {
$schema,
Expand Down Expand Up @@ -76,10 +76,10 @@ module.exports = async (
};

await Promise.all(
Object.keys( outputTemplates ).map(
Object.keys( pluginOutputTemplates ).map(
async ( outputFile ) =>
await writeOutputTemplate(
outputTemplates[ outputFile ],
pluginOutputTemplates[ outputFile ],
outputFile,
view
)
Expand Down Expand Up @@ -111,11 +111,11 @@ module.exports = async (

info( '' );
success(
`Done: block "${ title }" bootstrapped in the "${ slug }" folder.`
`Done: WordPress plugin "${ title }" bootstrapped in the "${ slug }" directory.`
);
if ( wpScripts ) {
info( '' );
info( 'Inside that directory, you can run several commands:' );
info( 'You can run several commands inside:' );
info( '' );
code( ' $ npm start' );
info( ' Starts the build for development.' );
Expand All @@ -132,11 +132,14 @@ module.exports = async (
code( ' $ npm run lint:js' );
info( ' Lints JavaScript files.' );
info( '' );
code( ' $ npm run plugin-zip' );
info( ' Creates a zip file for a WordPress plugin.' );
info( '' );
code( ' $ npm run packages-update' );
info( ' Updates WordPress packages to the latest version.' );
}
info( '' );
info( 'To enter the folder type:' );
info( 'To enter the directory type:' );
info( '' );
code( ` $ cd ${ slug }` );
if ( wpScripts ) {
Expand Down
47 changes: 29 additions & 18 deletions packages/create-block/lib/templates.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,23 +34,17 @@ const predefinedPluginTemplates = {
},
templatesPath: join( __dirname, 'templates', 'es5' ),
},
esnext: {
static: {
defaultValues: {
slug: 'esnext-example',
title: 'ESNext Example',
slug: 'static-example',
title: 'Static Example',
description:
'Example block written with ESNext standard and JSX support – build step required.',
'Example static block written with JSX support – build step required.',
dashicon: 'smiley',
supports: {
html: false,
},
folderName: 'src',
editorScript: 'file:./index.js',
editorStyle: 'file:./index.css',
style: 'file:./style-index.css',
},
templatesPath: join( __dirname, 'templates', 'esnext', 'plugin' ),
blockTemplatesPath: join( __dirname, 'templates', 'esnext', 'block' ),
},
};

Expand Down Expand Up @@ -103,22 +97,39 @@ const externalTemplateExists = async ( templateName ) => {
};

const configToTemplate = async ( {
assetsPath,
pluginTemplatesPath,
blockTemplatesPath,
defaultValues = {},
templatesPath,
assetsPath,
...deprecated
} ) => {
if ( ! isObject( defaultValues ) || ! templatesPath ) {
if ( ! isObject( defaultValues ) ) {
throw new CLIError( 'Template found but invalid definition provided.' );
}

if ( deprecated.templatesPath ) {
pluginTemplatesPath = deprecated.templatesPath;
defaultValues = {
folderName: '.',
editorScript: 'file:./build/index.js',
editorStyle: 'file:./build/index.css',
style: 'file:./build/style-index.css',
...defaultValues,
};
} else {
pluginTemplatesPath =
pluginTemplatesPath || join( __dirname, 'templates', 'plugin' );
blockTemplatesPath =
blockTemplatesPath || join( __dirname, 'templates', 'block' );
}

return {
blockOutputTemplates: blockTemplatesPath
? await getOutputTemplates( blockTemplatesPath )
: {},
defaultValues,
outputAssets: assetsPath ? await getOutputAssets( assetsPath ) : {},
outputTemplates: await getOutputTemplates( templatesPath ),
pluginOutputTemplates: await getOutputTemplates( pluginTemplatesPath ),
};
};

Expand Down Expand Up @@ -201,10 +212,10 @@ const getDefaultValues = ( pluginTemplate ) => {
customScripts: {},
wpEnv: false,
npmDependencies: [],
folderName: '.',
editorScript: 'file:./build/index.js',
editorStyle: 'file:./build/index.css',
style: 'file:./build/style-index.css',
folderName: './src',
editorScript: 'file:./index.js',
editorStyle: 'file:./index.css',
style: 'file:./style-index.css',
...pluginTemplate.defaultValues,
};
};
Expand Down

0 comments on commit 1bfc038

Please sign in to comment.