Skip to content

Commit

Permalink
feat: add generator for reusable patterns (#96)
Browse files Browse the repository at this point in the history
  • Loading branch information
dustin-jw authored Oct 20, 2023
1 parent cc9e0ff commit 0b1078c
Show file tree
Hide file tree
Showing 4 changed files with 145 additions and 0 deletions.
14 changes: 14 additions & 0 deletions docs/generators.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,17 @@ The following files will be created based on your input:
- `src/php/views/<page-template-name>.twig`

[Page Template documentation](https://developer.wordpress.org/themes/template-files-section/page-template-files/)

## Reusable Pattern

The generator for reusable patterns will prompt you for a name, description, and categories for the pattern, then create a script to register a reusable pattern with metadata based on your inputs and instructions for how to create the markup for the pattern.

```sh
npm run generate:pattern
```

The following file will be created based on your input:

- `src/php/patterns/<pattern-name>.php`

[Reusable pattern (a.k.a. Block pattern) documentation](https://developer.wordpress.org/themes/advanced-topics/block-patterns/)
130 changes: 130 additions & 0 deletions generators/pattern.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
const { writeFileSync, readFileSync } = require('fs');
const { join } = require('path');
const prompts = require('prompts');

const getPatternScript = ({ patternSlug, themeSlug, description, categories }) => `<?php
/**
* Title: ${description}
* Slug: ${themeSlug}/${patternSlug}
* Categories: ${categories.join(', ')}
*/
?>
<!-- wp:paragraph -->
<p>Replace this sample content with markup for a pattern.</p>
<!-- /wp:paragraph -->
<!-- wp:list -->
<ul><!-- wp:list-item -->
<li>Arrange whichever blocks you need to form the pattern in the WordPress editor</li>
<!-- /wp:list-item -->
<!-- wp:list-item -->
<li>Select all blocks (or the outermost block), the click the kebab menu > Copy (or Copy blocks)</li>
<!-- /wp:list-item -->
<!-- wp:list-item -->
<li>Paste the resulting content in ${patternSlug}.php</li>
<!-- /wp:list-item --></ul>
<!-- /wp:list -->
`;

const getDetails = async () => {
const questions = [
{
type: 'text',
name: 'name',
message: 'What should the pattern be called? Content editors will search for this name.',
},
{
type: 'text',
name: 'description',
message:
'Please describe this pattern. This will help content editors understand what the pattern should be used for.',
},
{
type: 'multiselect',
name: 'categories',
message:
'Which pattern categories should this pattern be included in? This will help content editors find the pattern.',
hint: 'Space to select. Return to submit',
instructions: false,
choices: [
{
title: 'My patterns (recommended)',
value: 'custom',
selected: true,
},
{
title: 'Featured',
value: 'featured',
selected: false,
},
{
title: 'Posts',
value: 'posts',
selected: false,
},
{
title: 'Text',
value: 'text',
selected: false,
},
{
title: 'Gallery',
value: 'gallery',
selected: false,
},
{
title: 'Call to Action',
value: 'call-to-action',
selected: false,
},
{
title: 'Banners',
value: 'banner',
selected: false,
},
{
title: 'Headers',
value: 'header',
selected: false,
},
{
title: 'Footers',
value: 'footer',
selected: false,
},
],
},
];

const response = await prompts(questions);

return response;
};

const getFirstGroup = (regexp, str) =>
Array.from(str.matchAll(regexp), (match) => match[1])?.[0] ?? 'theme-slug';

const getThemeSlug = () => {
const themeDefinitionPath = join(__dirname, '../src/php/style.css');
const themeDefinition = readFileSync(themeDefinitionPath, { encoding: 'utf-8' });

const themeSlug = getFirstGroup(/Theme Name:\s(.*)/gm, themeDefinition);

return themeSlug.toLowerCase().replace(/\W/g, '-');
};

const generatePattern = async () => {
const themeSlug = getThemeSlug();
const { name, description, categories } = await getDetails();
const patternSlug = name.toLowerCase().replace(/\W/g, '-');
const templateParams = { patternSlug, themeSlug, description, categories };

const patternScript = getPatternScript(templateParams);
const patternScriptPath = join(__dirname, '../src/php/patterns', `${patternSlug}.php`);
writeFileSync(patternScriptPath, patternScript, 'utf-8');
console.log(`Created ${patternScriptPath}`);
};

generatePattern();
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
"import-db": "./scripts/import-db.sh",
"preimport-db": "npm run backup-db",
"generate:page-template": "node ./generators/page-template.js",
"generate:pattern": "node ./generators/pattern.js",
"generate:post-type": "node ./generators/post-type.js",
"generate:shortcode": "node ./generators/shortcode.js",
"generate:taxonomy": "node ./generators/taxonomy.js",
Expand Down
Empty file added src/php/patterns/.gitkeep
Empty file.

0 comments on commit 0b1078c

Please sign in to comment.