如何让咕task任务将胡须部分渲染为静态HTML [英] how to have grunt task render mustache partials to static HTML

查看:65
本文介绍了如何让咕task任务将胡须部分渲染为静态HTML的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

背景



我一直使用grunt.js和hogan.js任务为我们的内部文档构建静态HTML。我正在学习JavaScript,但我已经完成了足够好的布局和页面任务,但它确实有助于我们的工作流程使hogan任务将胡子部分呈现为HTML,如本例中的示例所示: https://gist.github.com/4132781



当前设置和我想完成的任务



我们所有的胡子部分都位于名为partials的文件夹中。理想情况下,当运行grunt构建时,hogan任务将从partials文件夹中获取任何部分,并将它们插入到HTML引用的任何位置(同样以gist显示)。



我不想要什么



我不想在任务中定义每个部分或任务配置。这是行不通的,我们有大约200个局部区域并在不断增长,所以我们需要让这个任务扫描一个文件夹,并根据文件名或其他内容抓取局部区域。我也不想使用不同的语言或构建工具。我们使用了Jade,一些基于降价的文档构建器,以及其他一些。如果我们能够像所描述的那样得到部分渲染效果,那么我们将会非常棒!

是否有可能实现这个目标?提前感谢您的任何反馈

解决方案

我在要点中看到您的代码,其中一些选项与



以下是我更新您提供的代码以允许呈现部分内容的示例:



< h3> grunt.js

src是您正在构建的可能包含部分内容的页面列表
在这种情况下,components.mustache将位于'docs / components / templates / pages / components.mustache'



将布局选项更新为layout.mustache,用于所有页面(包括components.mustache)



将路径对象添加到具有部分文件夹路径的选项。所有这些部分将被读取和编译并存储在options.partials中,以供稍后在grunt任务中使用。

  module.exports = function(grunt){

'use strict';

//项目配置
grunt.initConfig({
pkg:'< json:package.json>',
meta:{
banner :
'/ ** \ n'+
'*<%= pkg.name%> .js v<%= pkg.version%> by @fat& @ mdo \\ \\ n'+
'*版权<%= grunt.template.today(yyyy)%><%= pkg.author%> \ n'+
'* http ://www.apache.org/licenses/LICENSE-2.0.txt\\\
'+
'* /'
},

//创建HTML文档。胡须文件
hogan:{
生产:{
src:'docs / components / templates / pages / *。mustache',
dest:'docs / components / FILE.html ',
选项:{
标题:'Sellside',
网址:'docs',
setAccount:'NA',
setSiteId:'NA',
布局:'docs / components / templates / layout.mustache',
dev:true,
docs:true,
app:false,
website:false,
paths:{
partials:'docs / components / templates / partials / *。mustache'
}
}
}
}
});

//载入npm任务。
grunt.loadNpmTasks('grunt-contrib');

//加载本地任务。
grunt.loadTasks('tasks');

grunt.registerTask('default','hogan');

};



hogan.js



更新此任务阅读所有partials并编译它们。

帮助程序正在更新,以将'body'partial(这是编译后的页面)添加到options.partials列表中。

然后将options.partials传递给hogan.render方法,以便所有页面都可用。

/ *
*从胡须文件构建HTML
* https://github.com/sellside/ui/ grunt.js
*
* Copyright(c)2012 Sellside
*由Jon Schlinkert撰写
* /

module.exports = function(grunt) {

// Grunt公用程序。
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._
$ b $ //外部依赖
var fs = require('fs'),
hogan = require('hogan');


// ==================================== ======================================
// TASKS
/ / ================================================= =========================
grunt.registerMultiTask('hogan','用hogan.js将胡须文件编译成HTML',函数(){

var data = this.data,
src = grunt.file.expandFiles(this.file.src),
dest = grunt.template.process(data .dest),

//选项在gruntfile中设置
defaults = {
production:false,
docs:false,
title:'Sellside ',
setAccount:'NA',
setSiteId:'NA',
layout:'docs / templates / layout.mustache',
paths:{},
部分:{}
},

选项= _.extend(默认值,this.data.options || {})

!src&& amp ; grunt.warn('Missing src property。')
如果(!src)返回false

!dest&& grunt.warn('Missing dest property')
if(!dest)返回false

var done = this.async()
var srcFiles = file.expandFiles(src)

if(options.paths.partials){

var partials = grunt.file.expandFiles(options.paths.partials);
log.writeln('编译部分...');
partials.forEach(function(filepath){
var filename = _.first(filepath.match(/ [^ \\\\ /:*?<> | \r \\\
] + $ / i))。replace(/\.mustache$/,'');
log.writeln(filename.magenta);

var partial = fs .readFileSync(filepath,'utf8');
options.partials [filename] = hogan.compile(partial);

));
log.writeln();
}

尝试{
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\\\
] + $ / I))代替(/\.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)
})
})

完成()
})

// ======================= ================================================== =
// HELPERS
// ==================================== ======================================
grunt.registerHelper('hogan',函数(src,filename,options,callback){
log.writeln('Compiling'+ filename.magenta);

var page = fs.readFileSync(src,'utf8'),
html = null,
layout = options.layout,
context = {};

context [文件名] ='active';
上下文。 _i = true;
context.production = options.production;
context.docs = options.docs;
context.setAccount = options.setAccount;
context.setSite Id = 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
}
})
};

有一点需要注意,如果您要将数据传递到partials中,您需要将其添加到文件layout.render调用中的上下文对象。



希望这一切都有意义并帮助您。


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

解决方案

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.

这篇关于如何让咕task任务将胡须部分渲染为静态HTML的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆