Search code examples
javascripthandlebars.jsassemble

Creating complex data models in yaml front matter in Assemble


Assemble front matter YAML supports dynamic data model creation at the top of a Handlebar page with this syntax

 ---
 myModel : { aFile : <%= fileName %>}
 ---

<div>
 {{myModel.aFile.someProperty}}
</div>

where fileName is some json file. Is it possible to manipulate myModel in YAML, after creating it, and before it is passed to rendering. This code doesn't work, but I'd like to do something like :

 ---
 myModel : { aFile : <%= fileName %>}
 myModel
    aFile
      someProperty : I was set in header 
 ---

Failing that, how else could one dynamically generate data in the header? Could I call a custom helper and pass its output to a variable, once again this doesn't work but hypothetically :

 ---
 myModel : { data: <%= someHelper('fileName') %> }
 ---

Solution

  • You can certainly do this with a customized Handlebars helper that formats the data however you want.

    Gruntfile.js

    assemble: {
        mySite: {
            options: {
                helpers: ['source/helpers/**/*.js']
    

    source/helpers/importJSON.js

    (function() {
        "use strict";
    
        var _ = require("lodash");
        var fs = require("fs");
    
        module.exports.register = function(Handlebars, options) {
            Handlebars.registerHelper("importJSON", function(fileSpec, options) {
                var customData = JSON.parse(fs.readFileSync(fileSpec, "utf8"));
    
                // Do anything to your data here
                if (customData.color === "blue") {
                    customData.color = "yellow";
                }
    
                _.extend(this, customData);
                return "";
            });
        };
    
    }).call(this);
    

    source/templates/somePage.hbs

    ---
    {{importJSON "./source/data/favorite.json"}}
    {{log color}}
    <html>
    <body>
        <h1>Some Page</h1>
    </body>
    </html>