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

Create block: Add support for static assets #28038

Merged
merged 3 commits into from
Jan 8, 2021
Merged
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
4 changes: 4 additions & 0 deletions packages/create-block/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@

- Increase the minimum Node.js version to 12 ([#27934](https://github.com/WordPress/gutenberg/pull/27934)).

### New Features

- Add support for handling static assets with the `assetsPath` field in the external template configuration ([#28038](https://github.com/WordPress/gutenberg/pull/28038)).

### Internal

- Update the demo included in the README file ([#28037](https://github.com/WordPress/gutenberg/pull/28037)).
Expand Down
28 changes: 25 additions & 3 deletions packages/create-block/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,17 +120,39 @@ Since version `0.19.0` it is possible to use external templates hosted on npm. T

### Template Configuration

It is mandatory to provide the main file for the package that returns a configuration object. It must containing at least `templatesPath` field with the path pointing to the location where template files live (nested folders are also supported).
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.

#### `templatesPath`

A mandatory field with the path pointing to the location where template files live (nested folders are also supported). All files without the `.mustache` extension will be ignored.

_Example:_

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

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

It is also possible to override the default template configuration using the `defaultValues` field.
#### `assetsPath`

This setting is useful when your template scaffolds a block 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:_

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

module.exports = {
assetsPath: join( __dirname, 'assets' ),
};
```

#### `defaultValues`

It is possible to override the default template configuration using the `defaultValues` field.

_Example:_

Expand Down
20 changes: 14 additions & 6 deletions packages/create-block/lib/scaffold.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const { writeFile } = require( 'fs' ).promises;
const { snakeCase } = require( 'lodash' );
const makeDir = require( 'make-dir' );
const { render } = require( 'mustache' );
const { dirname } = require( 'path' );
const { dirname, join } = require( 'path' );

/**
* Internal dependencies
Expand Down Expand Up @@ -42,7 +42,7 @@ module.exports = async (
info( '' );
info( `Creating a new WordPress block in "${ slug }" folder.` );

const { outputTemplates } = blockTemplate;
const { outputTemplates, outputAssets } = blockTemplate;
const view = {
apiVersion,
namespace,
Expand All @@ -67,10 +67,10 @@ module.exports = async (
await Promise.all(
Object.keys( outputTemplates ).map( async ( outputFile ) => {
// Output files can have names that depend on the slug provided.
const outputFilePath = `${ slug }/${ outputFile.replace(
/\$slug/g,
slug
) }`;
const outputFilePath = join(
slug,
outputFile.replace( /\$slug/g, slug )
);
await makeDir( dirname( outputFilePath ) );
writeFile(
outputFilePath,
Expand All @@ -79,6 +79,14 @@ module.exports = async (
} )
);

await Promise.all(
Object.keys( outputAssets ).map( async ( outputFile ) => {
const outputFilePath = join( slug, 'assets', outputFile );
await makeDir( dirname( outputFilePath ) );
writeFile( outputFilePath, outputAssets[ outputFile ] );
} )
);

await initBlockJSON( view );
await initPackageJSON( view );

Expand Down
32 changes: 26 additions & 6 deletions packages/create-block/lib/templates.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,23 @@ const getOutputTemplates = async ( outputTemplatesPath ) => {
);
};

const getOutputAssets = async ( outputAssetsPath ) => {
const outputAssetFiles = await glob( '**/*', {
cwd: outputAssetsPath,
dot: true,
} );
return fromPairs(
await Promise.all(
outputAssetFiles.map( async ( outputAssetFile ) => {
const outputAsset = await readFile(
join( outputAssetsPath, outputAssetFile )
);
return [ outputAssetFile, outputAsset ];
} )
)
);
};

const externalTemplateExists = async ( templateName ) => {
try {
await command( `npm view ${ templateName }` );
Expand All @@ -84,6 +101,7 @@ const getBlockTemplate = async ( templateName ) => {
outputTemplates: await getOutputTemplates(
join( __dirname, 'templates', templateName )
),
outputAssets: {},
};
}
if ( ! ( await externalTemplateExists( templateName ) ) ) {
Expand All @@ -108,19 +126,21 @@ const getBlockTemplate = async ( templateName ) => {
cwd: tempCwd,
} );

const { defaultValues = {}, templatesPath } = require( require.resolve(
templateName,
{
paths: [ tempCwd ],
}
) );
const {
defaultValues = {},
templatesPath,
assetsPath,
} = require( require.resolve( templateName, {
paths: [ tempCwd ],
} ) );
if ( ! isObject( defaultValues ) || ! templatesPath ) {
throw new Error();
}

return {
defaultValues,
outputTemplates: await getOutputTemplates( templatesPath ),
outputAssets: assetsPath ? await getOutputAssets( assetsPath ) : {},
};
} catch ( error ) {
throw new CLIError(
Expand Down