EJSで特定のファイルを共通ファイルとしてインクルードさせたいけど、ページによって一部変更したい箇所があるときなどに使える方法です。
ここではナビゲーションを例に該当のページだった場合は特定の要素にカレントクラスを付与させるという動きを具体的にはインクルード時の引数と条件分岐を利用して実装してみます。
- 紹介する方法はgulpを使用した実装方法になるので、予めgulpが使用できる環境を用意してください。
- EJSの基本的な使用方法などについては割愛しているので、「EJS -- Embedded JavaScript templates」や「GitHub - mde/ejs: Embedded JavaScript templates」などで確認してください。
使用するプラグインとファイル構成
プラグインのインストール
今回はgulpでEJSを使用するので、まず下記コマンドで「gulp-ejs」をインストールします。
$ npm i -D gulp-ejs
ファイル構成
ここで使用する方法は以下のようなファイル構成のものを使用した想定になり、後述するコード内のパスなどについてもこの構成をもとにしています。
/src/index.ejs
がTOPページ、/src/page/index.ejs
が下層ページ扱いとして、いずれも共通ナビゲーションが記述された/src/templates/_nav.ejs
を読み込んでナビゲーションを表示させるというものになります。
├─ /src
│ └─ /ejs
│ ├─ index.ejs
│ ├─ /page
│ │ └─ index.ejs
│ └─ /templates
│ ├─ _head.ejs
│ └─ meta.json
└─ gulpfile.js
タスクの記述
タスクは特別な記述などは必要なく、単純に/src
をgulp.dest()
するという感じでgulpfile.js
に下記のように記述します。
var gulp = require( 'gulp' ),
ejs = require( 'gulp-ejs' );
gulp.task('ejs', function() {
return gulp.src(['src/ejs/**/*.ejs', '!src/ejs/**/_*.ejs'])
.pipe(ejs({}, {}, {ext: '.html'}))
.pipe(gulp.dest('dist'));
});
EJSへの記述
まずは各index.ejs
にナビゲーションが記述されたファイルをインクルードさせていきます。
今回は/src/templates/_nav.ejs
をインクルードさせるのでinclude
を利用して、それぞれ下記のようにページを示すIDとなるような引数をcurrent: 'ID'
のような形で記述します。
ここでは/src/index.ejs
にはhome
を、/src/page/index.ejs
にはpage
をそれぞれ引数として指定しておきます。
<%-
include('./templates/_nav', {
current: 'home'
});
%>
/src/page/index.ejs
<%-
include('../templates/_nav', {
current: 'page'
});
%>
include
使用時の注意点としては、パスはその読み込むファイル(自身のファイル)からの相対パスで指定する必要があります。
また、読み込むファイルは_nav.ejs
ですが、上記のように拡張子を省略して指定することが可能です。
次に上でインクルードするように指定したナビゲーション用ファイルの作成で、ベースとなるHTMLとしては下記のようなものを使用します。
<nav>
<a href="#">home</a>
<a href="#">page</a>
</nav>
これをEJSの機能を利用して該当ページにいる場合は特定のa
要素に対して.is-current
というclassが付与されるようにしていき、/src/templates/_nav.ejs
に下記のように記述します。
<% var currentClass = 'class="is-current" '; -%>
<nav>
<a <%- current == 'home' ? currentClass : '' %>href="#">home</a>
<a <%- current == 'page' ? currentClass : '' %>href="#">page</a>
</nav>
まず、コード上部でカレントクラスを表示する際に使用する変数を作成し、今回は.is-current
というclassを付与したいのでclass="is-current"
としておきます。
次に各a
要素にtrue
だった場合にカレントクラス用の変数が入るように条件分岐を記述し、条件部分には先ほどインクルード時に指定した引数を利用してcurrent == 'ID'
のような形で記述します。
例えば、/src/index.ejs
にはインクルード時にhome
という引数を付けており、そのページを表示する際はひとつ目のa
要素にclassが付いてほしいので、そこにcurrent == 'home'
という条件を指定していきます。
あとは$ gulp ejs
を実行すれば/src
の並列に/dist
が出力されるので、その中の各HTMLを確認すると/dist/index.html
ではひとつ目のa
要素に、/dist/page/index.html
ではふたつ目のa
要素にそれぞれ下記のようにカレントクラスが記述されているのを確認できます。
<nav>
<a class="is-current" href="#">home</a>
<a href="#">page</a>
</nav>
<nav>
<a href="#">home</a>
<a class="is-current" href="#">page</a>
</nav>
今回はナビゲーションで特定の要素にカレントクラスを付与する動きを例に紹介してきましたが、冒頭にも書いたように特定のファイルを共通ファイルとしてインクルードさせつつページによって変更したい箇所がある場合に使えるので、EJSでこのようなことをしたいときに試してみてください。