Views&Static
這章節的教學將會包含如何使用使用views中間件渲染模板,動態的產生網頁內容。另一個主題是設定static中間件,讓我們可以簡單的傳送一些靜態物件,如圖片、音效、影片、腳本等等。
Views
前面幾個教學到現在我們總是簡單的回傳一些字串給前端
router.get('/', async (ctx) => {
ctx.body = "<h1>Hello Koa</h1>";
});
在第一章的時候,我們也曾經使用readFile
的方式,載入預寫好的html檔案,但是這種方式難以架構一個具有大型規模的網站。我們網頁上的資訊必須動態產生,如先讀取資料庫後動態的調整頁面的內容。如果我們用傳統的方式的話,光是字串處理的時間就會消磨掉一大半。幸運的是在Javascript龐大的模組庫中,我們有許多種模板引擎可以進行選擇。所謂的模板就是,我們先預定好一些html,並且在其中設定幾個空格,我們僅需要告訴模板引擎這些空格該填些什麼,模板引擎會幫我們把html渲染好,回傳回前端。
本文中使用的模板語言是pug(jade),但是不會特別的去說明如何撰寫pug
詳細pug的撰寫方法可以參考 Pug getting Started
安裝koa-views以及pug
yarn add koa-views @types/koa-views
準備需要渲染的模板
這個部分我們預計做出一個讓YouTube循環播放的網頁。當瀏覽/loop/YJSpGXxkCqE
時我們會重複播放YJSpGXxkCqE
這個影片。
首先我們在專案底下新增一個views
的資料夾,這個資料夾是專門用來放置模板的。
mkdir views
先來觀察一下內嵌循環播放的html長怎樣。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Youtube Looper</title>
</head>
<body>
<h1>Awesome Youtube Looper</h1>
<iframe src="https://www.youtube.com/v/YJSpGXxkCqE?version=3&loop=1&playlist=YJSpGXxkCqE" frameborder="0"></iframe>
</body>
</html>
觀察第11行iframe的src參數https://www.youtube.com/v/YJSpGXxkCqE?version=3&loop=1&playlist=YJSpGXxkCqE
,我們需要動態調整的地方為兩個YJSpGXxkCqE
的部分。
因此我們撰寫一個模板looper.pug
放置在views資料夾
<!DOCTYPE html>
html(lang="en")
head
meta(charset="UTF-8")
meta(name="viewport", content="width=device-width, initial-scale=1.0")
meta(http-equiv="X-UA-Compatible", content="ie=edge")
title My awesome youtube looper
body
h1 Awesome Youtube Looper
iframe(src=`https://www.youtube.com/v/${VideoID}?version=3&loop=1&playlist=${VideoID}`, frameborder="0" allowfullscreen)
這個模板會根據我們傳送給他不同的VideoID
變數,渲染出不同的網頁。
使用koa-views中間件
既然有了模板,那我們可以使用routing
// views.ts
import Koa = require('koa');
import Router = require('koa-router');
import Path = require('path');
import Views = require('koa-views');
const app = new Koa();
const router = new Router();
app.use(Views(Path.join(__dirname, 'views'), {
extension: 'pug', // 預設模板的副檔名為.pug
map: {
pug: 'pug', // 映射.pug檔到pug模板引擎
},
}));
router.get('/loop/:VideoID', async (ctx) => {
await ctx.render('index', { // 因為我們有設定預設副檔名為.pug,所以不需要打index.pug
VideoID: ctx.params.VideoID, // 將變數傳給模板引擎
});
});
app.use(router.routes()).use(router.allowedMethods());
app.listen(3000);
References:
1. queckezz/koa-views
2. koajs/static 3. pug 所有範例中的程式碼皆放置在koa-tutorial-sample專案中