ejs... 요즘 쓰는지 모르겠음 🧐 ㄱㅊ 모르는것보다 아는게 낫다~~~
EJS는 Embedded Javascript를 뜻한다. HTML 내부에 자바스크립트를 사용할 수 있게 해주는 템플릿 언어/엔진이다.
템플릿 양식과 특정 데이터 모델에 따른 입력 자료를 합성하여 결과 문서를 출력하는 소프트웨어
런타임에 템플릿 엔진이 템플릿 파일 내부의 변수들을 실제 데이터로 변환해서 클라이언트쪽으로 전송한다. 즉, HTML에 동적인 데이터를 삽입해준다
문법 | 설명 |
---|---|
<% | 'Scriptlet' 태그, 제어 흐름용, 출력 없음 |
<%_ | 'Whitespace Slurping' Scriptlet 태그는 그 앞에 있는 모든 공백을 제거 |
<%= | 템플릿에 값을 출력(HTML 이스케이프 처리) |
<%- | 이스케이프 처리되지 않은 값을 템플릿에 출력 |
<%# | 주석 태그, 실행 없음, 출력 없음 |
<%% | 리터럴 '<%' 출력 |
%> | 일반 종료 태그 |
-%> | 트림 모드('newline slurp') 태그, 줄 바꿈 다음에 오는 트림 |
_%> | '공백 슬러핑' 종료 태그, 그 뒤의 모든 공백 제거 |
.
├── app.js
├── node_modules
├── package-lock.json
├── package.json
├── public
│ └── css
└── views
├── about.ejs
├── compose.ejs
├── contact.ejs
├── home.ejs
├── partials
<%- include("partials/header") -%>
<h1>HOME</h1>
<%= homeStartingContent %>
<%- include("partials/footer") -%>
위와 같은 형태로 다른 페이지에도 동일하게 적용
const express = require('express');
const bodyParser = require('body-parser');
const ejs = require('ejs');
const app = express();
// homeStartingContent, aboutContent, contactContent 생략
app.set('view engine', 'ejs'); // 엔진 설정
app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.static('public'));
app.get('/', (req, res) => {
res.render('home', { homeStartingContent});
});
app.get('/about', (req, res) => {
res.render('about', { aboutContent });
});
app.get('/contact', (req, res) => {
res.render('contact', { contactContent });
});
app.get('/compose', (req, res) => {
res.render('compose');
});
app.listen(3000, () => {
console.log('Server started on port 3000');
});
body-parser 모듈의 역할
데이터(client에서 post로 보내준 데이터)들을 자동으로 파싱해주어서, 실제로 필요한 부분인 body부분을 추출한다.
app.get("/exampleUrl/:<paramName>", (req, res)=>{
// Access req.params.paramName
});
객체 형태로 전달하면 된다. {key:value}
const homeStartingContent = 'hello!';
app.get('/', (req, res) => {
res.render('home', { homeStartingContent });
});
home.ejs
<h1>HOME</h1>
<!-- key 이름 동일하게 !-->
<%= homeStartingContent %>
about, contact 페이지 반복
compose.ejs
<%- include("partials/header") -%>
<h1>Compose</h1>
<form action="/compose" method="post">
<div class="form-group">
<label>Title</label>
<input type="text" name="postTitle" class="form-control" /><br />
<label>Post</label>
<textarea
name="postBody"
cols="30"
rows="10"
class="form-control"
></textarea>
</div>
<div class="text-center">
<button class="btn btn-outline-success " type="submit" name="button">등록</button>
</div>
</form>
<%- include("partials/footer") -%>
app.js
const posts = [];
app.get('/', (req, res) => {
res.render('home', { homeStartingContent, posts });
});
app.post('/compose', (req, res) => {
const post = {
title: req.body.postTitle,
content: req.body.postBody,
};
posts.push(post);
res.redirect('/');
});
내용의 일부만 출력하도록 substring
사용한다.
home.ejs
<% posts.forEach(post => { %>
<h1><%=post.title%></h1>
<p>
<%=post.content.substring(0, 100) + " ..."%>
</p>
<% }) %>
post.ejs 파일 생성
<%- include("partials/header"); -%>
<%- include("partials/footer"); -%>
home.ejs 파일 내용 수정
간략하게 나타난 글 내용 옆에 <a>
태그 추가하여 전체 내용 페이지로 이동할 수 있도록 한다. 게시글의 제목을 이용하여 라우팅
<a href="/posts/<%=post.title%>">Read More</a>
app.js 파일에 내용 추가
lodash 모듈 사용
url 파라미터를 이용 (:postName
, req.params.postName
)
req.params
에 접근하기 위해서 url에 콜론(:)을 이용하여 변수이름(?)을 설정해준다.
const _ = require('lodash');
app.get('/posts/:postName', function (req, res) {
const requestedTitle = _.lowerCase(req.params.postName);
posts.forEach(function (post) {
const storedTitle = _.lowerCase(post.title);
if (storedTitle === requestedTitle) {
res.render('post', {
title: post.title,
content: post.content,
});
}
});
});