как сделать grunt task рендерить усы партиалов в статический HTML


Фон

Я использую grunt.js с Хоганом.задача js построить статический HTML для наших внутренних документов. Я изучаю JavaScript по ходу, но я получил задачу, чтобы работать достаточно хорошо для макетов и страниц, но это действительно поможет нашему рабочему процессу, чтобы задача hogan визуализировала частичные усы в HTML, как в Примере в этом gist: https://gist.github.com/4132781

Текущая настройка и то, что я хочу выполнить

Все наши партиалы усов находятся в папка называется "partials". В идеале, когда сборка grunt запущена, задача hogan захватит любые партиалы из папки partialsи вставит их в HTML, где бы они ни были указаны (также, как показано в gist).

Чего я не хочу

Я не хочу определять каждую частицу в задаче или конфигурации задачи. Это не сработает, у нас есть ~200 партиалов и растет, поэтому мы должны иметь задачу сканировать папку и захватить партиалы на основе имени файла или что-то еще. Я тоже не хочу. использовать другой язык или инструмент сборки. Мы использовали Jade, некоторые основывающиеся на markdown docs builders, ряд других. Если мы сможем просто заставить партиалов визуализировать, как описано, мы будем в отличной форме!

Возможно ли это сделать? Заранее спасибо за любую обратную связь

1 3

1 ответ:

Я смотрел на ваш код в gist, и некоторые параметры не совпадают с именами файлов, на которые вы ссылаетесь.

Вот мой удар по обновлению кода, который вы предоставили, чтобы разрешить рендеринг партиалов:

Ворчание.js

Src-это список создаваемых страниц, которые могут содержать партиалы В данном случае компоненты.усе будет находится в документы/компонентов/шаблонов/страниц/элементов.усы "

Обновление вариант компоновки макета.усы, которые используются для все страницы (включая компоненты.усы)

Добавление объекта paths в options, который имеет путь к папке partials. Все эти партиалы будут считаны, скомпилированы и сохранены в опциях.фрагментов для последующего использования в тяжелую задачу.

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');

};

Хоган.js

Обновление этой задачи для чтения всех партиалов и их компиляции.

Помощник обновляется, чтобы добавить часть "body" (которая является скомпилированной страницей)к параметрам.список партиалов.

В опции.партиалы затем передаются в Хоган.метод визуализации, так что все партиалы доступны для всех страниц.

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

Обратите внимание, что если вы собираетесь передавать данные в партиалы, вам нужно будет добавить их в объект context в макете файла.вызов рендера.

Надеюсь, что все это имеет смысл и поможет вам.