Search code examples
jsongulphandlebars.jsassemble

Parsing json data in to Assemble / Handlebar partials via Gulp


I'm working on a project that uses Assemble to statically build up modules and output them to a dist folder. Without json, this works as expected, however I want to optimize the process a little so that each Module has its own *.json file that acts as a manifest which is then injected and used with Handlebars to place those variables in to the partial/Module.

Looking at examples online, they all mention parsing data as an option to assemble, but even though I'm doing this it still isn't working. Am I doing something wrong?

This is my assemble task:

var gulp = require('gulp'),
    assemble = require('assemble'),
    rename = require('gulp-rename'),
    path = require('path'),
    fs = require('fs'),
    beautify = require('gulp-html-prettify'),
    gulpif = require('gulp-if'),
    utils = require(path.join(__dirname, '../lib/utils')),
    config = require(utils.getConfig()),
    app;

/**
 * Helper function to set our module key based on the filename.
 */
function fileNameAsModuleName(key, view) {
    var v = view ? view.basename : path.basename(key);
    v = v.split('/').pop().replace('.html', '').replace('.hbs', '');
    return v;
}

gulp.task('assemble:files', function() {

    app = assemble({
        data: './src/views/partials/**/*.json'
    });

    console.log(app.options);

    /**
     * Register all of our compiled component templates as partials
     * so we can render them all on the page.
     */
    app.create('pages', { viewType: 'layout', renameKey: fileNameAsModuleName });
    app.create('partials', { viewType: 'partial', renameKey: fileNameAsModuleName });
    app.create('styleguide', { viewType: 'partial', renameKey: fileNameAsModuleName });

    app.pages('./src/views/pages/*.html');
    app.partials('./src/views/partials/**/*.html');
    app.styleguide('./src/views/styleguide/index.html');

    app.toStream('styleguide')
        .pipe(app.renderFile())
        .pipe(rename('index.html'))
        .pipe(app.dest('./dist'));

    app.toStream('pages')
        .pipe(app.renderFile())
        .pipe(app.dest('./dist/pages'));
});

gulp.task('server:assemble', ['assemble:files']);

Following the official documentation, I should have context by the name of the html/hbs file.

foot.json:

{
    "script ": "/scripts/app.js"
}

foot.html

<script src="{{foot.script}}"></script>

But sadly if I reference the variable script, or give it a context/namespace then it still returns nothing in the output html. Do I need to parse data directly to 'app.partials'?


Solution

  • Instead of passing data as an option to the assemble constructor... use the .data method on the app instance:

    // from
    app = assemble({
        data: './src/views/partials/**/*.json'
    });
    
    // to
    app = assemble();
    app.data('./src/views/partials/**/*.json');
    

    If you found the other pattern in documentation, please point that out so we can get it updated. We're currently working on updating the documentation and the website. As of right now, the website only refers to grunt-assemble.