Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8895231
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 14, 20262026-06-14T23:43:24+00:00 2026-06-14T23:43:24+00:00

Background I’ve been using grunt.js with a hogan.js task to build the static HTML

  • 0

Background

I’ve been using grunt.js with a hogan.js task to build the static HTML for our internal docs. I’m learning JavaScript as I go, but I’ve gotten the task to work well enough for layouts and pages, but it would really help our workflow to have the hogan task render mustache partials to HTML, as in the example in this gist: https://gist.github.com/4132781

Current Setup and what I want to accomplish

All of our mustache partials are in a folder called "partials". Ideally when the grunt build is run, the hogan task will grab any partials from the partials folder and insert them into the HTML wherever they are referenced (also, shown in gist).

What I DON’T want

I don’t want to have to define each partial in the task or task configuration. This won’t work, we have ~200 partials and growing, so we need to have the task scan a folder and grab partials based on either file name or something. I also don’t want to use a different language or build tool. We’ve used Jade, some markdown-based docs builders, a number of others. If we can just get partials to render as described we’ll be in great shape!

Is it possible to accomplish this? Thanks in advance for any feedback

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-14T23:43:26+00:00Added an answer on June 14, 2026 at 11:43 pm

    I was looking at your code in the gist and some of the options don’t match with the filenames you’re referencing.

    Here is my stab at updating the code you provided to allow rendering partials:

    grunt.js

    The src is the list of pages you’re building that might contain partials
    In this case, components.mustache would be located at ‘docs/components/templates/pages/components.mustache’

    Updating the layout option to layout.mustache which is used for all the pages (including components.mustache)

    Adding a paths object to options which has a path to the partials folder. All these partials will be read and compiled and stored in options.partials for later use in the grunt task.

    module.exports = function(grunt) {
    
      'use strict';
    
      // Project configuration
      grunt.initConfig({
        pkg: '<json:package.json>',
        meta: {
          banner:
          '/**\n' +
          '* <%= pkg.name %>.js v<%= pkg.version %> by @fat & @mdo\n' +
          '* Copyright <%= grunt.template.today("yyyy") %> <%= pkg.author %>\n' +
          '* http://www.apache.org/licenses/LICENSE-2.0.txt\n' +
          '*/'
        },
    
        // Build HTML docs from .mustache files
        hogan: {
          production: {
            src: 'docs/components/templates/pages/*.mustache',
            dest: 'docs/components/FILE.html',
            options: {
              title:      'Sellside',
              url:        'docs',
              setAccount: 'NA',
              setSiteId:  'NA',
              layout:     'docs/components/templates/layout.mustache',
              dev:        true,
              docs:       true,
              app:        false,
              website:    false,
              paths: {
                partials: 'docs/components/templates/partials/*.mustache'
              }
            }
          }
        }
      });
    
      // Load npm tasks.
      grunt.loadNpmTasks('grunt-contrib');
    
      // Load local tasks.
      grunt.loadTasks('tasks');
    
      grunt.registerTask('default', 'hogan');
    
    };
    

    hogan.js

    Updating this task to read in all the partials and compile them.

    The helper is being updated to add the ‘body’ partial (which is the compiled page) to the options.partials list.

    The options.partials is then passed into the hogan.render method so all the partials are available to all the pages.

    /*
     * Build HTML from mustache files
     * https://github.com/sellside/ui/grunt.js
     *
     * Copyright (c) 2012 Sellside
     * Authored by Jon Schlinkert
     */
    
    module.exports = function(grunt) {
    
      // Grunt utilities.
      var task   = grunt.task,
        file     = grunt.file,
        utils    = grunt.util,
        log      = grunt.log,
        verbose  = grunt.verbose,
        fail     = grunt.fail,
        option   = grunt.option,
        config   = grunt.config,
        template = grunt.template,
        _        = utils._
    
      // external dependencies
      var fs   = require('fs'),
        hogan  = require('hogan');
    
    
      // ==========================================================================
      // TASKS
      // ==========================================================================
      grunt.registerMultiTask('hogan', 'Compile mustache files to HTML with hogan.js', function() {
    
        var data     = this.data,
          src        = grunt.file.expandFiles(this.file.src),
          dest       = grunt.template.process(data.dest),
    
          // Options are set in gruntfile
          defaults   = {
            production:  false,
            docs:        false,
            title:      'Sellside',
            setAccount: 'NA',
            setSiteId:  'NA',
            layout:     'docs/templates/layout.mustache',
            paths: {},
            partials: {}
          },
    
          options = _.extend(defaults, this.data.options || {})
    
          !src && grunt.warn('Missing src property.')
          if(!src) return false
    
          !dest && grunt.warn('Missing dest property')
          if(!dest) return false
    
        var done         = this.async()
        var srcFiles     = file.expandFiles(src)
    
        if(options.paths.partials) {
    
          var partials = grunt.file.expandFiles(options.paths.partials);
          log.writeln('Compiling Partials...');
          partials.forEach(function(filepath) {
            var filename = _.first(filepath.match(/[^\\\/:*?"<>|\r\n]+$/i)).replace(/\.mustache$/, '');
            log.writeln(filename.magenta);
    
            var partial = fs.readFileSync(filepath, 'utf8');
            options.partials[filename] = hogan.compile(partial);
    
          });
          log.writeln();
    }
    
        try {
          options.layout   = fs.readFileSync(options.layout, 'utf8')
          options.layout   = hogan.compile(options.layout, {
            sectionTags: [{
              o: '_i',
              c: 'i'
            }]
          })
        } catch(err) {
          grunt.warn(err) && done(false)
          return
        }
    
        srcFiles.forEach(function(filepath) {
          var filename = _.first(filepath.match(/[^\\\/:*?"<>|\r\n]+$/i)).replace(/\.mustache$/, '')
    
          grunt.helper('hogan', filepath, filename, options, function(err, result) {
            err && grunt.warn(err) && done(false)
            if(err) return
    
            file.write(dest.replace('FILE', filename), result)
          })
        })
    
        done()
      })
    
      // ==========================================================================
      // HELPERS
      // ==========================================================================
      grunt.registerHelper('hogan', function(src, filename, options, callback) {
        log.writeln('Compiling ' + filename.magenta);
    
        var page                = fs.readFileSync(src, 'utf8'),
            html                = null,
            layout              = options.layout,
            context             = {};
    
            context[filename]   = 'active';
            context._i          = true;
            context.production  = options.production;
            context.docs        = options.docs;
            context.setAccount  = options.setAccount;
            context.setSiteId   = options.setSiteId;
    
        var title               = _.template("<%= page == 'Index' ? site : page + ' · ' + site %>")
        context.title           = title({
          page: _(filename).humanize().replace('css', 'CSS'),
          site: options.title
        })
        try {
          page = hogan.compile(page, {
            sectionTags: [{
              o: '_i',
              c: 'i'
            }]
          })
    
          options.partials.body = page;
          page = layout.render(context, options.partials)
    
          callback(null, page)
        } catch(err) {
          callback(err)
          return
        }
      })
    };
    

    One thing to note, if you’re going to pass data into the partials, you’ll need to add that to the context object in the file layout.render call.

    Hope this all make sense and helps you out.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Background Our build script use Install() and InstallAs() to install a number of .dylib
Background: We're building an application that allows our customers to supply data in a
Background: I'm using the (fantastic) Vim plugin python-mode , which includes the pep8 linter.
Background - I am using paramiko to put files on a bunch of remote
Background : I'm trying to convert some JavaScript code which uses the the Crossfilter
Background: Using unix, codeigniter from localhost. I'd like to run a controllers via a
I am reading a book about Javascript and jQuery and using one of the
Background As CopyLocal=true causes a lot of build slowdowns as projects and solutions grow
Background My employer is progressively shifting our resource intensive ETL and backend processing logic
BACKGROUND I am automating an PowerPoint 2007 via C# I am writing unittests using

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.