Whenever we talk about building a web application, we need to talk about language preprocessors (transforming source code written in a particular language to target code in a native language). Often you’ll find yourself using languages that aren’t natively supported by web browsers because they help you wrap away repetitive work by providing features not available in plain HTML (e.g. Jade), CSS (e.g. Sass) and JavaScript (e.g. CoffeeScript).
每当我们谈论构建Web应用程序时,我们都需要谈论语言预处理器(将以特定语言编写的源代码转换为以本地语言为目标的代码)。 通常,您会发现自己使用的是网络浏览器本身不支持的语言,因为它们通过提供纯HTML(例如Jade),CSS(例如Sass)和JavaScript(例如CoffeeScript)不提供的功能来帮助您打包重复性工作。
An HTML template engine is a preprocessor that gives us the ability to write dynamic and reusable HTML documents that follows the (DRY) principle of application design.
HTML 模板引擎是一个预处理器,它使我们能够遵循应用程序设计的( DRY )原理编写动态且可重复使用HTML文档。
Jade is an open source HTML templating language for Node.js (server-side JavaScript). Jade is totally free to use and provides fast, easy, and fun HTML. It is heavily influenced by Haml, and it was originally created in Node as a module. It typically includes features common to most high-level programming languages, with an emphasis on processing plain text.
Jade是Node.js(服务器端JavaScript)的开源HTML模板语言。 Jade完全免费使用,并提供快速,简便和有趣HTML。 它受Haml的影响很大,它最初是在Node中作为模块创建的。 它通常包括大多数高级编程语言所共有的功能,并着重于处理纯文本。
When using modern CSS frameworks like Bootstrap and Foundation, most of the development becomes entirely about producing HTML, which brings out the power of Jade. Once you start using it, it’ll become an indispensable tool for you.
当使用现代CSS框架(如Bootstrap和Foundation)时,大部分开发工作完全是关于产生HTML的,这产生了Jade的强大功能。 一旦开始使用它,它将成为您不可缺少的工具。
In this tutorial I am going to introduce how to accelerate HTML production and inject plain data with Jade features in conjunction with Grunt.
在本教程中,我将介绍如何加快HTML的产生以及结合Grunt使用Jade功能注入纯数据。
Our toolset for this tutorial will include:
本教程的工具集将包括:
Jade 玉 Grunt 咕unt声 NodeJS 节点JSHere are the steps for installing Node.js, Jade, and the Grunt command-line interface (CLI). If you already have these installed, you can skip down to the next section in the tutorial.
这是安装Node.js,Jade和Grunt命令行界面(CLI)的步骤。 如果已经安装了这些工具,则可以跳至教程的下一部分。
Go to nodejs.org, and click on the “Install” button to download the latest version of node. Execute the downloaded file and follow the installation instructions.
转到nodejs.org ,然后单击“安装”按钮以下载最新版本的节点。 执行下载的文件,然后按照安装说明进行操作。
npm (Node Package Manager) will come bundled with Node, and can be used via the terminal. Open your terminal and execute npm init in the project directory. Then follow the instructions to create package.json.
npm(Node Package Manager)将与Node捆绑在一起,并且可以通过终端使用。 打开终端并在项目目录中执行npm init 。 然后按照说明创建package.json 。
To install Grunt, enter npm install --save-dev grunt
要安装Grunt,请输入npm install --save-dev grunt
Install the Grunt CLI (command-line interface) npm install -g grunt-cli to execute tasks straight from the command line.
安装Grunt CLI(命令行界面) npm install -g grunt-cli可以直接从命令行执行任务。
To install the Grunt plugin for Jade tasks, type npm install --save-dev grunt-contrib-jade
要为Jade任务安装Grunt插件,请键入npm install --save-dev grunt-contrib-jade
To install Jade, type npm install --save-dev jade
要安装Jade,请键入npm install --save-dev jade
NOTE:: There are three flags for installing npm packages:
注意::安装npm软件包有三个标志:
--save means those packages are required locally for the project and listed under the dependencies property.
--save表示这些软件包对于项目是本地必需的,并在dependencies属性下列出。
--save-dev adds the packages locally but as development dependencies. They are listed under devDependencies in package.json.
--save-dev在本地添加软件包,但将其作为开发依赖项。 它们在package.json devDependencies下列出。
-g indicates the package should be installed globally; this lets you execute grunt in your terminal, regardless of the current working directory.
-g表示该软件包应全局安装; 这样,无论当前工作目录如何,您都可以在终端中执行grunt。
A package.json manifest file will be created, which indicates a list of packages the project depends upon, and it includes some meta data such as project name, version, and description.
将创建一个package.json清单文件,该文件指示项目所依赖的软件包的列表,其中包括一些元数据,例如项目名称,版本和描述。
After the installation your package.json manifest will look like the following:
安装后,您的package.json清单将如下所示:
{ "name": "jadeTutorial", "version": "1.0.0", "description": "Jade with Grunt tutorial", "main": "index.js", "author": "Nouran Mahmoud", "license": "ISC", "devDependencies": { "grunt": "^0.4.5", "grunt-contrib-jade": "^0.14.1", "jade": "^1.9.2", } }In addition, a node_modules directory will be created and will include the npm modules installed earlier as grunt and jade.
另外,将创建一个node_modules目录,其中将包含先前安装为grunt和jade的npm模块。
I’ll introduce you to Grunt, a popular task runner, we will use it to automate and execute time-consuming command line tasks in your development workflow. A task is an action that produces a target like compiling Jade to generate HTML. Using Grunt, we will be able to run Jade, watch tasks, and perform any other task with only one command line. It’s okay if you’ve never heard of a task runner before; it’s not a hard concept to wrap your head around.
我将向您介绍流行的任务运行器Grunt,我们将使用它在您的开发工作流程中自动化并执行耗时的命令行任务。 任务是产生诸如编译Jade以生成HTML之类的目标的动作。 使用Grunt,我们将能够仅使用一个命令行来运行Jade,监视任务以及执行任何其他任务。 如果您以前从未听说过任务执行程序,那也可以; 缠头不是一个难的概念。
Grunt is not the absolute best tool for this job. If you are curious about using other build tools, you can check out these resources: How to Use npm as a Build Tool or An Introduction to Gulp.js.
Grunt并不是完成这项工作的绝对最佳工具。 如果您对使用其他构建工具感到好奇,可以查看以下资源: 如何将npm用作构建工具或Gulp.js简介 。
Grunt uses gruntfile.js to load any task and configure it with any parameters you need, as I’ll show you along the way.
Grunt使用gruntfile.js加载任何任务,并使用gruntfile.js任何参数对其进行配置,正如我将gruntfile.js介绍的那样。
Grunt tasks are configured by passing an object to the grunt.initConfig method, defining the affected files by the task and passing in a few other options. Learn more about Grunt.
通过将对象传递给grunt.initConfig方法,配置任务定义受影响的文件并传递其他一些选项,可以配置Grunt任务。 了解有关Grunt的更多信息 。
The grunt.registerTask method defines a task that will be executed when we run grunt build via the command line. The array [jade, watch] indicates the tasks that will run respectively for accomplishing the build process.
grunt.registerTask方法定义了一个任务,当我们通过命令行运行grunt build时将执行该任务。 数组[jade, watch]指示将分别运行以完成构建过程的任务。
To begin with, this is the minimum Gruntfile.js code:
首先,这是最小的Gruntfile.js代码:
module.exports = function (grunt) { grunt.initConfig({}); grunt.registerTask('default', []); };We’ll create our basic Gruntfile and put the following code inside it:
我们将创建基本的Gruntfile并将以下代码放入其中:
module.exports = function(grunt) { // Project configuration. grunt.initConfig({ jade: { compile: { options: { pretty: true, }, files: { 'build/index.html': 'app/views/jobs.jade' } } } }); // These plugins provide necessary tasks. grunt.loadNpmTasks('grunt-contrib-jade'); // Default task. grunt.registerTask('build', 'Convert Jade templates into html templates', ['jade']); };Setting up a grunt task needs fetching of the plugin by the npm registry and loading the plugin package, which contains the task through the grunt.loadNpmTasks method, so you can configure and execute them.
设置grunt任务需要通过npm注册表获取插件并加载plugin包,该包包含通过grunt.loadNpmTasks方法包含的任务,因此您可以配置和执行它们。
The previous task configuration will compile each Jade file individually and place the results in the build directory with a single index.html file.
先前的任务配置将分别编译每个Jade文件,并将结果与单个index.html文件一起放置在build目录中。
The Watch task is one of the most useful plugins. This will watch your changes, rebuild and proceed immediately automatically without the need to run the jade task each time we make a change.
Watch任务是最有用的插件之一。 这将监视您的更改,立即重建并自动进行,而无需每次执行更改时都运行jade任务。
To add the watch task, install the plugin using this command:
要添加监视任务,请使用以下命令安装插件:
npm install --save-dev grunt-contrib-watchThen add its configuration to Gruntfile.js:
然后将其配置添加到Gruntfile.js :
watch: { grunt: { files: ['Gruntfile.js'] }, jade: { files: 'app/views/**/*.jade', tasks: ['jade'] } }This will create a “watch” task for Jade files and the Grunt file. To complete this, you’ll also need to load the Grunt task and register the task:
这将为Jade文件和Grunt文件创建一个“监视”任务。 要完成此操作,您还需要加载Grunt任务并注册该任务:
grunt.registerTask('default','Convert Jade templates into html templates', ['jade','watch']); grunt.loadNpmTasks('grunt-contrib-watch');Now when you run the grunt command it will accomplish the following tasks:
现在,当您运行grunt命令时,它将完成以下任务:
Compile Jade 编译玉Run the watch task to watch the changes on the Jade files and automatically re-compile them once they’ve changed.
运行watch任务以监视Jade文件上的更改,并在更改后自动重新编译它们。
The process will be active until it’s killed by CTRL+C
该进程将一直处于活动状态,直到被CTRL + C杀死为止
NOTE: The grunt command is a shortcut/alias for grunt default. It defines what tasks to be executed – jade and watch in our case – when we run the grunt command.
注意: grunt命令是grunt default的快捷方式/别名。 它定义了当我们运行grunt命令时要执行的任务–在我们的情况下是jade和watch 。
You can use the grunt-init-gruntfile scaffolding command for creating a basic Gruntfile. We will not need all its default tasks in this tutorial, so we won’t use it.
您可以使用grunt-init-gruntfile脚手架命令来创建基本的Gruntfile。 在本教程中,我们不需要其所有默认任务,因此我们将不使用它。
We’ll create our source folder hierarchy as follows:
我们将如下创建源文件夹层次结构:
app └──views | └── layout.jade | └── jobs.jade | └── jobs-container.jade └──── partials | └─ head.jade └─ footer.jadeExecute the grunt jade command and the following structure will be created for you.
执行grunt jade命令,将为您创建以下结构。
build └── index.htmlJade is indentation and whitespace based, as each level of indentation creates a level of nesting elements in HTML. For illustration, the following code shows how the basic structure might look using Jade for producing an HTML document.
Jade是基于缩进和空格的 ,因为每个缩进级别都会在HTML中创建一个嵌套元素级别。 为了说明起见,以下代码显示了使用Jade生成HTML文档时基本结构的外观。
doctype html html head title Jade Tutorial body p.className#idName Hello SitePoint | Readers! img(src="images/image.png")Which compiles into:
编译成:
<!DOCTYPE html> <html> <head> <title> Jade Tutorial </title> </head> <body> <p class="className" id="idName"> Hello SitePoint Readers! </p> <img src="images/image.png"> </body> </html>Using Jade, you don’t have to write closing tags, which helps avoid potential mistakes, such as forgetting to add closing tags or losing the correct order of them. Any text at the beginning of a line is interpreted as a tag. You need to use proper indentation for each tag.
使用Jade,您不必编写结束标记,这有助于避免潜在的错误,例如忘记添加结束标记或丢失正确的顺序。 行首的任何文本都将解释为标签。 您需要为每个标签使用适当的缩进。
Note: if the tag name is omitted, a div will be created as a default tag.
注意:如果省略标签名称,则将创建一个div作为默认标签。
To add attributes to a tag, put them inside parentheses after the tag name and follow the name=value format. To separate multiple attributes, use a comma. In addition, classes and IDs can be written with . and # symbols respectively, as in the previous example.
要将属性添加到标签,请将其放在标签名称后的括号内,并遵循name=value格式。 要分隔多个属性,请使用逗号。 此外,可以使用编写类和ID . 和#分别的符号,如在前面的例子英寸
Sometimes we need to write the raw content of a tag on a new line but, as I mentioned earlier, any text at the beginning of a line is considered a tag. To avoid this, use the pipe or | character at the beginning of the line and write the inner text for the tag on the new line.
有时我们需要在新行上写标签的原始内容,但是,正如我之前提到的, 在行首的任何文本都被视为标签 。 为避免这种情况,请使用管道或| 行开头的字符,并在新行上写标签的内部文本。
Note: in order to see the changes you made in the Jade file by compiling it you need to run grunt based on the Grunt task we created before.
注意:为了通过编译查看您在Jade文件中所做的更改,您需要根据我们之前创建的Grunt任务运行grunt 。
In the previous section, I gave you a quick overview of Jade’s syntax. In the following sections, we’ll go over some other common and powerful Jade features, along with a few more advanced ones. We’ll do this by going through a simple “job vacancies page” sample. You can find the full examples for each case in the source code files or from this GitHub repo. Let’s start!
在上一节中,我为您提供了Jade语法的快速概述。 在以下各节中,我们将介绍一些其他常见且强大的Jade功能以及一些更高级的功能。 我们将通过一个简单的“职位空缺页面”示例来完成此操作。 您可以在源代码文件或此GitHub存储库中找到每种情况的完整示例。 开始吧!
The file called layout.jade will be the basic structure for our page’s layout, and this is a kind of DRY concept, as you don’t need to write these tags for each page. Instead you need to extend the layout and start to write the block content specific code, as we will see.
名为layout.jade的文件将是页面布局的基本结构,这是一种DRY概念,因为您无需为每个页面编写这些标签。 相反,您将需要extend布局并开始编写block content特定的代码,如我们所见。
Blocks are kind of separating or organizing the layout. It can then be overwritten in another file.
块是一种分隔或组织布局的方式。 然后可以将其覆盖在另一个文件中。
NOTE: The CSS and JavaScript code are removed for brevity and focus. You can find these in the repo. Also, I’ve used the copy Grunt task for transferring the js and style directories from the app directory to the build directory.
注意:为了简洁和集中,已删除了CSS和JavaScript代码。 您可以在仓库中找到这些。 另外,我使用了copy Grunt任务将js和style目录从app目录转移到build目录。
Here is the layout.jade file:
这是layout.jade文件:
doctype html html(lang="en" dir="ltr") block head include partials/head.jade body block content block footer include partials/footer.jadeYou can create footer.jade and head.jade according to your needs. For our page, we will use Foundation and jQuery to help us establish some basic design and functionality.
您可以根据需要创建footer.jade和head.jade 。 对于我们的页面,我们将使用Foundation和jQuery帮助我们建立一些基本的设计和功能。
Here is the partials/head.jade file:
这是partials/head.jade文件:
head meta(name="viewport", content="width=device-width, initial-scale=1.0") meta(charset="UTF-8") title Jobs link(rel = "stylesheet" href = "style/foundation.min.css") link(rel = "stylesheet" href = "style/app.css")Here is the partials/footer.jade file:
这是partials/footer.jade文件:
div#footer.row div.small-12.large-12.columns p Copyright (c) foobar script(src="js/jquery.min.js") script(src="js/foundation.min.js") script(src="js/app.js")In the next snippet of code, we will create jobs.jade, which uses all the other files by inheriting our layout using the extends keyword and then overwriting the blocks that we need. In this example, we overwrite the content block.
在下一个代码片段中,我们将创建jobs.jade ,通过使用extends关键字继承我们的布局,然后覆盖所需的块,来使用所有其他文件。 在此示例中,我们覆盖了content block 。
jobs.jade:
jobs.jade :
extends layout.jade block content div#container.row div.small-12.large-12.columns include job-container.jadeBut what if we don’t need to overwrite the entire block? What if we just need to add content instead? Let’s take block head as an example. We need to add a special script for this page in the header, so we will use the append or prepend keywords after block.
但是,如果我们不需要覆盖整个块怎么办? 如果我们只需要添加内容怎么办? 让我们以block head为例。 我们需要在标题中为此页面添加一个特殊的脚本,因此我们将在block之后使用append或prepend关键字。
// append head can be used without block 'append head' block append head script. alert('Welcome to SitePoint')In the previous section, we included job-container.jade. In this section, we will look at the benefit of loops and mixins and how we can use them it in Jade.
在上一节中,我们包含了job-container.jade 。 在本节中,我们将研究循环和混合的好处,以及如何在Jade中使用它们。
Here is the initial version of a new code snippet:
这是新代码段的初始版本:
- each job in jobs div.sub-container.row div.title.small-12.large-12.columns p #{job.title} div.description.display.small-12.large-12.columns div.row div.block.small-12.large-12.columns p Skills and Requirements ul - each skill in job.skills li #{skill} div.block.small-12.large-12.columns p Preferred Skills ul - each pskill in job.pskills li #{pskill} button.apply.button(value="apply") ApplyAs you see, we’re using multiple normal loop statements like the one on the first line - each job in jobs. The - character is used for unbuffered code that does not add any output directly.
如您所见,我们正在使用多个普通循环语句,例如第一行中的语句- each job in jobs 。 -字符用于不直接添加任何输出的无缓冲代码。
In the previous snippet of code, there is redundant code that can become DRY-ier using mixins, as in the following code:
在前面的代码片段中,有多余的代码可以使用mixins变为DRY-ier,如以下代码所示:
- each job in jobs div.sub-container.row div.title.small-12.large-12.columns p #{job.title} div.description.display.small-12.large-12.columns div.row +skillsBlock("Skills and Requirements", job.skills) +skillsBlock("Preferred Skills", job.pskills) button.apply.button(value="apply") Apply mixin skillsBlock(title, loopItems) div.block.small-12.large-12.columns p= title ul - each skill in loopItems li #{skill}Here we’re creating a reusable block of Jade using the mixin feature. Mixins are like methods (or functions) that have names and take arguments to evaluate in their inner code. In the above example, we created a mixin called skillsBlock().
在这里,我们使用mixin功能创建了一个可重复使用的Jade块。 Mixins就像方法(或函数)一样,具有名称并带有参数以在其内部代码中求值。 在上面的示例中,我们创建了一个称为skillsBlock()的混合。
To use this mixin, we just write its name and pass the proper parameter values, prefixing the mixin name with a + sign to identify it as a mixin call.
要使用此mixin ,我们只需编写其名称并传递适当的参数值,并在混合名称之前加上+号即可将其标识为mixin调用。
NOTE: as in the above code, we can evaluate values either by =, != or #{}. But be careful when you use !=, which does not do any escaping, so is not safe for user input.
注意:如以上代码所示,我们可以通过= , !=或#{}来评估值。 但是,当您使用!=时,请务必小心,因为它不会进行任何转义,因此对于用户输入而言是不安全的。
After establishing our environment, let’s do some awesome stuff with the combination of Grunt and Jade by passing JSON data from a JSON file to Jade using a Grunt task.
建立环境之后,让我们通过使用Grunt任务将JSON数据从JSON文件传递到Jade,从而结合使用Grunt和Jade进行一些很棒的工作。
At first, create the JSON file data.json, and fill it with your desired data.
首先,创建JSON文件data.json ,并用所需的数据填充它。
Then open Gruntfile.js and add the data attribute to the options of the Jade task, as follows:
然后打开Gruntfile.js并将data属性添加到Jade任务的选项中,如下所示:
jade: { compile: { options: { pretty: true, data: { jobs: grunt.file.readJSON('data.json') } }, files: { 'build/index.html': 'app/views/jobs.jade' } } }The jobs data/locals (data passed to Jade templates are called locals) attribute will be passed to the Jade files identified in the files property and can be used in the Jade code. This manner gives you the ability to add text content to web pages easily.
jobs数据/本地(传递给Jade模板的数据称为本地)属性将被传递到files属性中标识的Jade文件,并且可以在Jade代码中使用。 这种方式使您能够轻松地将文本内容添加到网页。
Lastly, you can see how the page looks if you check out the demo. Of course, the source is compiled so the demo is of little importance in this case. A screenshot is shown below.
最后, 如果您查看演示 ,您将看到页面外观。 当然,源代码是经过编译的,因此在这种情况下,演示并不重要。 屏幕截图如下所示。
Reasons to use template engines may vary, but they can be categorized as more productivity, less repetition, and having a more pleasant syntax. Also, you might not want to write code in the native language because it is too repetitive, error-prone, or maybe you simply don’t like it. This is where a language like Jade, tuned to keeping your code concise and simple, comes into play.
使用模板引擎的原因可能有所不同,但是可以将其归类为更高的生产率,更少的重复以及具有更令人愉悦的语法。 另外,您可能不想使用本机语言编写代码,因为它过于重复,容易出错,或者您可能根本不喜欢它。 这就是像Jade这样的语言,为了使您的代码简洁明了而进行了调整。
Jade helps you write cleaner code, which makes it less tedious to do your job. We’ve covered some of the basics and tips and tricks using Grunt. There is more you can learn about Jade that we didn’t cover in this tutorial, so you can check out the official documentation for more.
Jade可帮助您编写更简洁的代码,从而减少工作量。 我们已经介绍了使用Grunt的一些基础知识,技巧和窍门。 您可以了解本教程中未介绍的关于Jade的更多信息,因此您可以查看官方文档以获取更多信息。
翻译自: https://www.sitepoint.com/using-jade-and-grunt-to-speed-up-html-production/