在单页应用程序成为主流之前,像 Pug 这样的模板语言非常流行,因为它们允许开发人员在将页面发送到客户端之前在服务器端渲染页面。 Express 是最流行的 Node.js 后端应用程序框架。它以其轻量级、不固执且易于使用而自豪。在本指南中,您将学习如何从 Express.js 服务器应用程序中使用 Pug 提供动态 HTML。
HTML 有时编写起来很麻烦。该语言不支持“组件”等功能,这可能会导致代码重复,除非您依赖 JavaScript 等外部工具。
Pug 是一个模板引擎,可以更轻松地编写 HTML。使用 Pug,您可以拆分代码并在任意多的地方重用“组件”。关于语法,Pug 与传统 HTML 不同,因为它使用缩进而不是结束标记。在 HTML 中,您可以像这样定义一个元素:
<div class='hello'>This is something worth noting</div>
然而,在 Pug 中,您可以像这样定义一个元素:
div(class='hello') This is something worth noting
标签名称定义在左侧,其属性位于括号内。标签与其内容之间由旁边的空格分隔开。 Pug 转译器会将您的代码转译回浏览器可识别的正确 HTML 代码。子元素通过缩进定义。这意味着如果你想在主标签内有一个 div,你可以这样做:
main div Hello from the children of planet Earth!
要将 Pug 添加到您的 Express.js 项目中,只需使用您选择的任何包管理器安装 Pug 即可。对于此示例,我正在使用 NPM:
npm i pug
这会将 Pug 添加到 package.json 文件中的依赖项列表中。现在,您需要将视图引擎设置为 pug,因此在项目的入口文件(通常是 main.js、app.js 或 index.js )中,正确导入express并使用 set 方法配置应用程序设置。
import express from 'express'; const app = express(); app.set('view engine', 'pug');
通过将视图引擎设置为“pug”,您将告诉 Express 使用 Pug 作为其模板引擎。因此,当您在响应对象上调用 render 方法时,必须传递一个有效的“视图”以便 Express 进行渲染。 Express 中的视图必须放置在项目根目录中的特殊视图目录中。如果您还没有创建视图目录,可以使用以下命令来创建:
mkdir views # Make sure you are in your project root
现在,您已经完成了所有设置,让我们继续在 Pug 中编写我们的第一个视图。
创建一个views/index.pug 文件,并向其中添加以下内容:
html head title Welcome to my website body div Hello World
现在您的index.pug 文件已准备就绪,您需要将其提供给路由上的客户端。转到项目的入口文件并定义一个获取请求处理程序,该处理程序将渲染views/index.pug 文件并将其返回给客户端。
app.get("/", (req, res) => { res.render("index.pug"); });
当您打开 localhost:
res.render(view [, locals] [, callback]);
首先,我们有视图,它只是您要渲染的 .pug 文件的路径。请记住,Express 会相对于视图目录定位 .pug 文件。因此,如果您有一个位于views/layouts/main.pug 的Pug 文件,则在设置路线中的视图时应将其称为layouts/main。
app.get("/", (req, res) => { res.render("layouts/main"); });
接下来,局部变量是一个对象,其属性定义了应传递到指定视图进行插值的局部变量。提供回调时,渲染操作生成的 HTML 不会发送到客户端。相反,您可以通过回调函数中的参数访问它,如下所示:
app.get("/", (req, res) => { res.render("index.pug", {}, (err, html) => { console.log(html); }); });
当客户端向“/”发出 get 请求时,不会发送响应。相反,html 会记录到服务器控制台。您可以使用 send 方法手动将 HTML 发送到客户端:
res.send(html)
现在是时候将事情提升到一个新的水平了。您将学习如何使用 Pug 插入数据以动态创建动态内容。在 Pug 中,字符串插值是通过语法 #{
// greet.pug html head title Welcome to my website body div Hello #{name}
在上面的代码块中, name 将被替换为传递给 render 方法的 locals 对象的实际值。如果名称未定义,则不会引发错误。这是在行动。
app.get('/greet', (req, res) => { const {name} = req.query; res.render('greet.pug', {name}) })
当客户端点击 /greet?name=David 时,将返回以下 HTML
<html> <head> <title>Welcome to my website</title> </head> <body> <div>Hello David</div> </body> </html>
The string interpolation syntax (#{}), is escaped by Pug. This is useful in situations where the content comes from users. If you want Pug is render the string as is without escaping, you'll need to use the !{} syntax.
- var example = <strong>very risky</strong> div !{example}
Pug provides a handy syntax for tag interpolation #[], which you can use like this:
p This is a #[strong very important] message.
This will render as:
<p>This is a <strong>very important</strong> message.</p>
- var username = 'John' p Hello, #[strong #{username}]!
You don't have to worry about self-closing tags, because Pug knows what tags are self closing. But if you really need to self-close a tag, you can append the / character to the end of the tag like this:
div/
To save space, You can use the : shorthand instead of indentation to specify nested tags.
label: input(type='text' name='username')
The code block above is just as valid as:
label input(type='text' name='username')
In the last code block, notice the use of the var keyword from JavaScript to create a variable. Pug allows you to insert valid JavaScript code on any line that starts with an -. For example, you can create an array and iterate over it to render a list of items. Pug has its native syntax for this, but in this example, you can use JavaScript.
html head title Welcome to my website body div List of items - var items = ['milk', 'peas', 'bread'] - items.forEach((item)=>{ li #{item} - })
Study the previous example. Notice how Pug and JavaScript are combined. The forEach method is not part of the Pug API, it belongs to JavaScript. Likewise, the string interpolation symbol is not part of the #{} JavaScript API. The lines with valid JavaScript code are marked with the - symbol. On the second to last line, there is no - symbol, because that is Pug code.
For common things like conditionals and iteration, Pug provides its syntax that you can use instead of JavaScript. The most popular keyword for iteration in Pug is each. each must come in the form each VARIABLE_NAME of JS_EXPRESSION. Here's how you can use it:
each item in ['milk', 'peas', 'bread'] li #{item}
When dealing with objects, the expected format for each is each VALUE, KEY OF JS_EXPRESSION. For example:
each val, key in {1:'milk', 2:'peas', 3:'bread'} #{key} : #{val}
You can use the if syntax to handle conditionals. Here's an example:
╴ var loggedIn = false if !loggedIn p Sorry you cannot access this item because you're not logged in
Conversely, Pug has an unless keyword that you can use like this:
unless loggedIn p Sorry you cannot access this item because you're not logged in
Pug offers many features beyond just string interpolation and conditionals. If you are working on a large website, you might need to use advanced features that Pug provides, such as layouts and partials.
Layout files allow you to define a common structure for your pages and extend it in other templates, ensuring consistency across your website. Here's an example of how you can use layout files.
//- views/layout.pug html head title My Website Title body header h1 My Website block content footer p Footer content
Notice the block keyword in the code block above. A block in a layout file acts as a placeholder. Each block must have a name. In this example, block is defined as content. Whenever you want to use your layout file, you use the extends syntax to tell Pug that a template should include a layout.
//- views/index.pug extends layout block content p Welcome to the homepage!
In this example, index.pug extends the layout.pug template, which provides the page's base structure, including the header and footer. The block content line defines a block named content where the indented paragraph "Welcome to the homepage!" is inserted. When index.pug is rendered, the final HTML will look this this:
<html> <head> <title>My Website Title</title> </head> <body> <header> <h1>My Website</h1> </header> <p>Welcome to the homepage!</p> <footer> <p>Footer content</p> </footer> </body> </html>
Partials are reusable pieces of templates that can be included in other templates, which helps to keep your code DRY (Don't Repeat Yourself). You can create partials in Pug with the include syntax.
//- views/partials/sidebar.pug aside p This is the sidebar content.
In sidebar.pug defines a partial template for a sidebar with an aside element containing a paragraph of text.
//- views/layout.pug html head title My Website Title body include partials/sidebar block content footer p Footer content
In layout.pug, a layout template is created with a basic HTML structure. It includes the header and sidebar partials using the include keyword, places a block content placeholder for dynamic content, and adds a footer with a paragraph of text. The final render should look something like this:
<html> <head> <title>My Website Title</title> </head> <body> <header></header> <aside> <p>This is the sidebar content.</p> </aside> <p>Welcome to the homepage!</p> <footer> <p>Footer content</p> </footer> </body> </html>
1. Use partials and layouts wherever you can: Using partials, layouts, and helpers in Pug enhances template organization and efficiency. Partials are reusable snippets that prevent code repetition, while layouts provide a consistent structure for pages by defining common elements and extending them in individual templates.
2. Minimize the use of inline JavaScript: When writing your templates, try to use inline JavaScript sparingly. Adding huge blocks of JavaScript to your code can create issues with debugging and maintainability.
One way to reduce inline JavaScript is through the use of helpers. Helpers, defined in the server-side code, allow dynamic content within templates. You can pass a helper function to a template using the locals method on the express app.
const express = require('express'); const app = express(); app.set('view engine', 'pug'); app.locals.formatDate = function(date) { return new Date(date).toLocaleDateString(); }; app.get('/', (req, res) => { res.render('index', { title: 'Home', currentDate: new Date() }); }); app.listen(3000, () => { console.log('Server is running on port 3000'); });
With the formatDate helper function set, you can use it in your Pug template like this:
p Welcome to the homepage! p Today's date is #{formatDate(currentDate)}
In this guide, you learned how to serve dynamic HTML with Pug and Express. We covered basic Pug syntax, integrating Pug with Express, building dynamic pages, and advanced techniques like using layout files and partials.
Templating engines are very powerful especially when building a server-side web application. They are great for Search Engine optimization too because unlike single-page applications, the content is rendered on the server on each request.
以上是使用 Pug 和 Express 提供动态 HTML的详细内容。更多信息请关注PHP中文网其他相关文章!