EJSとは
EJSはテンプレートエンジンと呼ばれるNode.jsのパッケージの1つで、JavaScriptとHTMLを混ぜた感じで書くことができる
EJS導入でメリットとして感じたこと
・パーシャルでファイルを分割できるので管理が楽。また、パーシャルで作成したファイルをインクルードで呼び出して使いまわせる。(_head、_header、_footerなど)
・変数を使うことでHTMLページ内のサイト名、<title>、<meta>、<h1>、その他色々なサイト共通の単語を使い回せる。
・if文で状態管理ができる。(ナビゲーションなど)
EJSの基本的な書き方
<% %>:Javascriptの変数の宣言やifやforなどのjavascriptの記述をする。
<%= %>:囲われた中にあるejsの変数の出力を行う(エスケープする)
<%- %>:囲われた中にあるejsの変数の出力を行う(エスケープしない)
ejs内でコメントアウト
<%# htmlに出力されない %>
変数を宣言する
index.ejs
<% let text = "テキスト" %>
変数の呼び出し
index.ejs
<% let text = "テキスト" %>
<p><%- text %></p>
出力html
<p>テキスト</p>
if文
index.ejs
<% let page = "top" %>
<% if(param !== 'top'){ %>
<p>トップページ</p>
<% }else{ %>
<p>下層ページ</p>
<% } %>
出力html
<p>トップページ</p>
for文
index.ejs
let nameList = [
"名前1",
"名前2",
"名前3"
];
<% for (var i = 0; i < nameList.length; i++) { %>
<li><%= i+1 %>:<%= nameList[i]%></li>
<% } %>
出力html
<li>名前1</li>
<li>名前2</li>
<li>名前3</li>
パーツのinclude
index.ejs
<%# parts/_header.ejsをインクルード %>
<% include parts/_header %>
<%# parts/_header.ejsをインクルード。data='test'という引数を渡す %>
<%- include('parts/_header', {data: 'test'}) %>
パーツのインクルードは相対パスで絶対パスにならないので以下のようにすると楽。
index.ejs
<%# './parts/_header'をインクルードする。 %>
<% var path = './'; %>
<%- include(path + 'parts/_header') %>
include時に引数を渡す
includeを用いるとき、引数を渡すことができる。
<%- include('./_partial', {datalabel:'data'}) %>
これにより、共通パーツでも渡す引数によって変化をつけることができる。
EJSのよく使う書き方
headタグなどの毎回使うものはテンプレート化しておく
ejsの階層が変わった時は、pathの変数を変更する。
index.ejs
<%
const baseMeta = {
ttl: 'ページタイトル',
desc: 'ディスクリプション',
url: 'test.html',
path: './'
};
%>
<%#
インクルード時に、baseMetaに最初に定義したbaseMetaを渡す。
するとインクルード先で、baseMeta.ttlという風にして使用できる。
%>
<%- include(baseMeta.path + 'parts/_head', {baseMeta: baseMeta}) %>
インクルード先↓
<%= baseMeta.〜 %>で呼び出し
index.ejs
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title><%= baseMeta.ttl %></title>
<meta name="description" content="<%= baseMeta.desc %>">
<meta property="og:type" content="website" />
<meta property="og:title" content="<%= baseMeta.ttl %>" />
<meta property="og:description" content="<%= baseMeta.desc %>" />
<meta property="og:url" content="" />
<meta property="og:site_name" content="<%= baseMeta.ttl %>" />
<!--css-->
<link rel="stylesheet" href="<%= baseMeta.path %>assets/css/style.css" />
</head>
if文で状態管理
例として「ナビゲーションの現在地はスタイルを変える」という実装。
今までは.is-currentや.is-activeクラスの付け外しで見た目を変えていくことで実装していたが、EJSを使えば、共通のナビゲーションモジュールとして外部化し、if文を使ってモジュール内部で分岐を行うことで、「1ファイルだけ編集すれば、読み込むすべてのファイルで編集が適用され、場合分けもできる」という非常に効率的な状態にすることができる。
各々の<li>のクラスがlocationの値によって分岐するような形。
nav.ejs
<ul class="global-nav">
<li class="global-nav__item <% if(location == 'top'){ %>is-current<% } %>"><a href="#" class="global-nav__link">TOP</a></li>
<li class="global-nav__item <% if(location == 'about'){ %>is-current<% } %>"><a href="#" class="global-nav__link">このサイトについて</a></li>
<li class="global-nav__item <% if(location == 'profile'){ %>is-current<% } %>"><a href="#" class="global-nav__link">著者プロフィール</a></li>
<li class="global-nav__item <% if(location == 'contact'){ %>is-current<% } %>"><a href="#" class="global-nav__link">お問い合わせ</a></li>
</ul>
読み込む側に{location:top}というパラメータを引き渡す。↓
index.ejs
<header>ヘッダー</header>
<nav>
<%- include('_partial/nav.ejs', {location:'top'}) %>
</nav>
<footer>フッター</footer>
コンパイル後↓
location == topという条件に合致したため、1つ目の<li>に.is-currentが付与される。
index.html
<header>ヘッダー</header>
<nav>
<ul class="global-nav">
<li class="global-nav__item is-current"><a href="#" class="global-nav__link">>TOP</a></li>
<li class="global-nav__item "><a href="#" class="global-nav__link">>このサイトについて</a></li>
<li class="global-nav__item "><a href="#" class="global-nav__link">>著者プロフィール</a></li>
<li class="global-nav__item "><a href="#" class="global-nav__link">>お問い合わせ</a></li>
</ul>
</nav>
<footer>フッター</footer>
ページそのものに<% let location == "top" %>のように指定しておくという方法もあります。この場合、引数を渡さずにincludeしても処理が行われる。
これらは、局所的に引数を渡すべきなのか、ページ固有で持つべき変数なのか、などで適宜使い分けしていく。
↧