npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

vite-plugin-twig-drupal

v1.4.2

Published

Provides a ⚡️ Vite plugin to transform 🌱 Twig into HTML with a 💧 Drupal flavour

Downloads

3,866

Readme

Build status version downloads MIT License PRs Welcome

Watch on GitHub Star on GitHub Tweet

Table of Contents

The problem

You are working with Twig in a styleguide-driven-development process. You are writing isolated components that consist of css, twig and Javascript. You want to be able to use twig to render your components for Storybook. You want fast refresh with Vite. You want Twig embeds, includes and extends to work. You want to use Drupal specific twig features like create_attributes etc.

This solution

The Vite plugin Twig Drupal is a Vite plugin based on Twig JS for compiling Twig-based components into a Javascript function so that they can be used as components with Storybook. It allows you to import twig files into your story as though they are Javascript files.

Comparison to other solutions.

  • Vite plugin twig loader Doesn't handle nested includes/embeds/extends. These are a fairly crucial feature of twig when building a component library as they allow re-use and DRY principles
  • Components library server Requires you to have a running Drupal site. Whilst this ensures your twig output is identical to that of Drupal (because Drupal is doing the rendering), it is a bit more involved to setup. If you're going to use single directory components or a similar Drupal module like UI patterns then this may be a better option for you.

Installation

This module is distributed via npm which is bundled with node and should be installed as one of your project's devDependencies:

npm install --save-dev vite-plugin-twig-drupal

You then need to configure your vite.config.js.

import { defineConfig } from "vite"
import twig from 'vite-plugin-twig-drupal';
import { join } from "node:path"

export default defineConfig({
  plugins: [
    // Other vite plugins.
    twig({
      namespaces: {
        components: join(__dirname, "/path/to/your/components"),
        // Other namespaces as required.
      },
      // Optional if you are using React storybook renderer. The default is 'html' and works with storybook's html
      // renderer.
      // framework: 'react'
      functions: {
        // You can add custom functions - each is a function that is passed the active Twig instance and should call
        // e.g. extendFunction to register a function
        reverse: (twigInstance) => twigInstance.extendFunction("reverse", () => (text) => text.split(' ').reverse().join(' ')),
        // e.g. extendFilter to register a filter
        clean_unique_id: (twigInstance) => twigInstance.extendFilter("clean_unique_id", () => (text) => text.split(' ').reverse().join(' ')),
      },
      globalContext: {
        // Global variables that should be present in all templates.
        active_theme: 'my_super_theme',
        is_front_page: false,
      },
    }),
    // Other vite plugins.
  ],
})

With this config in place you should be able to import twig files into your story files.

Examples

// stories/Button.stories.js

// Button will be a Javascript function that accepts variables for the twig template.
import Button from './button.twig';

// Import stylesheets, this could be a sass or postcss file too.
import './path/to/button.css';
// You may also have JavaScript for the component.
import './path/to/some/javascript/button.js';

export default {
  title: 'Components/Button',
  tags: ['autodocs'],
  argTypes: {
    title: {
      control: { type: 'text' },
    },
    modifier: {
      control: { type: 'select' },
      options: ['primary', 'secondary', 'tertiary'],
    },
  },
  // Just pass along the imported variable.
  component: Button,
};

// Set default variables in the story.
export const Default = {
  args: { title: 'Click me' },
};

export const Primary = {
  args: { title: 'Click me', modifier: 'primary' },
};

// Advanced example.
export const ButtonStrip = {
  name: 'Button group',
  render: () => `
    ${Button({title: 'Button 1', modifier: 'primary'})} 
    ${Button({title: 'Button 2', modifier: 'secondary'})}
  `
}

Usage with React

When adding framework: 'react' to vite.config.js twig files will output React JSX functions that can be used inside a React Storybook instance.

This way Twig components can be rendered alongside React components.

However, you will need to revert to a straight TwigJS function import so you can nest Twig components inside other Twig components. In these instances append ?twig to your component import. This will return a JavaScript function instead of a React component. When nesting Twig components inside React components this is not needed. Nesting React components inside Twig components does not work currently.

import Button from './button.twig';
import OtherComponent from ../other-component.twig?twig

export default {
  title: 'Components/Button',
  tags: ['autodocs'],
  args: {
    // Render by calling the component as a function.
    // You can pass any variables down as an object.
    otherComponent: OtherComponent(),
  },
  component: Button,
};

Issues

🐛 Bugs

Please file an issue for bugs, missing documentation, or unexpected behavior.

See Bugs

💡 Feature Requests

Please file an issue to suggest new features. Vote on feature requests by adding a 👍. This helps maintainers prioritize what to work on.

See Feature Requests

❓ Questions

For questions related to using the library, please visit a support community instead of filing an issue on GitHub.

LICENSE

MIT