HTML을 작성하기 위해서 컨트롤러에서 res.send()메소드로 보내주어도 되만 이렇게 작성했을 시에는 코드가 길어지고 유지보수가 매우 힘들어지며 가독성도 떨어진다.
이를 위해 Express문서 Guide에 Using template engines with Express에보면 다른 많은 Template Engine이 있지만 그 중 Pug를 소개하고 있다.
Pug
https://pugjs.org/api/getting-started.html
Getting Started – Pug
Getting Started Installation Pug is available via npm: $ npm install pug Overview The general rendering process of Pug is simple. pug.compile() will compile the Pug source code into a JavaScript function that takes a data object (called “locals”) as an
pugjs.org
pug를 설치하고 pug사용한다는 것을 선언하기 위해 server.js에 아래 문장을 추가해준다.
app.set("view engine", "pug");
app.set("views", "./views");
이렇게 setting을 해주게 되면 ./views라는 디렉토리에 pug 템플릿을 만들어 사용을 해주어야한다.
주의할 점
API reference 문서에 따르면 views의 파일은 process.cwd()+'./view'로 추적이된다. process.cwd()는 node가 실행되는 rootfile이 있는 곳 즉 package.json이 기준점이 된다 . 따라서 "./views"를 "./src"에 두었다면 밖으로 빼주면 인식이 pug가 인식이 될것이다.
만약 src 폴더 안에 두고 싶다면
app.set("views", process.cwd() + "/src/views");
같이 설정한다.
"./views"에 pug 파일을 만들고 이것을 렌더링하기 위해 controller에서 res.render("파일 이름")을 작성하면 된다.
정리하자면 다음과 같다
//server.ts js
import express from "express";
import morgan from "morgan";
import globalRouter from "./routers/globalRouter";
const PORT = 5040;
const app = express();
app.set("view engine", "pug");
app.set("views", process.cwd() + "/src/views");
/* global middelware */
app.use(morgan("dev"));
/* routers */
app.use("/", globalRouter);
const handleListen = () =>
console.log("✅ Server is Listenin on http://localhost:5040");
app.listen(PORT, handleListen);
////////////
//globalRouter.ts js
import express from "express";
import { home } from "../controllers/globalController";
const globalRouter = express.Router();
globalRouter.get("/", home);
export default globalRouter;
//////////
//globalController.js
export const home = (req, res) => {
return res.render("home", { title: "hello" });
};
////////////
// ./views/home.pug
doctype html
html(lang="ko")
head
meta(charset="UTF-8")
meta(name="viewport", content="width=device-width, initial-scale=1.0")
title Document
body
h1=title
footer= new Date().getFullYear()
footer #{new Date().getFullYear()} ©
Includes
include로 컴포넌트처럼 pug파일을 추가 할 수 있다. 또한 mark down 파일도 포함시켜 html로 변환이 가능하다.
//home.pug
doctype html
html(lang="ko")
head
meta(charset="UTF-8")
meta(name="viewport", content="width=device-width, initial-scale=1.0")
title Document
body
h1= title
include partials/footer
// ./partials/footer.pug
footer
p #{new Date().getFullYear()} © SoundStream
Inheritance : Extends and Block
Extends를 쉽게 설명하자면 Layout라고 말할 수 있겠다. 반복되는 HTML을 Layout에 작성하여 불와서 작성할 수 있게 만들 수 있다.
또한 block을 지정해서 원하는 템플릿에서 불러와 작성할 수 도 있다.
// ./layout/layout.pug
doctype html
html(lang="ko")
head
meta(charset="UTF-8")
meta(name="viewport", content="width=device-width, initial-scale=1.0")
title Document
body
h1= title
block contents
include ../partials/footer
// ./home.pug
extends layout/layout
block contents
h1 this is homepage
Interpolation
pug는 템플릿엔진이기도 하지만 javascript로 이루어져 있어서 변수 생성도 가능하고 backend와 변수로 소통도 가능하다.
// layout.pug
- const hi = "hahahoho"
doctype html
html(lang="ko")
head
meta(charset="UTF-8")
meta(name="viewport", content="width=device-width, initial-scale=1.0")
title #{pageTitle} | SoundStream
body
h2= hi
block contents
include ../partials/footer
//globalControllers.js
import { ExpressRouter } from "../types/type";
export const home: ExpressRouter = (req, res) => {
return res.render("home", { pageTitle: "HOME" });
};
Conditionals
또한 pug는 if문을 작성할 수 있다. 또한 controller와 연동해서 사용도 가능하다 backend에서 object를 보내 그것을 읽어 내는 것도 가능하다.
//layout.pug
doctype html
html(lang="ko")
head
meta(charset="UTF-8")
meta(name="viewport", content="width=device-width, initial-scale=1.0")
title #{pageTitle} | SoundStream
body
header
include ../partials/navigation
block contents
include ../partials/footer
// navigation.pug
nav
ul
if user
li
a Logout
li
a My Page
else
li
a LogIn
//globalControllers.js
import { ExpressRouter } from "../types/type";
export const home: ExpressRouter = (req, res) => {
return res.render("home", { pageTitle: "HOME", user: true });
};
Iteration
iteration은 쉽게 말하자면 react에서 map 메소드와 vue에서 v-for 라고 생각하면 된다. 또한 backend에서 object를 보내면 읽어 낼수 있다.
- const a = [1,2,3,4,5]
- const b = {1:"hoho",2:"haha",3:"hehe"}
- const c = []
ul
each number,index in a
li=number+`${index}`
each number,key in b
li=`${number} ${key}`
each number,key in c
li=`${number} ${key}`
else
li Nothing
each number,key in c.length >0 ? c :['no value']
li=`${number} ${key}`
// controller.js
import { ExpressRouter } from "../types/type";
export const home: ExpressRouter = (req, res) => {
const movies = [
{ id: 1, title: "hoho", desc: "fhj" },
{ id: 2, title: "heeh", desc: "werte" },
{ id: 3, title: "hahah", desc: "ryftujkty" },
{ id: 4, title: "asdf", desc: "asfdasdf" },
];
return res.render("home", { pageTitle: "HOME", movies });
};
// **.pug
each movie in movies
li
p movie.id
p movie.titlr
p movie.desc
Mixins
interation을 사용하다보면 반복되는 사용이 많아질 수가 있다. 이럴 때 mixins를 사용하면 아주 유용하다. mixins는 function과 비슷하다. Mixins pug파일을 만들어주고 iteration과 object를 보내주면 반복되는 결과물을 쉽게 얻어 낼수 있다.
// controller.js or ts
import { ExpressRouter } from "../types/type";
export const home: ExpressRouter = (req, res) => {
const videos = [
{ id: 1, title: "hoho", desc: "fhj" },
{ id: 2, title: "heeh", desc: "werte" },
{ id: 3, title: "hahah", desc: "ryftujkty" },
{ id: 4, title: "asdf", desc: "asfdasdf" },
];
return res.render("home", { pageTitle: "HOME", videos });
};
// videoMixin.pug
mixin videoMixin(video)
div
ul
li #{video.id}
li #{video.title}
li #{video.desc}
//layout.pug
include ../mixins/videoMixin
doctype html
html(lang="ko")
head
meta(charset="UTF-8")
meta(name="viewport", content="width=device-width, initial-scale=1.0")
title #{pageTitle} | SoundStream
body
header
include ../partials/navigation
each video in videos
+videoMixin(video)
block contents
include ../partials/footer
'CODING PRACTICE > NodeJS' 카테고리의 다른 글
NodeJS / Express Back to Front__005 (CRUD / Update, Delete ) (0) | 2024.01.02 |
---|---|
NodeJS / Express Back to Front__004 (CRUD / Create) (0) | 2023.12.29 |
NodeJS / Express Back to Front__003 (DataBase / MongoDB) part.1 (1) | 2023.12.27 |
NodeJS / Express Back to Front__002 (Router) (0) | 2023.12.26 |
NodeJS / with ExpressBack to Front __001 (1) | 2023.12.22 |