Getting Started
Installation
bash
npm install --save-dev @pdrittenhouse/storybook-addon-twig-wordpressPeer dependencies: storybook ^8.0.0 || ^10.0.0 and @storybook/html ^8.0.0 || ^10.0.0 must already be installed.
Prerequisites
- Storybook 8 or 10 with
@storybook/html-vite(Vite builder is required; webpack support is available viawebpackFinalbut not recommended) - Pattern templates follow the
_name.tpl.twignaming convention by default (configurable via thetemplateGloboption) - Node.js 18+
Minimal setup
1. Configure the addon in main.ts
ts
// .storybook/main.ts
import path from 'path';
import { fileURLToPath } from 'url';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const ROOT = path.resolve(__dirname, '..');
export default {
framework: {
name: '@storybook/html-vite',
options: {},
},
addons: [
{
name: '@pdrittenhouse/storybook-addon-twig-wordpress',
options: {
patternsRoot: path.join(ROOT, 'src/patterns'),
namespaces: {
atoms: 'atoms',
molecules: 'molecules',
organisms: 'organisms',
},
// Optional: expose compiled SCSS variables as sass_data in every story
scssVariablesPath: path.join(ROOT, 'dist/scss-variables.json'),
// Optional: forward global SCSS variables to pattern stylesheets
sassAdditionalData: `@use "${path.join(ROOT, 'src/patterns/_variables.scss').replace(/\\/g, '/')}" as *;`,
},
},
],
stories: ['../src/patterns/**/*.stories.ts'],
};2. Write your first story
ts
// src/patterns/atoms/button/button.stories.ts
import type { Meta, StoryObj } from '@storybook/html';
import { definePattern } from '@pdrittenhouse/storybook-addon-twig-wordpress';
export default {
title: 'Atoms/Button',
...definePattern('@atoms/button/_button.tpl.twig', {
button_text: 'Click me',
button_color: 'primary',
button_size: '',
}),
} satisfies Meta;
export const Default: StoryObj = {};
export const Secondary: StoryObj = {
args: { button_color: 'secondary' },
};
export const Large: StoryObj = {
args: { button_size: 'lg' },
};3. Start Storybook
bash
npx storybook dev -p 6006What the addon does
When Storybook starts, the addon's Vite plugin:
- Walks all namespace subdirectories under
patternsRootand collects every_*.tpl.twigfile - Reads each file's contents and builds a registry mapping namespace keys to template strings (e.g.
@atoms/button/_button.tpl.twig → "...") - If
extraPatternRootsare configured, merges them in order — later roots override earlier keys (last entry wins) - Exposes the registry as the virtual module
virtual:twig-registry - Parses
scssVariablesPathand exposes it asvirtual:sass-data
At runtime, preview.ts imports both virtual modules, registers all templates with twig.js, applies shims, and injects a WordPress context mock into every story's args.
Pattern file structure
The addon expects patterns organized into namespace subdirectories under patternsRoot:
src/patterns/
├── atoms/ (@atoms)
│ └── button/
│ ├── _button.tpl.twig ← registered as @atoms/button/_button.tpl.twig
│ ├── _button.scss
│ ├── index.js
│ └── button.stories.ts ← Storybook story
├── molecules/ (@molecules)
└── organisms/ (@organisms)Only _*.tpl.twig files (leading underscore) are registered. Top-level .twig demo wrappers are intentionally excluded.
Next steps
- Configuration reference — all
AddonOptionsfields - Pattern Override Cascade — parent/child theme override setup
- twig.js compatibility — shims and known limitations