뷰를 작성하다보면, header나 footer처럼 반복되는 영역이 있을 수 있다. express-ejs-layouts를 통해 레이아웃을 만들고, 반복되는 영역을 재작성하는 일을 줄일 수 있다.
$ npm install express-ejs-layouts
const express = require('express');
const expressLayouts = require('express-ejs-layouts');
const app = express();
app.set('view engine', 'ejs');
app.use(expressLayouts);
// ...
require('express-ejs-layouts')를 미들웨어로 등록해주면 된다. 또한 layout.ejs 파일을 view 폴더에 위치시키면 된다. 페이지를 렌더링할 때, layout.ejs를 렌더링 해주며 경로에 맞게 렌더링 해주는 view 파일의 내용을 설정한 위치에 넣어준다.
layout 파일
<%- bar %>
<%- foo %>
<%- body %>
view 파일
<p> section-body </p>
<%- contentFor('foo') %>
<p> section-foo </p>
<%- contentFor('bar') %>
<p> section-bar </p>
Render
section-bar
section-foo
section-body
contentFor 구문으로 Content의 이름을 지정해 줄 수 있으며, layout 파일에 지정된 구역으로 해당 Content가 들어간다. body는 기본으로 등록된 영역이며, contentFor 구문으로 Content의 이름을 지정해주지 않으면 body로 등록된다.
위 예시의 layout에서 특정 Content를 불러올 때 <%- content %> 구문으로 작성하였다. 위처럼 작성할 시, 해당 Content가 없으면 에러가 발생한다. defineContent구문으로 작성할 시, 해당 Content가 없는 경우 ''로 대체되기에 에러가 발생하지 않는다. 선택적으로 넣거나 빼고 싶은 Content가 있는 경우 사용하면 좋을것 같다.
layout 파일
1
<%- defineContent('a') %>
2
<%- defineContent('b') %>
3
view 파일
<%- contentFor('a') %>
1.5
Render
1
1.5
2
3
Content를 불러올 때, Script 구문들을 따로 추출할 수 있다. 다음 코드를 추가해주자.
app.set("layout extractScripts", true);
이후 모든 파일에 대해, 스크립트 구문을 따로 추출하여 <%- script %>로 옮겨준다.
layout 파일
something<script>somejs</script>something
view 파일
<body>
<%- body %>
<%- script %>
</body>
Render
<body>
somethingsomething
<script>somejs</script>
</body>
다음처럼 옵션을 통해 개별적으로 설정해줄 수 있다.
req.render('view', { extractScripts: true });
app.set("layout extractStyles", true);
Script Blocks Extraction과 동일하게 작동한다.
<link rel="stylesheet" ...>와 <style ...> 태그에 대해 적용된다.extractStyles 옵션명으로 설정가능하다.<%- style %>을 통해 불러올 수 있다.app.set("layout extractMetas", true);
Script Blocks Extraction과 동일하게 작동한다.
<meta ...>와 <meta .../> 태그에 대해 적용된다.extractMetas 옵션명으로 설정가능하다.<%- meta %>을 통해 불러올 수 있다.기본값으로는 layout.ejs 파일이 레이아웃 파일로 사용된다. 만약 다른 파일을 사용하고 싶다면, express app settings의 layout 속성을 변경하면 된다.
app.set('layout', 'layouts/layout');
기본값으로 설정된 레이아웃 대신 다른 레이아웃을 사용하고 싶다면, locals 객체의 layout에 해당 레이아웃을 설정하면 된다.
app.get('/', (req, res) => {
res.render('the-view', { layout: 'specific-layout' });
}