EJS는 html의 태그처럼 자바스크립트 내용을 삽입할 수 있다.
일반 html 파일은 무조건 <script> 태그를 사용해서 분리시켜야하지만, EJS는 지정된 태그를 통해 스트립트 내용을 하나의 요소처럼 사용될 수 있게 한다.
또한, 서버에서 보낸 변수를 가져와 사용할 수 있다!
기본 세팅은 Node.js의 Express를 사용한다.
템플릿 엔진: 문법과 설정에 따라 파일을 html 형식으로 변환시키는 모듈
Embedded JavaScript의 약자로 자바스크립트가 내장되어 있는 html 파일
npm install ejs
app.set("view engine", "ejs")
EJS 엔진에서는 기본적으로 views 폴더에 템플릿 파일 저장
app.set("views", "./views")
템플릿 파일에서 사용하는 정적 파일 제공 (CSS, JS, 이미지 등)
app.use(express.static('public'))
ejs에는 자바스크립트를 내장시킬 수 있는 2가지 태그가 있다.
가장 기본은 <%%>이고, 이 사이에 자바스크립트 내용을 넣으면 된다.
<%-include('view의 파일')%>
<%-include('navbar') %> 으로 불러오면 된다.<%= 변수 %>
res.render(view, data)로 넘긴 값을 템플릿에서 바로 사용할 수 있다. // 예: 컨트롤러
app.get('/profile', (req, res) => {
res.render('profile', {
title: '프로필',
user: { username: 'dyeon', nickname: '다연' },
posts: [{ id: 1, text: 'hi' }, { id: 2, text: 'hello' }]
})
})
<!-- profile.ejs -->
<h1><%= title %></h1>
<p>닉네임: <%= user.nickname %></p>
<ul>
<% posts.forEach(post => { %>
<li><%= post.text %></li>
<% }) %>
</ul>
// views/login.ejs
<%-include('navbar') %>
<main>
<section class="login-section">
<div class="login-container">
<h1>로그인</h1>
<form action="/login">
<div class="form-group">
<label for="username">아이디</label>
<input type="text" id="username" name="username" required>
</div>
<div class="form-group">
<label for="password">비밀번호</label>
<input type="password" id="password" name="password" required>
</div>
<button type="submit" class="login-submit-btn">로그인</button>
</form>
</div>
</section>
</main>
html 코드를 적었으니까 이걸 보여줘야한다.
/login 루트 경로 접속 시 위의 코드인 login.ejs가 로그인 화면으로 나타나도록 한다.
loginController.js 파일을 생성getLogin 함수를 구현하고 모듈로 내보냄.// controllers/loginController.js
const getLogin = (req, res) => {
res.render('login')
}
module.exports = {
getLogin
}
loginRoutes.js 파일을 생성함.getLogin 함수가 실행되도록 라우팅을 설정하고 라우터를 내보냄.// routes/loginRoutes.js
const express = require('express')
const router = express.Router()
const loginController = require('../controllers/loginController')
router.get('/login', loginController.getLogin)
module.exports = router
app.js에서 로그인 라우트가 실행되도록 추가app.use('/', require('./routes/loginRoutes'))
사용자가 아이디와 비밀번호 입력 후 로그인 클릭 시 POST 방식으로 서버에 정보를 보내도록 한다.
login.ejs 폼 태그의 method를 post로 설정하고 action을 /login 경로로 지정<form action="/login" method="post" class="login-form">
loginController.js에 추가postLogin 함수를 작성하고, 요청 본문에서 사용자 아이디와 비밀번호를 가져옴// POST /login
const postLogin = (req, res) => {
const { username, password } = req.body
if(username === 'admin' && password === '1234') {
res.redirect('/')
} else {
res.send('로그인 실패')
}
}
postLogin 함수를 가져와 POST 방식 /login 요청 시 실행되도록 설정함.const { getLogin, postLogin } = require('../controllers/loginController')
router.route('/login').get(getLogin).post(postLogin)
사용자의 로그인 정보를 저장하고 navbar나 페이지에서 로그인 여부에 따라 분기처리를 해주어야 한다.
로그인 상태 관리를 위해 세션없이 쿠키로 로그인 상태를 관리하고, 미들웨어에서 로그인 유저를 res.locals.user에 넣으면 모든 EJS에서 사용이 가능하다.
// controllers/loginController.js (성공 시)
res.cookie('user', JSON.stringify({ username: user.username, nickname: user.nickname }), { httpOnly: false })
// app.js
const cookieParser = require('cookie-parser')
app.use(cookieParser())
app.use((req, res, next) => {
res.locals.user = req.cookies.user ? JSON.parse(req.cookies.user) : null
next()
})
<% if (locals.user) { %>
<span class="user-name">안녕하세요, <%= user.nickname %>님!</span>
<button class="write-btn" href="#">글쓰기</a>
<form action="/logout" method="post">
<button class="logout-btn" type="submit">로그아웃</button>
</form>
<% } else { %>
<form action="/login" method="get">
<button class="login-btn" type="submit">로그인</button>
</form>
<form action="/signup" method="get">
<button class="signup-btn" type="submit">회원가입</button>
</form>
<% } %>