Giter Club home page Giter Club logo

grunt-twig-render's Introduction

grunt-twig-render

Build Status NPM version

Render twig templates

Getting Started

This plugin requires Grunt ~0.4.5

If you haven't used Grunt before, be sure to check out the Getting Started guide, as it explains how to create a Gruntfile as well as install and use Grunt plugins. Once you're familiar with that process, you may install this plugin with this command:

npm install grunt-twig-render --save-dev

Once the plugin has been installed, it may be enabled inside your Gruntfile with this line of JavaScript:

grunt.loadNpmTasks('grunt-twig-render');

The "twigRender" task

Overview

In your project's Gruntfile, add a section named twigRender to the data object passed into grunt.initConfig().

grunt.initConfig({
  twigRender: {
    options: {
      // Task-specific options go here.
    },
    your_target: {
      options: {
        // Target specific options go here
      },
      files : [
        {
          data: // Path to JSON, JSON5 or YAML file, or POJO, or Array of filepaths and POJO
          template: // Path to template file
          dest: // Path to output destination here
        }
      ]
    },
  },
});

You can also use Grunt built-in files syntax for more dynamic lists. In that case, one of data or template must be specified, the other one will use the dynamic src property.

Note: The files parameter must be an array, and must conform to the format specified above. Each object in the file array represents one rendered template.

Examples:

files: [
  {
    data: "path/to/data/file.json",
    template: "path/to/template.twig",
    dest: "file/to/output.html"
  }
]
files: [
  {
    data: { 
      greeting: "Hello",
      target: "world"
    },
    template: "path/to/template.twig",
    dest: "file/to/output.html"
  }
]

Compile all your templates, with data from a central data file:

grunt.initConfig({
  twigRender: {
    your_target: {
      files : [
        {
          data: 'path/to/datafile.json',
          expand: true,
          cwd: 'path/to/templates/',
          src: ['**/*.twig', '!**/_*.twig'], // Match twig templates but not partials
          dest: 'path/to/output/',
          ext: '.html'   // index.twig + datafile.json => index.html
        }
      ]
    },
  },
});

Compile a list of posts, same template but different data files:

grunt.initConfig({
  twigRender: {
    your_target: {
      files : [
        {
          template: 'path/to/template.twig',
          expand: true,
          cwd: 'path/to/data/',
          src: ['post*.json'], // post1.json, post2.json,...
          dest: 'path/to/output/',
          ext: '.html'   // post1.json + template.twig => post1.html
        }
      ]
    },
  },
});

Data parameter

The data parameter accepts multiple formats, here is a detailed description of each.

filename (string): JSON, JSON5 or YAML

JSON file should end in .json, YAML in .yml.

JSON5 is an extension to standard JSON, allowing (among other things) comments and multi-line strings. This is an optional format, to enable it you need to install JSON5:

npm install json5

Then simply set data to the path of a json5 file (ending in .json or .json5).

Javascript object

Used as is.

Array

Each element of the array can be any of the accepted format, results are merged. In case of conflicts, last data in the array has priority.

dataPath

An optional dataPath string can be supplied, in dot notation format. If supplied, renderer will look for it in the loaded data and pass it as dataPath property to the template. This lets you call the same template with different parts of the data tree.

files: [
  {
    data: {
      post: {
        title: "a new post",
        content: "about life"
        info: {
          published: "2014/09/12",
          size: 1234,
          author: "John Doe"
        }
      }
    }
    dataPath: "post.info",
  },

Then in template post.twig use {{dataPath.published}} directly

Multiple destinations

If the data parameter results in an array (either through dataPath or as file containing a Javascript array), then multiple destination files are generated. Their names are the destination parameter with '_(number)' appended to the filename.

For example:

data.json
{
  "posts": [
    {
      "title": "first post",
      "content": "Lorem ipsum dolor sit amet, consectetur adipisicing elit."
    },
    {
      "title": "another post",
      "content": "Fugiat enim, at sit natus temporibus maxime repudiandae."
    }
  ]
}
one_post.twig
<h1>{{dataPath.title}}</h1>
<p>{{dataPath.content}}</p>
Gruntfile
grunt.initConfig({
  twigRender: {
    your_target: {
      files : [
        {
          data: "path/to/data/data.json",
          dataPath: "posts",
          template: "path/to/one_post.twig",
          dest: "file/to/post.html"
        }
      ]
    },
  },
});
Files generated
post_0.html
post_1.html

Flattening

If the data parameter results in a tree (that is, an array containing some arrays), you can use the flatten property to reduce this into a list:

#####data.json

{
  "menu": [
    {"label": "action1"},
    {"label": "action2"},
    {
      "label": "sub-menu",
      "actions": [
        {"label": "action3"},
        {"label": "action4"}
      ]
    }
  ]
}

#####Gruntfile

files: [
  {
    data: "data.json",
    dataPath: "menu",
    flatten: "actions"
    template: "myTemplate.twig",
    dest: "myDest.html"
  },

Will result in 4 files (myDest_0-3.html)

Options

options.cache

Type: Boolean
Default value: false

Indicates if Twig should use a template cache or read template file every time. Default is set to false to enable template file watch and recompilation. Set it to true if you need to generate lots of files with an identical template.

options.extensions

Type: Array
Default value: []

Can be an array of functions that extend TwigJS.

Example 1: Filter Extension
options:
{
  extensions:
  [
  
    // Usage: {{ [1, 2, 3]|fooJoin(' | ') }}
    // Output: 1 | 2 | 3

    function(Twig)
    {
      Twig.exports.extendFilter( "fooJoin", function(value, params)
      {
        if (value === undefined || value === null)
        {
          return;
        }

        var join_str = "",
            output = [],
            keyset = null;

        if (params && params[0])
        {
          join_str = params[0];
        }
              
        if (value instanceof Array)
        {
          output = value;
        }
        else
        {
          keyset = value._keys || Object.keys(value);
                  
          Twig.forEach(keyset, function(key)
          {
            if (key === "_keys")
            {
              return; // Ignore the _keys property
            }
                    
            if (value.hasOwnProperty(key))
            {
              output.push(value[key]);
            }
          });
        }
              
        return output.join(join_str);
      });
    }
            
  ]
}
Example 2: Function Extension
options:
{
  extensions:
  [
  
    // Usage:
    //   {% for i in 1..3 %}
    //   {{ fooCycle(['odd', 'even'], i) }}
    //   {% endfor %}
    
    // Output:
    //   even
    //   odd
    //   even

    function(Twig)
    {
      Twig.exports.extendFunction( "fooCycle", function(arr, i)
      {
        var pos = i % arr.length;
        return arr[pos];
      });
    }
            
  ]
}
Example 3: Tag Extension
options:
{
  extensions:
  [
  
    // Usage:
    //   {% fooSpaceless %}<div>
    //   <b>b</b>   <i>i</i>
    //   </div>{% endFooSpaceless %}
    
    // Output:
    //   <div><b>b</b><i>i</i></div>
    

    function(Twig)
    {
      Twig.exports.extendTag(
      {
        type: "fooSpaceless",
        regex: /^fooSpaceless$/,
        next: [
          "endFooSpaceless"
        ],
        open: true,

        // Parse the html and return it without any spaces between tags
        parse: function (token, context, chain)
        {
          // Parse the output without any filter
          var unfiltered = Twig.parse.apply(this, [token.output, context]),

          // A regular expression to find closing and opening tags with spaces between them
          rBetweenTagSpaces = />\s+</g,
                  
          // Replace all space between closing and opening html tags
          output = unfiltered.replace(rBetweenTagSpaces,'><').trim();

          return {
            chain: chain,
            output: output
          };
        }
      });
    },

    function(Twig)
    {
      Twig.exports.extendTag(
      {
        type: "endFooSpaceless",
        regex: /^endFooSpaceless$/,
        next: [ ],
        open: false
      });
    }
            
  ]
}
Example 4: Change TwigJS Settings via an Extension
options:
{
  extensions:
  [

    function(Twig)
    {
      // Although it might not be obvious, you have access to the Twig instance within this function
      // and can configure TwigJS as you like

      // disables caching
      Twig.cache = false;
    }

  ]
}

Release History

1.7.0

  • added cache option to enable/disable Twig caching (needed for livereload).

1.6.0

  • added flatten option to flatten data lists for multi-files generation.

1.5.0

  • task renamed to twigRender (was twig_render), to comply with Javascript conventions and make jshint happy in client codes.

1.4.1

  • dataPath returns full data object with additional dataPath property, instead of just the data pointed to (allows template to access full context).

1.4.0

  • dataPath parameter, to load sub-part of a data structure.
  • data arrays to generate multiple destinations.

1.3.0

  • Use src for data or template, allowing globbing and more
  • Allow use of JSON5, if library is present (optional).

1.2.0

  • Allowing data to be an array of strings/objects.

1.1.0

  • Added support for YAML data files.

1.0.1

  • Added debug output when the target file has been written.

1.0.0

  • Rechecked code. Seems to be fine โ€“ releasing version 1.0.0.

0.3.1

  • Updated version string.

0.3.0

  • Added option to extend TwigJS functionality (filters, functions, tags).

0.2.0

  • Added basic tests.

0.1.0

  • Defined twigRender task.

grunt-twig-render's People

Contributors

benib avatar stefanullinger avatar xavierpriour avatar zizaco avatar

Stargazers

 avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.