뷰를 작성하다보면, 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' });
}