как заставить задачу grunt отображать части усов в статический HTML

Фон

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

Текущая настройка и то, что я хочу достичь

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

Чего я НЕ хочу

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

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


person jonschlinkert    schedule 23.11.2012    source источник
comment
мы используем для этого ассемблер   -  person jonschlinkert    schedule 20.08.2013


Ответы (1)


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

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

grunt.js

Src - это список создаваемых вами страниц, которые могут содержать частичные файлы. В этом случае components.mustache будет находиться в 'docs / components / templates / pages / components.mustache'.

Обновление параметра макета до layout.mustache, который используется для всех страниц (включая components.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.

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

person doowb    schedule 28.11.2012
comment
классно! благодарю вас! это работает так, как я хотел, и это именно то, чего я хотел добиться. - person jonschlinkert; 28.11.2012