国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Express 實戰(zhàn)(七):視圖與模板:Pug 和 EJS

wmui / 891人閱讀

摘要:而框架中最常用的兩個視圖引擎是和。實際上這些上下文對象就是會在視圖中使用到的變量。其實視圖緩存并不是緩存視圖實際上它緩存的視圖路徑。根據(jù)默認視圖引擎將缺少拓展名的視圖文件補充完整。實際上存在由不同組織維護的兩個不同版本的。


前面的內(nèi)容大都是關(guān)于 Express 框架自身的內(nèi)容,包括:Express 簡介、工作原理、框架特點。在系列的最后,我們將把注意力放到 Express 框架周邊工具鏈上。學(xué)習(xí)如果使用這些工具來拓展 Express 框架的功能。

首先,本文我們將會討論視圖模版引擎的使用。通過這些模版引擎我們能過動態(tài)的生成 HTML 內(nèi)容。在前面我們已經(jīng)使用過 EJS 并使用變量語法實現(xiàn)內(nèi)容的注入。但是這些內(nèi)容只是整個模版引擎部分的冰山一角。接下來,將會學(xué)習(xí)到多種內(nèi)容注入方式、EJS,Pug 等模版引擎的特性。

Express 視圖特性

在開始之前,我們有必要解釋下何為視圖引擎(view engine)?視圖引擎作為編程術(shù)語它主要意思是指“進行視圖渲染的模塊”。而 Express 框架中最常用的兩個視圖引擎是 Pug 和 EJS 。需要注意的是,Pug 早期的名稱是 Jade 由于某些原因不得已改名 。

另外,Express 并沒有指定必須使用何種引擎。只要該視圖引擎的設(shè)計符合 Express API 規(guī)范,你就可以將其應(yīng)用到工程中。下面,我們看看它到底是如何工作的。

簡單的視圖渲染示例

下面我們通過一個簡單示例回顧下 EJS 渲染過程:

var express = require("express");
var path = require("path");
var app = express();

app.set("view engine", "ejs");

app.set("views", path.resolve(__dirname, "views"));

app.get("/", function(req, res) {
    res.render("index");
});

app.listen(3000);

在運行代碼之前,你需要通過 npm install 安裝 EJS 和 Express。在安裝完成后訪問應(yīng)用主頁的話,程序就會尋找 views/index.ejs 文件并使用 EJS 對其進行渲染。另外,工程中一般都只會使用一個視圖引擎,因為多個引擎會給工程引入不必要的復(fù)雜性。

復(fù)雜的視圖渲染

下面我們看一個更為復(fù)雜的示例,其中會同時用到兩個視圖引擎 Pug 和 EJS:

var express = require("express");
var path = require("path");
var ejs = require("ejs");
var app = express();
app.locals.appName = "Song Lyrics";
app.set("view engine", "jade");
app.set("views", path.resolve(__dirname, "views"));
app.engine("html", ejs.renderFile);
app.use(function(req, res, next) {
    res.locals.userAgent = req.headers["user-agent"];
    next();
});
app.get("/about", function(req, res) {
    res.render("about", {
        currentUser: "india-arie123"
    });
});
app.get("/contact", function(req, res) {
    res.render("contact.ejs");
});
app.use(function(req, res) {
    res.status(404);
    res.render("404.html", {
        urlAttempted: req.url
    });
});
app.listen(3000);

雖然代碼看起來比較復(fù)雜,但其實分解后步驟也還簡單。下面,我們就對上面調(diào)用 render 處的代碼進行分析:

Express 在你每次調(diào)用 render 時都會創(chuàng)建上下文對象,并且在進行渲染時會傳入到視圖引擎中。實際上這些上下文對象就是會在視圖中使用到的變量。

Express 首先會將所有請求都公用的 app.local 中已存在的屬性添加視圖中。然后添加 res.locals 中的屬性并對可能與 app.local 沖突的屬性進行覆蓋操作。最后,添加 render 調(diào)用處的屬性并且也可能進行覆蓋操作。例如,訪問 /about 路徑時,上下文對象就包含三個屬性:appname、userAgentcurrentUser;訪問 /contact 路徑時,上下文對象的屬性就只有 appname、userAgent ;而進行 404 處理時上下文對象的屬性就變成了:appnameuserAgent、urlAttempted 。

緊接著,我們將會設(shè)置是否啟用視圖緩存。其實視圖緩存并不是緩存視圖實際上它緩存的視圖路徑。例如,它會將 views/my_views.ejs 路徑緩存起來并綁定到 EJS 引擎上。

Express 通過兩種方式來決定是否對視圖文件進行緩存:

文檔記錄方式:通過調(diào)用 *app.enabled("view cache")* 開啟。在開發(fā)模式下默認是被禁用的,但是你可以在正式生產(chǎn)環(huán)境中開啟。當然,你可以通過 *app.disable("view cache")* 手動關(guān)閉。

非文檔記錄方式:根據(jù)第一步上下文中的 *cache* 對象是否為 *true* 來決定是否緩存該文件。這樣你就可以對每一個文件進行自定義設(shè)置了。

接下來,Express 會設(shè)置視圖文件名及其使用的視圖引擎。如果在第二步中已經(jīng)進行了視圖緩存則可以直接跳到最后一步。否則,則繼續(xù)下一步。

根據(jù)默認視圖引擎將缺少拓展名的視圖文件補充完整。在本例中,about 會被拓展成 about.jade ,而 contact.ejs 以及 404.html 文件會保存不變。如果你既沒有指定默認視圖引擎也沒有明確拓展名,那么程序會出現(xiàn)崩潰。

通過文件拓展名進行視圖引擎匹配。對于 .html 格式文件則根據(jù) app.engine("html", xx); 設(shè)置進行匹配。

在視圖問價夾下,查找視圖文件名對應(yīng)的文件。如果不存在則報錯。

判斷查找到的視圖文件是否需要進行緩存。

使用引擎對視圖文件進行渲染并生成最終的 HTML 文件。

同時使用多個視圖引擎確實為程序增加了不必要的復(fù)雜性,好在絕大多數(shù)時候我們并不會這樣做。

Express 給客戶端默認響應(yīng)的內(nèi)容是 HTML。雖然大多數(shù)時候這沒什么問題,但是有時可能需要返回的是純文本、XML、JSON 等格式。此時,你可以通過修改參數(shù) res.type 進行自定義設(shè)置:

app.get(“/”, function(req, res) { 
? res.type(“text”); 
? res.render(“myview”, { 
?? currentUser: “Gilligan” 
? }); 
} 

當然,你可以使用更簡單的 res.json

視圖引擎的 Express 兼容設(shè)置:Consolidate.js

除了 EJS 和 Pug 之外,其實還有很多中模版引擎。但是這些模版引擎可能并不像 EJS 和 Pug 那樣是為 Express 專門設(shè)計的。此時如果需要使用這些未適配的模版引擎,我們就不得不使用 Consolidate.js 進行封裝以期能夠兼容 Express API。而且 Consolidate.js 支持的種類也非常多,你可以在項目首頁看到完整的支持列表。

假設(shè),現(xiàn)在你正是使用的引擎是與 Express 并不兼容的 Walrus。那么,下面我們看 Consolidate 是如何進行兼容適配工作的。

首先,使用 npm install walrus consolidate 安裝相關(guān)類庫和依賴項,然后我們將其引入:

var express = require("express");

var engines = require("consolidate");
var path = require("path");
var app = express();

app.set("view engine", "wal");
app.engine("wal", engines.walrus);
app.set("views", path.resolve(__dirname, "views"));

app.get("/", function(req, res) {
    res.render("index");
});
app.listen(3000);

是不是很簡單?只需幾行代碼我們就完成了整個適配工作。所以當有兼容適配需求的時候,我強烈建議你使用 Consolidate 而不是自己悶頭干。

EJS 中你必須要了解的東西

EJS 是 Express 中最簡單也是最受歡迎的視圖引擎之一。它可以為字符串、HTML、純文本創(chuàng)建模版,而且他的集成也非常簡單。它在瀏覽器和 Node 環(huán)境中都能正常工作。它與 Ruby 中的 ERB 與法非常的類似。

實際上存在由不同組織維護的兩個不同版本的 EJS。雖然在功能上它們很相似,但是并不是同一個類庫。其中 Express 中使用的 EJS 是由 TJ Holowaychuck 維護的,你可以通過 npm 查找到該類庫。另一個同名類庫在 09 年就停止了更新且它不能在 Node 環(huán)境中運行。

EJS 語法

除了用做 HTML 模版之外,它還能應(yīng)用于字符串和純文本中。請看 EJS 是如何對下面文本模版進行渲染的:

Hi <%= name %>!
You were born in <%= birthyear %>, so that means you"re <%= (new Date()).getFullYear() - birthyear %> years old.
<% if (career) { -%>
  <%=: career | capitalize %> is a cool career!
<% } else { -%>
  Haven"t started a career yet? That"s cool.
<% } -%>
Oh, let"s read your bio: <%- bio %> See you later!

將下面的 JSON 數(shù)據(jù)傳入上面摸板中:

{
    name: "Tony Hawk",
    birthyear: 1968,
    career: "skateboarding",
    bio: "Tony Hawk is the coolest skateboarder around."
}

最終,得到的渲染結(jié)果是(假設(shè)當前是 2015 年):

Hi Tony Hawk!
You were born in 1968, so that means you’re 47 years old.
Skateboarding is a cool career!
Oh, let’s read your bio: Tony Hawk is the coolest skateboarder around. See
you later!

該示例演示了 EJS 常用的四種語法:打印、打印并轉(zhuǎn)義、執(zhí)行 JS 代碼、過濾。

在 EJS 你可以使用兩種語法打印表達式的值:<%= expression %> 和 <%- expression %>,其中前者會對結(jié)果進行 HTML 轉(zhuǎn)義。例如,當傳入的 expression 值為 Express 時,前者執(zhí)行的結(jié)果是 Express 而后者得到的字符串是 Express。我建議你使用前一種方式,因為它更為可靠。

同樣,EJS 還允許你 通過 <% expression %> 語法在其中執(zhí)行 JS 表達式,并且該表達式并不會被打印出來。該特性在執(zhí)行循環(huán)和條件判斷的時候非常有用。另外,你還可以通過 <% expression -%> 避免不必要的換行。

通過 <%=: expression | xxx %> 語法,我們可以對表達式結(jié)果再進行一次過濾處理。例如,上面我們就對表達式結(jié)果應(yīng)用了首字母大寫過濾器。當然,除了自帶的大量過濾器之外,你還可以進行自定義。

這里,我做了一個 EJS 的示例程序。雖然界面不是很好看,但是你能從中熟悉 EJS 的各種語法使用。

在已有 EJS 文件中嵌入其他 EJS 模版

EJS 引擎允許你在當前模版中使用另一個 EJS 模版。這樣我們就能對整個進行組件拆分復(fù)用。例如,將 HTML 的頭部和尾部拆分為 headerfooter 模塊,然后在其他模版中進行組合復(fù)用。

示例如下:首先我們創(chuàng)建 header.ejs 并拷貝代碼:




    
    
    <%= appTitle %>/title>
</head>
<body>
    <header>
        <h1><%= appTitle %></h1>
    </header></pre>
<p>緊接著創(chuàng)建 footer 組件 <em>footer.ejs</em> 并拷貝代碼:</p>
<pre><footer>
    All content copyright <%= new Date().getFullYear() %> <%= appName %>.
</footer>
</body>
</html></pre>
<p>最后,我們通過 <em>include</em> 語法進行組件嵌入操作:</p>
<pre><% include header %>
    <h1>Welcome to my page!</h1>
    <p>This is a pretty cool page, I must say.</p>
<% include footer %></pre>
<p>假設(shè),你現(xiàn)在需要實現(xiàn)一個展示用戶信息的組建,那么你可以創(chuàng)建 <em>userwidget.ejs</em> 文件并拷貝:</p>
<pre><div   id="t5np7hr"   class="user-widget">
    <img src="<%= user.profilePicture %>">
    <div   id="hrhnfd7"   class="user-name"><%= user.name %></div>
    <div   id="b7xpfnn"   class="user-bio"><%= user.bio %></div>
</div></pre>
<p>那么,在渲染當前用戶時可以這樣使用該模版:</p>
<pre><% user = currentUser %>
<% include userwidget %></pre>
<p>或者在渲染用戶列表時:</p>
<pre><% userList.forEach(function(user) { %>
  <% include userwidget %>
<% } %></pre>
<p>通過 EJS 中的 <em>include</em> 語法,我們可以在創(chuàng)建模版的同時將其作為組件進行子視圖的渲染操作。</p>
<b>添加你自己的過濾器</b>
<p>Express 內(nèi)置的 22 個過濾器,其中包括對數(shù)組和字符串的常用操作。通常情況下,它們能過滿足你的需求,但是有時你不得不添加自己的過濾器。</p>
<p>假設(shè),現(xiàn)在你已經(jīng)引入了 EJS 模塊并將其保存到名為 <em>ejs</em> 變量中。那么你可以為按照下面的方式為 <em>ejs.filters</em> 拓展一個用于數(shù)組求和的過濾器。</p>
<pre>ejs.filters.sum = function(arr) {
  var result = 0;
  for (var i = 0; i < arr.length; i++) {
    result += arr[i];
  }
  return result;
};</pre>
<p>然后,你就可以在代碼中使用該過濾器了:</p>
<pre><%=: myarray | sum %></pre>
<p>實現(xiàn)和使用都非常簡單,所以我建議你將那些常用操作實現(xiàn)為過濾器。</p>
<b>Pug 中你必須要了解的東西</b>
<p>像 Handlebars ,Mustache ,以及 EJS 這樣的視圖引擎只是在 HTML 拓展了新語法它并沒有對 HTML 語法造成破壞。對于一個了解 HTML 語法的設(shè)計師來說這最好不過了,畢竟不用學(xué)習(xí)新語言。同樣它們還適用于非 HTML 模版環(huán)境,而這一點則是 Pug 的軟肋。</p>
<p>但是 Pug 也有自己獨特的優(yōu)勢。它能減少你的代碼量,而且代碼風(fēng)格也非常不錯。尤其在寫 HTML 模版時,標簽會嵌套縮進而且無需閉合。另外,EJS 風(fēng)格的判斷和循環(huán)語法也是內(nèi)置的。雖然需要學(xué)的東西比較多,但是它的功能也異常強大。</p>
<b>Pug 語法</b>
<p>像 HTML 這樣的語言是嵌套的,其中有根元素(<html>)以及各種子元素(像 <head> 和 <body> ),而子元素還可以進一步嵌套其他元素。另外,HTML 的元素必須像 XML 一樣需要閉合。</p>
<p>而 Pug 則采用了不同的縮進語法。下面的代碼就展示了使用 Pug 實現(xiàn)的簡單 web 頁面:</p>
<pre>doctype html
html(lang="en") 
  head
    title Hello world!
  body
    h1 This is a Pug example
    #container 
      p Wow.</pre>
<p>上面的代碼中內(nèi)容將被轉(zhuǎn)變?yōu)橄旅娴?HTML。</p>
<pre><!DOCTYPE html>
<html lang="en">
<head>
    <title>Hello world!

        

This is a Pug example

Wow.

你可以去 Pug 項目主頁去查看它時如何實現(xiàn)這種轉(zhuǎn)變的。

Pug 的布局

布局時所有模版語言的一個重要特性。它可以讓我們實現(xiàn)公共組件然后在其他文件中實現(xiàn)復(fù)用。例如,我們可以將頁面的 header 和 footer 抽離出來。這樣不僅可以保證所有頁面的 header 和 footer 內(nèi)容的一致,而且修改起來也更加方便。

Pug 布局的實現(xiàn)步驟大致如下:

第一步,為所有頁面定義一個主布局文件,而該文件幾乎就是一個空模版。它用 block 語法進行占位操作,然后實際生成的頁面會使用內(nèi)容替換這些占位符。示例如下:

doctype html
html
  head
    meta(charset="utf-8")
    title Cute Animals website
    link(rel="stylesheet" href="the.css")
    block header  
  body
    h1 Cute Animals website
    block body  

你可以看到上面定義了 headerbody 兩個占位符。下面我們將它保存到 layout.jade 文件中。緊接著我們實現(xiàn)其中的 body 塊:

extends layout.jade
block body
  p Welcome to my cute animals page!

layout.jade 將會被渲染成:



  
    
    Cute Animals website
    
  
  
    

Cute Animals website

Welcome to my cute animals page!

注意到當你拓展主布局時,并不一定需要實現(xiàn)其中的所有占位塊。例如上面就沒有實現(xiàn) header

在其他頁面可以對 body 塊進行不同的實現(xiàn):

extends layout.jade
block body
  p This is another page using ths layout.
  img(src="cute_dog.jpg" alt="A cute dog!")
  p Isn"t that a cute dog!

Pug 通過布局進行組件分離讓我們可以避免一些重復(fù)的代碼。

Pug 的 Mixins 功能

Pug 中還有一個被稱為 Mixins 的酷炫特性。通過該特性你可以對文件中可能需要反復(fù)使用的功能進行一次定義。下面,我們就通過該特性對前面 EJS 部分用戶信息展示的功能進行重新實現(xiàn):

mixin user-widget(user)
  .user-widget
    img(src=user.profilePicture)
    .user-name= user.name
    .user-bio= user.bio
    
// 展示當前用戶
+user-widget(currentUser)  

// 展示用戶列表
- each user in userList 
  +user-widget(user)

Pug 的基礎(chǔ)內(nèi)容到此為止,更多語法細節(jié)請查看官方文檔。

總結(jié)

這章的內(nèi)容包括:

Express 的視圖系統(tǒng),以及它是如何進行動態(tài)渲染的。

EJS 引擎的語法和基本使用。

Pug 引擎的語法和基本使用。

原文地址

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/84846.html

相關(guān)文章

  • Express 文檔(使用模板引擎)

    摘要:一些與一起使用的流行模板引擎是和,應(yīng)用程序生成器使用作為其默認值,但它也支持其他幾個。有關(guān)可與一起使用的模板引擎列表,請參閱模板引擎,另請參閱比較模板引擎等。,使用的模板引擎,例如,要使用模板引擎。 使用模板引擎 模板引擎使你可以在應(yīng)用程序中使用靜態(tài)模板文件,在運行時,模板引擎用實際值替換模板文件中的變量,并將模板轉(zhuǎn)換為發(fā)送到客戶端的HTML文件,這種方法可以更輕松地設(shè)計HTML頁面。...

    gxyz 評論0 收藏0
  • Express 實戰(zhàn)(三):Express 基礎(chǔ)

    摘要:同樣的的框架中也有被稱為中間件概念。所以,整個工作流有兩種可能情形另外,這些中間件函數(shù)中部分函數(shù)需要對響應(yīng)做出響應(yīng)。擴展和在原來基礎(chǔ)上對和對象進行了功能擴展。除了對響應(yīng)對象進行了拓展之 Express 框架的初衷是為了拓展 Node 內(nèi)置模塊的功能提高開發(fā)效率。當你深入研究后就會發(fā)現(xiàn),Express 其實是在 Node 內(nèi)置的 HTTP 模塊上構(gòu)建了一層抽象。理論上所有 Express...

    KoreyLee 評論0 收藏0
  • 實戰(zhàn)】用 express+MongoDB 搭建一個完整的前端項目

    摘要:前言要做一個全沾的工程師,對于后端和數(shù)據(jù)庫來說,即使不認識也要見個面的?;玖私獾母拍罹秃茫饕前惭b上數(shù)據(jù)庫,并進行簡單的增刪操作。 前言:要做一個全沾的工程師,對于后端和數(shù)據(jù)庫來說,即使不認識也要見個面的。本文給的例子很簡單,也貼出來源碼,只要一步步下來,就可以跑起來啦~~~ 思考一個需求:做一個登錄頁面,自己搭建服務(wù)和數(shù)據(jù)庫,將用戶輸入的登錄信息保存到數(shù)據(jù)庫如何完成呢:首先選擇...

    Steve_Wang_ 評論0 收藏0
  • Express 文檔(Express生成器)

    摘要:應(yīng)用程序生成器使用應(yīng)用程序生成器工具快速創(chuàng)建應(yīng)用程序框架。生成的應(yīng)用程序具有以下目錄結(jié)構(gòu)生成器創(chuàng)建的應(yīng)用程序結(jié)構(gòu)只是構(gòu)建應(yīng)用程序的眾多方法之一,隨意使用此結(jié)構(gòu)或修改它以最好地滿足你的需求。 Express應(yīng)用程序生成器 使用應(yīng)用程序生成器工具express-generator快速創(chuàng)建應(yīng)用程序框架。 express-generator包安裝了express命令行工具,使用以下命令執(zhí)行此操...

    abson 評論0 收藏0
  • express web的一款mvc框架

    摘要:相關(guān)的網(wǎng)站開發(fā)有這么常用的四款數(shù)據(jù)層視圖層控制層框架,我們今天說一下阿里的框架是一個自身功能極簡,完全是由路由和中間件構(gòu)成一個的開發(fā)框架安裝創(chuàng)建一個目錄通過命令為你的應(yīng)用創(chuàng)建一個文件。修改請求和響應(yīng)對象。注意只對使用或加載的中間件有效。 express express相關(guān)的網(wǎng)站*http://expressjs.com/*http://www.expressjs.com.cn/*htt...

    _ang 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<