静的サイトをEJSで共通化する
Webサイトを作っていると出来るだけ効率良く制作したいです。
今回は、静的サイトの共通部分をEJSでパーツ化して、管理しやすく変更に強いサイト制作を紹介します。
この記事では、
npmの ejs-cliを使い、EJSファイルから HTMLファイルに変換(複数ページのメタ情報含む)
を紹介しています。
目次
EJSとは
Embedded JavaScript 略して EJS
JavaScriptテンプレートエンジンと呼ばれるうちの1つです。
簡単に言うと【 効率良く制作するための書き方 】です。
導入までのハードルは高く、使えるようになるまでが大変ですが、
準備さえができれば覚えることが少ない点が魅力です。
EJSは、PHPと使い方が似ているため、PHPでパーツ化などの経験があれば抵抗なく使えると思います。
公式はこちら:Embedded JavaScript templating.
Node.js と npm が必要
EJSを使うには、Node.jsと npmをPCにインストールする必要があります。
これが導入までのハードルが高い理由です。簡単に説明すると、
Node.js とは
JavaScriptをサーバー上でも使えるようにするための土台です。
Node.jsにはパッケージ(package)と呼ばれる、単体では意味を成さないようなプログラムの小包が有志の方々によって沢山用意されており、その中の1つに EJSがあります。(Sassなどもあります)
npm とは
沢山あるプログラムの小包(package)を管理する手段です。
リンク紹介
Node.js が分かりやすい記事
・初心者向け!3分で理解するNode.jsとは何か?|エンジニアの入り口
PCにインストール
説明は外部リンクに頼ります。
Windowsはこちら(Googleの検索結果です)
node.js npm インストール windows|Google検索結果
Macはこちら
Node.js を Mac にインストール|Web Design Leaves
EJSファイルの準備
上記のインストールが終わった状態と仮定して、説明します。
階層構造(例)
普段使っている HTMLファイルの拡張子を .ejsに書き換えて、↑ 画像のようにします。
includeフォルダ → 共通化したいファイル入れ
pageフォルダ → 下層ページ用のファイル入れ
index.ejsファイル → トップページ用のファイル
data.jsonファイル → サイト情報を記述するJSONファイル
パーツ化して使うための EJS記述
<%-
include('./include/_〇〇.ejs', { meta: data['top'] } );
%>
<%- include( ' 共通部分読み込み ' , { JSONファイル読み込み } ) ; %>
PHPの記述と非常に似ていて <%- %> で囲むことで、変換後にHTML要素として出力されます。
使い方(index.ejs内)
<%-
include('./include/_header.ejs', { meta: data['top'] } );
%>
<!-- ▼メインコンテンツ▼ ---------------------------------------------------------------->
<main>
<h2>EJS変換テスト</h2>
</main>
<!-- ▲メインコンテンツここまで▲ ---------------------------------------------------------------->
<%-
include( './include/_footer.ejs', { meta: data['top'] });
%>
include( ' 〇〇.ejs ' )
includeフォルダ内の header.ejs、footer.ejsを相対パスで参照しています。
{ meta: data['top'] }
data.jsonファイル内の "top"の値を参照しています。(JSONファイルについては下記)
サイト情報を記述した JSONファイルの準備
JSONファイルとは
「JavaScript Object Notation」の略で………情報を記述しておくファイルです。
JSONファイル記述例(サイト情報)
data.jsonファイルを作り、サイトの情報を記述します。
{
"data": {
"$comment": "// 共通の設定 ------------------------------",
"default": {
"path": "./",
"title": "EJSテストサイト",
"description": "サイトの説明",
"og_img": "https//〜〜〜〜〜",
"twitter_site": "@pazfinder",
"favicon": "./〜〜〜/favicon.ico",
"$comment": "// CSSファイル ------------------------------",
"styles": [{
"style": "assets/css/vendor.min.css"
}, {
"style": "assets/css/index.min.css"
}],
"$comment": "// グローバルナビ ------------------------------",
"navs": [{
"link": "index.html",
"name": "トップページ"
}, {
"link": "page/product.html",
"name": "製品ページ"
}],
"$comment": "// JSファイル ------------------------------",
"scripts": [{
"script": "js/vendor.js"
}, {
"script": "js/index.js"
}],
"media": "all"
},
"$comment": "// トップページ ------------------------------",
"top": {
"title": "トップページ|EJSテストサイト",
"description": "トップページのサイトの説明"
},
"$comment": "// プロダクトページ ------------------------------",
"product": {
"path": "../",
"title": "製品情報|EJSテストサイト",
"description": "製品ページのサイトの説明"
}
}
}
"default" → サイト共通の情報
"top" → トップページ用の情報
"product" → 製品ページ用の情報
を記述しておき、ページに合わせて記述内容を反映させます。
(サイトの構成に応じてアレンジして下さい。)
"$comment" とありますが、JSONファイル内ではコメントを記すことが出来ないため、あえて変な記述がしてあります。消してもらって大丈夫です。
使用例(header.ejs)
<%
const _default = data['default'];
for ( let i in _default ) {
if ( typeof meta[i] === 'undefined' ) {
meta[i] = _default[i];
}
}
-%>
<!DOCTYPE html>
<html lang="ja">
<head prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb# website: http://ogp.me/ns/website#">
<meta name="description" content="<%= meta.description %>">
<meta property="og:image" content="<%= meta.og_img %>" />
<meta name="twitter:site" content="<%= meta.twitter_site %>" />
<!-- ファビコン -->
<link rel="icon" href="<%= meta.favicon %>">
<!-- CSS -->
<% for (var i in meta.styles) { -%>
<link rel="stylesheet" href="<%= meta.path %><%= meta.styles[i].style %>" type="text/css" media="<%= meta.media %>">
<% } -%>
<!-- サイトタイトル -->
<title><%= meta.title %></title>
</head>
<body>
<!-- ヘッダー -->
<header>
<h1></h1>
<nav>
<ul>
<%_ for (var i in meta.navs) { _%>
<li>
<a href="<%= meta.path %><%=meta.navs[i].link %>"><%= meta.navs[i].name %></a>
</li>
<%_ } _%>
</ul>
</nav>
</header>
<%= 変数名.〇〇 %>
<%= %> で囲むことで変換後に文字列として出力されます。
変数名は metaと名付けています。
変数名.〇〇の記述で data.jsonに書いてある情報を出力します。
meta.descriptionであれば "description"の情報を出力。といった具合です。
2〜7行目 JavaScript
「 meta.〇〇 が未定義な場合は、JSONファイルの data['default']を参照する」と言う意味です。
各ページ固有の情報を読み込んでも未定義だった場合は、基本的なサイト情報の書いてある "default" の内容が適用されます。
CSSや Gナビのような複数出力に for文
繰り返し必要な項目に for文や forEach文が使えます。
EJSを変換してHTMLで出力する
VS Codeを例に説明します。
Webサイトのフォルダで【右クリック → 総合ターミナル】を押します。
ここから npmコマンドの出番です。ターミナルにて、
〜〜〜@MacBook-Air site-name_ejs % npm init -y
npm init -y と入力。エンターキーで決定。
( init は初期化、-y は全てYESで答えるという意味)
すると、package.jsonファイルが作られます。
続けて、
〜〜〜@MacBook-Air site-name_ejs % npm install --save-dev ejs-cli
npm install --save-dev ejs-cli と入力。エンターキーで決定。
すると、
package-lock.jsonファイル と
node_modulesフォルダと一緒に、大量のファイルが作られます。
が、一旦無視して下さい。
(node_modulesはこの大量のファイルが当たり前なので、心配なさらずに)
そして、
package.jsonファイル内の "scripts"を
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
以下に書き換えます。
"scripts": {
"ejs": "ejs-cli --base-dir src/ejs '**/*.ejs' --exclude 'include/' --out dest/ --options data.json"
},
その後、ターミナルにて
〜〜〜@MacBook-Air site-name_ejs % npm run ejs
npm run ejs と入力。エンターキーで決定。
とすれば、
distフォルダが作られ、その中には 各ページのHTMLファイルが完成しています。
サーバーへアップロードする際は、この distフォルダのみをアップするといった具合です。
EJS使用時の注意点
includeするファイル内( header.ejs, footer.ejsなど)では、変数や if文・for文が使えますが、
include先のファイル( index.ejs, product.ejsなど)では、変数や if文・for文が使えませんのでご注意ください。
(無理矢理使う方法はあるっぽいです。検索してみてください。)
参考サイト
npmを詳しく。
・npm の基本的な使い方|Web Design Leaves
EJSの書き方について詳しく。
・EJS まとめ|Qiita
まとめ
今回は EJSから HTMLファイルへ変換するやり方だけでしたが、
次回は CSSや画像なども一緒に distフォルダへ出力されるような方法も紹介できればなと思います。
最後まで読んでいただき、ありがとうございました。