Skip to content

Getting Started

Installation

bash
npm install --save-dev @pdrittenhouse/storybook-addon-twig-wordpress

Peer 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 via webpackFinal but not recommended)
  • Pattern templates follow the _name.tpl.twig naming convention by default (configurable via the templateGlob option)
  • 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 6006

What the addon does

When Storybook starts, the addon's Vite plugin:

  1. Walks all namespace subdirectories under patternsRoot and collects every _*.tpl.twig file
  2. Reads each file's contents and builds a registry mapping namespace keys to template strings (e.g. @atoms/button/_button.tpl.twig → "...")
  3. If extraPatternRoots are configured, merges them in order — later roots override earlier keys (last entry wins)
  4. Exposes the registry as the virtual module virtual:twig-registry
  5. Parses scssVariablesPath and exposes it as virtual: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

Released under the MIT License.