使用Grunt从单个Jade模板创建多个HTML文件
Creating multiple HTML files from a single Jade template with Grunt
我希望使用Grunt从单个Jade模板创建多个HTML文件。
我是这样做的:
- 从外部文件抓取JSON数据
- 遍历该对象
- 为JSON对象中的每个值创建grunt配置任务
下面是我的代码:
neighborhoods = grunt.file.readJSON('data/neighborhoods.json');
for(var i = 0; i < Object.keys(neighborhoods).length; i++) {
var neighborhood = {
"title" : Object.keys(neighborhoods)[i],
"data" : neighborhoods[Object.keys(neighborhoods)[i]]
};
grunt.config(['jade', neighborhood.title], {
options: {
data: function() {
return {
neighborhoods: neighborhood.data
}
}
},
files: {
"build/neighborhoods/<%= neighborhood.title %>.html": "layouts/neighborhood.jade"
}
});
}
我遇到的问题是这个
Running "jade:Art Museum" (jade) task
Warning: An error occurred while processing a template (Cannot read property 'title' of undefined). Use --force to continue.
如果我使文件名为字符串,它运行良好,但显然创建具有相同文件名的所有文件,因此只创建一个文件。我需要将文件名设置为动态
我在这里找到了解决方案:
在Grunt中使用全局变量设置构建输出路径
问题是模块在这些全局变量被设置之前导出,所以它们在initConfig()任务中定义的后续任务中都是未定义的。
这个成功了!
var neighborhoods = grunt.file.readJSON('data/neighborhoods.json');
for(var i = 0; i < Object.keys(neighborhoods).length; i++) {
var neighborhood = {
"title" : Object.keys(neighborhoods)[i],
"data" : neighborhoods[Object.keys(neighborhoods)[i]]
};
/*
* DEFINE VALUE AS GRUNT OPTION
*/
grunt.option('neighborhood_title', neighborhood.title);
grunt.config(['jade', neighborhood.title], {
options: {
data: function() {
return {
neighborhoods: neighborhood.data,
neighborhood_title: neighborhood.title
}
}
},
/*
* OUTPUT GRUNT OPTION AS FILENAME
*/
files: {
"build/neighborhoods/<%= grunt.option('neighborhood_title') %>.html": "layouts/neighborhood.jade"
}
});
}
这会产生期望的输出:
Running "jade:East Passyunk" (jade) task
File build/neighborhoods/Society Hill.html created.
Running "jade:Fishtown" (jade) task
File build/neighborhoods/Society Hill.html created.
Running "jade:Graduate Hospital" (jade) task
File build/neighborhoods/Society Hill.html created.
Running "jade:Midtown Village" (jade) task
File build/neighborhoods/Society Hill.html created.
Running "jade:Northern Liberties" (jade) task
File build/neighborhoods/Society Hill.html created.
...
我知道这是一个旧的帖子,但我一直回到这里,同时试图解决类似的问题。我想使用for循环从单个jade模板文件输出多个html文件。
我遇到的两个问题是设置输出文件名(javascript对象字面值KEY),并确保内联javascript函数立即运行,以便循环变量可用。
这是我的完整源代码与注释。我希望这对其他偶然看到这篇文章的人有用。
Gruntfile.js:
module.exports = function(grunt) {
// Create basic grunt config (e.g. watch files)
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
watch: {
grunt: { files: ['Gruntfile.js'] },
jade: {
files: 'src/*.jade',
tasks: ['jade']
}
}
});
// Load json to populate jade templates and build loop
var json = grunt.file.readJSON('test.json');
for(var i = 0; i < json.length; i++) {
var obj = json[i];
// For each json item create a new jade task with a custom 'target' name.
// Because a custom target is provided don't nest options/data/file parameters
// in another target like 'compile' as grunt wont't be able to find them
// Make sure that functions are called using immediate invocation or the variables will be lost
// http://stackoverflow.com/questions/939386/immediate-function-invocation-syntax
grunt.config(['jade', obj.filename], {
options: {
// Pass data to the jade template
data: (function(dest, src) {
return {
myJadeName: obj.myname,
from: src,
to: dest
};
}()) // <-- n.b. using() for immediate invocation
},
// Add files using custom function
files: (function() {
var files = {};
files['build/' + obj.filename + '.html'] = 'src/index.jade';
return files;
}()) // <-- n.b. using () for immediate invocation
});
}
grunt.loadNpmTasks('grunt-contrib-jade');
grunt.loadNpmTasks('grunt-contrib-watch');
// Register all the jade tasks using top level 'jade' task
// You can also run subtasks using the target name e.g. 'jade:cats'
grunt.registerTask('default', ['jade', 'watch']);
};
src/index.jade:
doctype html
html(lang="en")
head
title= pageTitle
script(type='text/javascript').
if (foo) {
bar(1 + 5)
}
body
h1 #{myJadeName} - node template engine
#container.col
p.
Jade is a terse and simple
templating language with a
strong focus on performance
and powerful features.
test.json:
[{
"id" : "1",
"filename" : "cats",
"tid" : "2016-01-01 23:35",
"myname": "Cat Lady"
},
{
"id" : "2",
"filename" : "dogs",
"tid" : "2016-01-01 23:45",
"myname": "Dog Man"
}]
运行'grunt'后,输出应该是:
build/cats.html
build/dogs.html
遇到了一个类似的要求,我正在工作的项目,但不能得到这个工作。我一直只生成一个文件,因为grunt选项对所有任务具有相同的值(最后一个值)。所以我最终使用<%= grunt.task.current.target %>
作为文件名在你的情况下,它将与neighborhood.title
相同
相关文章:
- 从Javascript和Php变量创建Html模板文档
- 为非列表项目创建HTML实时搜索
- 使用javascript动态创建html内容/元素
- 如何使用jQuery动态创建HTML输入
- 在 JQUERY 中创建 HTML 后,Jquery 方法不起作用
- 使用HTML标记中的JS变量在Javascript中动态创建HTML
- 如何使用jQuery和乘法行和列创建HTML表
- MVC 4:使用 JQUERY 和 PartViewResult 动态创建 HTML 文本框.如果代码是动态添加的,如何
- 如何将函数绑定到使用链接函数创建 HTML 的角度指令
- 我需要使用AngularJS从JSON文件创建HTML元素
- 从Ajax Arraybuffer响应类型创建HTML画布
- 创建HTML对象的Javascript与创建HTML字符串的比较
- 在动态创建html元素之后,是否可以触发事件
- 如何在动态创建html时实现分层标题组织
- 如何从输入到url的路径创建html文件
- 从sql server中用javascript创建HTML表
- 如何在表单中创建html元素,而无需重新加载页面
- 做全栈JavaScript框架在客户端或服务器上创建HTML
- 使用JQuery创建HTML父标记
- 在服务器端创建html元素VS将数据作为JSON获取,并使用javascript创建标签