【Nodejs】淺談網頁開發中的模板語言:Pug 和 EJS

閱讀時間約 18 分鐘

這一篇文章,我想來談談模板語言(template language/engine)。而其中比較有名的為handlebar、pug、ejs。那我會的事後兩著,因此拿這兩個出來寫一篇文章。

Pug

指令:npm install pug
raw-image

比起 HTML 的語法,pug 語法可以說簡潔很多。

那下面直接放一個html跟一個pug

// shop.html 
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>商城</title>
<link rel="stylesheet" href="/css/bootstrap.min.css" />

</head>

<body>
<header class="main-header">
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<a class="navbar-brand" href="/">NodeJs商城</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav">
<li class="nav-item active">
<a class="nav-link" href="/">商城</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/admin/add-product">添加产品</a>
</li>

</ul>
</div>
</nav>

</header>

<main class="container p-5">
<h1>我的产品</h1>
<div class="row">
<div class="col-md-4 p-2">
<div class="card" style="width: 18rem;">
<img src="https://miro.medium.com/max/1200/1*m5RYM_Wkj4LsZewpigV5tg.jpeg" class="card-img-top" alt="...">
<div class="card-body">
<h5 class="card-title">产品名称</h5>
<p class="card-text">产品详情介绍信息,该课程讲解十分细致,各个知识点都有所涉及。</p>
<p>29.99</p>
<a href="#" class="btn btn-primary">加入购物车</a>
</div>
</div>

</div>
</div>
</main>
</body>

</html>
// shop.pug
<!DOCTYPE html>
html(lang="en")
head
meta(charset="UTF-8")
meta(name="viewport", content="width=device-width, initial-scale=1.0")
title #{docTitle}
link(rel="stylesheet", href="/css/bootstrap.min.css")
body

nav.navbar.navbar-expand-lg.navbar-dark.bg-dark
a.navbar-brand(href="/") NodeJs商城
button.navbar-toggler(type="button", data-toggle="collapse",data-target="#navbarNav" ,aria-controls="navbarNav" ,aria-expanded="false",
aria-label="Toggle navigation")
span.navbar-toggler-icon
div#navbarNav.collapse.navbar-collapse
ul.navbar-nav
li.nav-item
a.nav-link(href="/") 商城
li.nav-item.active
a.nav-link(href="/admin/add-product") 添加产品

main.container.p-5
h1 我的产品
if prods.length > 0
div.row
each product in prods
div.col-md-4.p-2
div.card(style="width: 18rem;")
img.card-img-top(src="https://miro.medium.com/max/1200/1*m5RYM_Wkj4LsZewpigV5tg.jpeg",alt="产品图片")
div.card-body
h5.card-title #{product.title}
p.card-text 产品详情介绍信息,该课程讲解十分细致,各个知识点都有所涉及。
p ¥29.99
a.btn.btn-primary(href="#") 加入购物车
else
div.alert.alert-danger(role="alert") 暂无产品

恩...他好像有一種python的感覺(笑)。

附上html轉pug得線上工具:https://pughtml.com

pug使用動態網頁

那大概知道pug的代碼風格後,要來提到動態網頁的部分了。恩...可能我是小菜雞的緣故,目前碰到的還是以字串、變數或陣列為主。

先來看一下這一段js代碼:

// adminData 為一個array
const adminData = require("./admin");

router.get("/", (req, res, next) => {
const products = adminData.products;
// 要傳出去的東西
res.render("shop", { prods: products, docTitle: "商城" });
});

module.exports = router;

我在這一段代碼中主要傳兩個東西,一個是陣列prods,一個是字串docTitle,那傳到的位置為shop.pug(笑死我剛剛打成png,圖然感覺這個單字好可愛,一定是我打錯的部分)

接著來看png的地方吧

// 傳遞字串這樣寫
title #{docTitle}

// 陣列的話主要是要一個一個輸出,這邊要使用each...in...
each product in prods
div.col-md-4.p-2
div.card(style="width: 18rem;")
img.card-img-top(src="https://miro.medium.com/max/1200/1*m5RYM_Wkj4LsZewpigV5tg.jpeg",alt="产品图片")
div.card-body
h5.card-title #{product.title}
p.card-text 产品详情介绍信息,该课程讲解十分细致,各个知识点都有所涉及。
p ¥29.99
a.btn.btn-primary(href="#") 加入购物车

Include的方式去封裝pug

在每一次轉html轉pug的時候,是不是有一些東西會重複寫(沒錯~),而工成師的經隨就是:懶!!!(不是我說的,是我們老師說的!!!),因此我們可以使用include的方式去封裝pug

要封裝的部分用一個開一個位置給他

// includes/header.pug 
<!DOCTYPE html>
html(lang="en")
head
meta(charset="UTF-8")
meta(name="viewport", content="width=device-width, initial-scale=1.0")
title #{docTitle}
link(rel="stylesheet", href="/css/bootstrap.min.css")

接著在每一個需要用到它的地方:

include includes header.pug 
... 其他代碼



EJS(Embedded JavaScript templates)

用於在Node.js應用程式中生成動態HTML內容。它允許你將JavaScript嵌入到HTML中,從而可以根據資料動態生成HTML內容。

指令: npm install ejs
設定:要在你的伺服器上加上這兩行
app.set('view engine', 'ejs');
app.set('views', 'views');

那ejs我是把它區分成三種,照理來說是混搭使用,那為了清楚展示,我故意差開寫:

  1. <% js條件 %> 在裡面寫js的條件判斷式
<!DOCTYPE html>
<html>
<head>
<title>Conditional Example</title>
</head>
<body>
<% if (showMessage) { %>
<h1>Message is shown!</h1>
<% } else { %>
<h1>Message is not shown!</h1>
<% } %>
</body>
</html>
  1. <%= title %> 後台有東西要傳入,加等號
<!DOCTYPE html>
<html>
<head>
<title><%= title %></title>
</head>
<body>
<h1><%= message %></h1>
</body>
</html>
  1. <%- %> 類似pug的封裝
<!DOCTYPE html>
<html>
<head>
<title>Unescaped Content Example</title>
</head>
<body>
<div>
<h1>Unescaped Content Example</h1>
<div class="content">
<%- htmlContent %>
</div>
</div>
</body>
</html>

<%- htmlContent %> 裡面就是裝載著封裝的html

這樣的方式也可以用在express框架的router

app.get('/', (req, res) => {
const htmlContent = '<p>This is <strong>unescaped</strong> content.</p>';
res.render('unescaped', { htmlContent });
});

🥰那~~以上是本文所分享的內容。如果您發現任何錯誤或遺漏,請不吝賜教。

4會員
10內容數
留言0
查看全部
發表第一個留言支持創作者!
W. C. Chen的沙龍 的其他內容
新版Input System 要先來調整設定: (如果日後發現移動不了,可能是這邊有出問題,可以把這邊視為一個檢查點) 下載Input System 在script中的寫法: (這邊的功能是讀取移動的值而已,主要目的是讓unity讀到movement,絕對不是托篇幅的拉🥺) using
今天在練習寫網頁時,剛好要來有做到Dark Mode 的功能,那順便來記錄一下做法~ 首先要先知道Dark Mode的運作原理。是如何知道你現在是Light Mode還是Dark Mode呢? 😀就是這邊拉~當你按下按鈕時,javascript 的toggle()去為<html>增加dark標
當然指令不是背的,所以第一步就是要打開Tailwind CSS的官網。 Installation - Tailwind CSS 主要的方式有CLI跟CDN,這裡使用的方式前者。 Install Tailwind CSS npm install -D tailwindcss npx tai
這篇要來談談網站部屬的方式 Netlify 提供100GB的空間給大家做使用~ 一定事先註冊登入的拉~,那我登入的方式為github。以下就是你會看的頁面。 上傳完後,就回到Netlify,選擇github,並選取剛剛建立好的專案。 接著進行部屬網站前的先置(但我自己基本是除了網站名稱,
本文將引導您使用簡單的 Header 組件,學習如何使用 render 和 screen 來渲染和查詢元素。我們將探索如何測試文字和字元計數功能,並使用 userEvent 模擬使用者操作。了解如何使用斷言來確保測試結果正確。同時,我們將處理包含 fetch 的異步測試,並介紹 waitFor 函數
新版Input System 要先來調整設定: (如果日後發現移動不了,可能是這邊有出問題,可以把這邊視為一個檢查點) 下載Input System 在script中的寫法: (這邊的功能是讀取移動的值而已,主要目的是讓unity讀到movement,絕對不是托篇幅的拉🥺) using
今天在練習寫網頁時,剛好要來有做到Dark Mode 的功能,那順便來記錄一下做法~ 首先要先知道Dark Mode的運作原理。是如何知道你現在是Light Mode還是Dark Mode呢? 😀就是這邊拉~當你按下按鈕時,javascript 的toggle()去為<html>增加dark標
當然指令不是背的,所以第一步就是要打開Tailwind CSS的官網。 Installation - Tailwind CSS 主要的方式有CLI跟CDN,這裡使用的方式前者。 Install Tailwind CSS npm install -D tailwindcss npx tai
這篇要來談談網站部屬的方式 Netlify 提供100GB的空間給大家做使用~ 一定事先註冊登入的拉~,那我登入的方式為github。以下就是你會看的頁面。 上傳完後,就回到Netlify,選擇github,並選取剛剛建立好的專案。 接著進行部屬網站前的先置(但我自己基本是除了網站名稱,
本文將引導您使用簡單的 Header 組件,學習如何使用 render 和 screen 來渲染和查詢元素。我們將探索如何測試文字和字元計數功能,並使用 userEvent 模擬使用者操作。了解如何使用斷言來確保測試結果正確。同時,我們將處理包含 fetch 的異步測試,並介紹 waitFor 函數
你可能也想看
Google News 追蹤
Thumbnail
這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
Thumbnail
11/20日NVDA即將公布最新一期的財報, 今天Sell Side的分析師, 開始調高目標價, 市場的股價也開始反應, 未來一週NVDA將重新回到美股市場的焦點, 今天我們要分析NVDA Sell Side怎麼看待這次NVDA的財報預測, 以及實際上Buy Side的倉位及操作, 從
Thumbnail
Hi 大家好,我是Ethan😊 相近大家都知道保濕是皮膚保養中最基本,也是最重要的一步。無論是在畫室裡長時間對著畫布,還是在旅途中面對各種氣候變化,保持皮膚的水分平衡對我來說至關重要。保濕化妝水不僅能迅速為皮膚補水,還能提升後續保養品的吸收效率。 曾經,我的保養程序簡單到只包括清潔和隨意上乳液
Thumbnail
咦!奇怪, 怎麼網頁用一用就出現以下的畫面了, 到底是怎麼回事啊? 不用慌張, 讓我們仔細看看中間的「HTTP ERROR 431」,看到這樣的錯誤代碼, 相信心中隱約已經知曉我們的請求標頭內容太大了, 超過限制導致這樣的問題發生, 讓我們先詳細查閱這樣的錯誤訊息吧! 📚 https://
Thumbnail
研究這個部分起因是因為公司某些功能服務是使用AWS Serverless來處理計算,故而外訂立了三個月學習NodeJS的計畫,並開始試著實作Serverless服務,Jest測試還沒研究到,下次再補充說明。
Thumbnail
NodeJS 學習來到 file systems 操作,在文檔操作上有分為同步跟異步的處理,接下來分階段介紹操作函數
Thumbnail
最近跟著影片學習NodeJS,第一部分先學習對Buffer的處理跟理解,以下是對於NodeJS Buffer的理解筆記
Thumbnail
NodeJS作用? NodeJS 作為一個後端程式語言,與伺服器交互,能夠開發服務器應用、開發工具類應用,例如:Webback、Vite 這些好用工具,或是透過NodeJS的electron框架開發桌面端應用,而常見的桌面端應用如 VScode
一般來說我們如果將程式運行在console上,只要用ctrl + c 之類的強制中斷方式就能讓程式中止,但如果我們想要在程式運行到一半時,偵測到某些例外狀況就離開程式,可以怎麼做呢? nodejs核心模組提供了process.exit()的方法可以讓程式強制中止,但使用了這個功能之後,我們尚未完成的
Thumbnail
由於Javascript本身設計就適合於單線程的應用, 但一般後端應用程式都會支援多個服務來處理client的請求, nodejs中也提供了cluster模組來達成此功能。 Cluster的原理很簡單,由於每個Process都只能用單核心的CPU來運行,那麼就多開幾個來幫忙處理吧! 而這個Clust
參考 : https://www.w3school.com.cn/jsref/jsref_replace.ASP 取代字串方式 取代找到的第一個 全取代 str.replace(/原始字詞/g, '新字詞');
Thumbnail
這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
Thumbnail
11/20日NVDA即將公布最新一期的財報, 今天Sell Side的分析師, 開始調高目標價, 市場的股價也開始反應, 未來一週NVDA將重新回到美股市場的焦點, 今天我們要分析NVDA Sell Side怎麼看待這次NVDA的財報預測, 以及實際上Buy Side的倉位及操作, 從
Thumbnail
Hi 大家好,我是Ethan😊 相近大家都知道保濕是皮膚保養中最基本,也是最重要的一步。無論是在畫室裡長時間對著畫布,還是在旅途中面對各種氣候變化,保持皮膚的水分平衡對我來說至關重要。保濕化妝水不僅能迅速為皮膚補水,還能提升後續保養品的吸收效率。 曾經,我的保養程序簡單到只包括清潔和隨意上乳液
Thumbnail
咦!奇怪, 怎麼網頁用一用就出現以下的畫面了, 到底是怎麼回事啊? 不用慌張, 讓我們仔細看看中間的「HTTP ERROR 431」,看到這樣的錯誤代碼, 相信心中隱約已經知曉我們的請求標頭內容太大了, 超過限制導致這樣的問題發生, 讓我們先詳細查閱這樣的錯誤訊息吧! 📚 https://
Thumbnail
研究這個部分起因是因為公司某些功能服務是使用AWS Serverless來處理計算,故而外訂立了三個月學習NodeJS的計畫,並開始試著實作Serverless服務,Jest測試還沒研究到,下次再補充說明。
Thumbnail
NodeJS 學習來到 file systems 操作,在文檔操作上有分為同步跟異步的處理,接下來分階段介紹操作函數
Thumbnail
最近跟著影片學習NodeJS,第一部分先學習對Buffer的處理跟理解,以下是對於NodeJS Buffer的理解筆記
Thumbnail
NodeJS作用? NodeJS 作為一個後端程式語言,與伺服器交互,能夠開發服務器應用、開發工具類應用,例如:Webback、Vite 這些好用工具,或是透過NodeJS的electron框架開發桌面端應用,而常見的桌面端應用如 VScode
一般來說我們如果將程式運行在console上,只要用ctrl + c 之類的強制中斷方式就能讓程式中止,但如果我們想要在程式運行到一半時,偵測到某些例外狀況就離開程式,可以怎麼做呢? nodejs核心模組提供了process.exit()的方法可以讓程式強制中止,但使用了這個功能之後,我們尚未完成的
Thumbnail
由於Javascript本身設計就適合於單線程的應用, 但一般後端應用程式都會支援多個服務來處理client的請求, nodejs中也提供了cluster模組來達成此功能。 Cluster的原理很簡單,由於每個Process都只能用單核心的CPU來運行,那麼就多開幾個來幫忙處理吧! 而這個Clust
參考 : https://www.w3school.com.cn/jsref/jsref_replace.ASP 取代字串方式 取代找到的第一個 全取代 str.replace(/原始字詞/g, '新字詞');