3

バックグラウンド

私は内部ドキュメントの静的HTMLを構築するためにhogan.jsタスクでgrunt.jsを使用してきました。私はJavaScriptを学びながら学習していますが、レイアウトとページで十分に機能するタスクを取得しましたが、この要点の例のように、ホーガンタスクで口ひげの部分をHTMLにレンダリングするワークフローは本当に役立ちます:https ://gist.github.com/4132781

現在の設定と達成したいこと

私たちの口ひげの部分はすべて「部分」と呼ばれるフォルダにあります。理想的には、gruntビルドが実行されると、hoganタスクはpartialsフォルダーからパーシャルを取得し、参照されている場所(要点にも示されています)にHTMLに挿入します。

欲しくないもの

タスクまたはタスク構成で各パーシャルを定義する必要はありません。これは機能しません。最大200のパーシャルがあり、成長しているため、タスクでフォルダーをスキャンし、ファイル名などに基づいてパーシャルを取得する必要があります。また、別の言語やビルドツールを使用したくありません。Jade、いくつかのマークダウンベースのドキュメントビルダー、その他の多くを使用しました。説明したようにパーシャルをレンダリングすることができれば、素晴らしい形になります!

これを達成することは可能ですか?フィードバックを事前に感謝します

4

1 に答える 1

5

私は要点であなたのコードを見ていました、そして、いくつかのオプションはあなたが参照しているファイル名と一致しません。

パーシャルのレンダリングを可能にするために提供したコードを更新する際の私の刺し傷は次のとおりです。

grunt.js

srcは、パーシャルを含む可能性のある作成中のページのリストです。この場合、components.mustacheは「docs / components / templates / pages/components.mustache」にあります。

レイアウトオプションを、すべてのページ(components.mustacheを含む)に使用されるlayout.mustacheに更新します

パーシャルフォルダへのパスを持つオプションにパスオブジェクトを追加します。これらのパーシャルはすべて読み取られ、コンパイルされてoptions.partialsに格納され、後でgruntタスクで使用できるようになります。

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

このタスクを更新して、すべてのパーシャルを読み込み、コンパイルします。

ヘルパーは、「body」パーシャル(コンパイルされたページ)をoptions.partialsリストに追加するように更新されています。

次に、options.partialsがhogan.renderメソッドに渡され、すべてのパーシャルがすべてのページで使用できるようになります。

/*
 * 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
    }
  })
};

データをパーシャルに渡す場合は、ファイルlayout.render呼び出しのコンテキストオブジェクトにデータを追加する必要があることに注意してください。

これがすべて理にかなっていて、あなたを助けてくれることを願っています。

于 2012-11-28T03:16:40.607 に答える