【HTML・CSS】EJSの環境構築とパーツ分割・変数・配列・ループの使い方【効率化】

EJSの使い方
SIM

EJSを使った静的サイト制作の効率アップの方法を紹介します。

目次

EJSを使う目的

EJSはおもにHTMLページの制作をスピードアップ・効率化するためのツールです。

EJSでできること
  • EJSによるHTMLページのパーツ分割
  • EJSで変数を使う方法
  • EJSで配列とループを使う方法
  • EJSでパスを変数化する方法

一般的にはWordPressで使うことはあまりないようです。

EJSの環境構築

SIM

EJSはgulpで使うことを前提したツールです。

gulpが分からない人は下のgulp解説記事を参照してください。

EJSのインストール

SIM

EJSのインストール手順をザックリまとめると下のとおりです。

EJSのインストール手順
  1. Visual Studio Code(以下、VSCode)でサイト制作用の作業フォルダを開きます。
  2. VSCodeの新規ターミナルで下記コマンドを入力・リターン
    npm install –save-dev gulp gulp-ejs
  3. gulpfile.jsを新規作成、内容を編集する

一つずつ解説していきます。

VSCodeで作業フォルダを開く

SIM

サイト制作の作業フォルダの構成は人それぞれですが、今回は一例ということでご理解ください。

作業フォルダの一例

DEMOサイト(フォルダ)
 CSS(フォルダ)
  style.css
 image(フォルダ)
 company(フォルダ)
  index.html
 contact(フォルダ)
  index.html
 index.html

gulpとgulp-ejsのインストール

VSCodeメニューバーからでターミナル>新規ターミナルを開き、下記コマンドをVSCodeのターミナルに入力し、リターンキーを押す。

npm install --save-dev gulp gulp-ejs

インストールが成功すると下記2つのファイルと1つのフォルダが生成される。

生成されるファイルとフォルダ
  • package.json
  • package-lock.json
  • node_modulesフォルダ

そして、package.jsonを開くと、下記のようにgulpとgulp-ejsがインストールされていることが確認できる。

EJSインストール後のファイル構成とpackage.jsonの中身

gulpfile.jsの新規作成と編集

作業フォルダの一番上の階層にgulpfile.jsを新規作成し、下記内容を記述する。

const gulp = require("gulp");
const ejs = require("gulp-ejs");

function compileEJS() {
  // コンパイル元のパス
  return gulp.src(["./src/**/*.ejs", "!./src/**/_*.ejs"])
  // コンパイル処理
  .pipe(ejs())
  // コンパイル後のパス
  .pipe(gulp.dest("./public/"))
}

exports.compileEJS = compileEJS;

フォルダとファイル構成を編集

  1. 新たに、srcフォルダとpublicフォルダを作る
  2. srcフォルダに編集時に使うファイルをすべて入れ、HTMLファイルの拡張子をすべて.ejsに変える
  3. publicフォルダは基本そのままだが、今回は最低限htmlの生成ができればよいのでCSSとimageフォルダをassetsフォルダに入れた状態でpublicフォルダに移動
  4. パスが正しく動作するように編集
フォルダとファイル構成の編集例

DEMOサイト(フォルダ)
 public(フォルダ)
  assets(フォルダ)
   CSS(フォルダ)
    style.css
   image(フォルダ) 
 src(フォルダ)
  company(フォルダ)
   index.ejs
  contact(フォルダ)
   index.ejs
  index.ejs
node_modules
gulpfile.js
package-lock.json
package.json

この状態で、ターミナルに下記コマンドを入力しリターンキーを押すと、publicフォルダ内にファイルが生成されEJSの動作確認ができる

npx gulp compileEJS

生成ファイルの拡張子のリネーム

上記のままでは、pubicフォルダ内に生成されるファイルの拡張子が.ejsになってしまうため、これを.htmlにリネームするためのパッケージ「gulp-rename」をインストールする。

  • 下記コマンドをターミナルに入力リターンする。
npm install --save-dev gulp-rename
  • gulpfile.jsを「gulp-rename」について下記のように追記する
const gulp = require("gulp");
const ejs = require("gulp-ejs");
const rename = require("gulp-rename");

function compileEJS() {
  // コンパイル元のパス
  return gulp.src(["./src/**/*.ejs", "!./src/**/_*.ejs"])
  // コンパイル処理
  .pipe(ejs())
  .pipe(rename({extname: '.html'}))
  // コンパイル後のパス
  .pipe(gulp.dest("./public/"))
}

exports.compileEJS = compileEJS;

この状態でターミナルに下記コマンドを入力リターンすると、srcフォルダ内のejsファイルからpublicフォルダ内にhtmlファイルが生成されることが確認できる。

EJSの書き方(超基本)

変数

SIM

拡張子.ejsファイル内でのEJSの変数の書き方の基本を紹介します。

変数宣言

EJSの変数宣言の構文

<% JavaScriptの記述 %>

例文は下記のとおり

<%
const company = “会社概要”;
%>

変数の出力の書き方

EJSの変数の出力の書き方(エスケープ処理あり)

<%= 変数名 %>

注)パーツ内のごく一部で使う時はこちらの方が適している

使用例は下記の通り

<a class="header__link" href="./company/"><%= company %></a>
EJSの変数の出力の書き方(エスケープ処理なし)

<%- 変数名 %>

注)パーツ全体を出力するときはこちらを使う

使用例は下記のとおり

<a class="header__link" href="./company/"><%-  contact %></a>

EJSのコメントアウトの書き方

EJSのコメントアウトの書き方

<%# コメント %>

注)コンパイルしてもコメントは出力されない

EJSの空行対策

SIM

上で紹介した記法でそのままEJSを書くとコンパイル後に空行が発生します。ここでは、この対策について紹介します。

EJSの空行対策1:変数宣言

下記のように_で挟むと_で挟まれた区間は出力されない(空行にならない)

<%_
const 変数名 = “文字列”;
_%>

例文は下記のとおり。

<%_
const company = “会社概要”;
_%>
EJSの空行対策1:変数の出力側

<%#_ 変数宣言 _%>

もしくは閉じタグの前に-を入れると改行されない

<%#  変数宣言 -%>

EJSの配列とループの使い方

EJSの配列の型

SIM

例文としてヘッダーにあるグローバルメニューを使って解説します。

EJSの配列の定義

EJSの配列の型

<%_
const 配列名 = [
配列
];
_%>

例文は下記のとおり

<%_
const menus = [
  {
    name: "会社概要",
    path: "./company/index.html/"
  },
  {
    name: "お問い合わせ",
    path: "./contact/index.html/"
  },
];
_%>

EJSの配列の出力

EJSの配列の出力構文

<% 配列名.forEach(配列の要素 =>{ %>
html文の中に配列として<%= 配列の要素.キー %>を入れる
<% }) %>

例えば、上で定義した配列をnavタグ内にループで出力する場合には下記のようになる

<nav class="header-nav">
  <% menus.forEach(menu =>{ %>
    <a class="header__link" href="<%= menu.path %>"><%= menu.name %></a>
  <% }) %>
</nav>

さらに空行対策して下記のように_で囲むと良い

  <%_ menus.forEach(menu =>{ _%>
    <a class="header__link" href="<%= menu.path %>"><%= menu.name %></a>
  <%_ }) _%>

このように配列を利用すると、メニュー項目が増えたときも記述量が少なく済みミスも減るので良い。下記のように最初に増えた分の配列を定義してしまえば、htmlが自動生成されるため非常に便利である。

<%_
const menus = [
  {
    name: "会社概要",
    path: "./company/index.html/"
  },
  {
    name: "サービス",
    path: "./service/index.html/"
  },
  {
    name: "お知らせ",
    path: "./news/index.html/"
  },
  {
    name: "お問い合わせ",
    path: "./contact/index.html/"
  },
];
_%>

EJSのパーツ分割

基本構文|EJSのパーツ分割

SIM

EJSの基本操作は下記のとおりです。

  1. ejsファイルのパーツ化したい部分を別のejsファイルにカット&ペースト
  2. 元ejsファイルのカットして空いた場所に下記構文を入れる
<%- include(“パス”) %>

例文:footerをパーツ化する場合

  1. footer.ejsを新規作成する(通常はsrcフォルダ内にpartsフォルダを新設し、その中に新規作成する)。
フォルダ・ファイル構成

DEMOサイト(フォルダ)
 public(フォルダ)
  assets(フォルダ)
   CSS(フォルダ)
    style.css
   image(フォルダ) 
 src(フォルダ)
  company(フォルダ)
   index.ejs
  contact(フォルダ)
   index.ejs
  parts(フォルダ)
   footer.ejs
  index.ejs
node_modules
gulpfile.js
package-lock.json
package.json

2. footer.ejsの内容:元のindex.ejsからそのままカット&ペースト(インデントの調整必要)

  <footer class="footer">
    <div class="footer__inner inner">
      <div class="footer__copyright">Copyright © 2023 Logo All rights reserved.</div>
    </div>
  </footer>
</body>
</html>

注意:</body>と</html>の閉じタグまで含める

元のindec.ejsは下記のとおり(下記は完成形)

<%- include("./parts/_footer") %>

下記は完成形全文

<%- include("./parts/_header", {
  title: "DEMOサイト",
  description: "トップページのディスクリプション",
  path: "."
}) -%>
<%- include("./parts/_main-visual-top") -%>

<div class="section">
  <div class="inner">
    <h2 class="section__title">セクション</h2>
    <div class="section__lead">Section</div>
    <div class="section__body">
      <p>会社概要のコンテンツが入ります。</p>
    </div>
  </div>
</div>

<%- include("./parts/_footer") %>

例文:ヘッダー(メニューあり)をパーツ化する場合

header.ejs全文の完成形は下記のとおりだが、下記ではパスの変数化も行っている

<%# 変数宣言 -%>
<%_
const menus = [
  {
    name: "会社概要",
    path: `${path}/company/index.html`
  },
  {
    name: "お問い合わせ",
    path: `${path}/contact/index.html`
  },
];
_%>
<!doctype html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <title><%= title %></title>
    <meta name="description" content="<%= description %>">

    <!-- Font -->
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@400;500;700;900&display=swap" rel="stylesheet">

    <!-- CSS -->
    <link rel="stylesheet" href="<%= path %>/assets/css/style.css">
  </head>
  <body>
    <header class="header">
      <div class="header__inner inner">
        <h1 class="header__logo"><a href="<%= path %>/index.html">Logo</a></h1>
        <nav class="header__nav">
          <%_ menus.forEach(menu =>{ _%>
          <a class="header__link" href="<%= menu.path %>"><%= menu.name %></a>
          <%_ }) _%>
        </nav>
      </div>
    </header>

元のindex.ejsはfooterの箇所を参照してください。

トップページと下層ページでタイトルとディスクリプションを別々に設定したいとき

トップページ

index.ejs

<%- include("./parts/_header", {
  title: "DEMOサイト",
  description: "トップページのディスクリプション",
  path: "."
}) -%>
<%- include("./parts/_main-visual-top") -%>

<div class="section">
  <div class="inner">
    <h2 class="section__title">セクション</h2>
    <div class="section__lead">Section</div>
    <div class="section__body">
      <p>会社概要のコンテンツが入ります。</p>
    </div>
  </div>
</div>

<%- include("./parts/_footer") %>

header.ejsの抜粋

<!doctype html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <title><%= title %></title>
    <meta name="description" content="<%= description %>">

下層ページ

トップページとの違いはパス。

<%- include("../parts/_header", {
  title: "会社概要",
  description: "会社概要ページのディスクリプション",
  path: ".."
}) -%>
    <div class="main-visual">
      <div class="main-visual__content">
        <div class="main-visual__text">会社概要</div>
      </div>
    </div>

    <div class="section">
      <div class="inner">
        <h2 class="section__title">会社概要</h2>
        <div class="section__lead">Company</div>
        <div class="section__body">
          <p>会社概要のコンテンツが入ります。</p>
        </div>
      </div>
    </div>

<%- include("../parts/_footer") %>

header.ejsはトップページと共通

HTMLを整形するパッケージのインストール

下記コマンドをターミナルに入力リターン

npm install --save-dev gulp-html-beautify

gulpfile.jsに下記を追記

const htmlBeautify = require(“gulp-html-beautify”);
.pipe(htmlBeautify())

const gulp = require("gulp");
const ejs = require("gulp-ejs");
const rename = require("gulp-rename");
const htmlBeautify = require("gulp-html-beautify");

function compileEJS() {
  // コンパイル元のパス
  return gulp.src(["./src/**/*.ejs", "!./src/**/_*.ejs"])
  // コンパル処理
  .pipe(ejs())
  .pipe(rename({extname: '.html'}))
  .pipe(htmlBeautify())
  // コンパイル後のパス
  .pipe(gulp.dest("./public/"))
}

exports.compileEJS = compileEJS;

EJSのパスの配列化

パスを配列に加えることにより、ページごとのパスの設定を一部自動化できる。

header.ejs

ejs構文中に変数を入れる場合は書き方が特殊なので注意する

`${変数} …….`という書き方に変える。

path: `${path}/company/index.html`

以下、配列の定義部分の抜粋

<%_
const menus = [
  {
    name: "会社概要",
    path: `${path}/company/index.html`
  },
  {
    name: "お問い合わせ",
    path: `${path}/contact/index.html`
  },
];
_%>

本文中は下記のように代入する。

<%= 変数名 %>

<%= path %>

本文中の関係箇所抜粋

<!-- CSS -->
 <link rel="stylesheet" href="<%= path %>/assets/css/style.css">

全文抜粋:上記CSSに他にH1タグのリンクも配列の変数に置き換えている。

<%# 変数宣言 -%>
<%_
const menus = [
  {
    name: "会社概要",
    path: `${path}/company/index.html`
  },
  {
    name: "お問い合わせ",
    path: `${path}/contact/index.html`
  },
];
_%>
<!doctype html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <title><%= title %></title>
    <meta name="description" content="<%= description %>">

    <!-- Font -->
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@400;500;700;900&display=swap" rel="stylesheet">

    <!-- CSS -->
    <link rel="stylesheet" href="<%= path %>/assets/css/style.css">
  </head>
  <body>
    <header class="header">
      <div class="header__inner inner">
        <h1 class="header__logo"><a href="<%= path %>/index.html">Logo</a></h1>
        <nav class="header__nav">
          <%_ menus.forEach(menu =>{ _%>
          <a class="header__link" href="<%= menu.path %>"><%= menu.name %></a>
          <%_ }) _%>
        </nav>
      </div>
    </header>

index.ejs(トップページ)

配列の定義に「path: “.”」を追記する必要あり。

<%- include("./parts/_header", {
  title: "DEMOサイト",
  description: "トップページのディスクリプション",
  path: "."
}) -%>
<%- include("./parts/_main-visual-top") -%>

index.ejs(下層ページ)

配列の定義に「path: “..”」を追記する必要あり。

<%- include("../parts/_header", {
  title: "会社概要",
  description: "会社概要ページのディスクリプション",
  path: ".."
}) -%>

EJSをテンプレとして他のプロジェクトで使い回す方法

EJSのフォルダとファイル構造

EJSのフォルダ・ファイル構成

作業用フォルダ
 public(フォルダ) ←コンパイル後のhtmlファイルが生成されるフォルダ
  assets(フォルダ)
   CSS(フォルダ)
    style.css
   image(フォルダ) 
 src(フォルダ) ←開発用のファイルを入れるフォルダ
  company(フォルダ)
   index.ejs ←下層ページ
  contact(フォルダ)
   index.ejs ←下層ページ
  parts(フォルダ) ←共通パーツフォルダ
   _header.ejs ←共通パーツファイル
   _footer.ejs ←共通パーツファイル
   _main-visual-top.ejs ←共通パーツファイル
  index.ejs ←トップページ
gulpfile.js ←コピペで作る
package.json ←コピペで作る

gulpfile.jsを作る

gulpfile.jsに下記コードをすべてコピペすれば、使えます。

const gulp = require("gulp");
const ejs = require("gulp-ejs");
const rename = require("gulp-rename");
const htmlBeautify = require("gulp-html-beautify");

function compileEJS() {
  // コンパイル元のパス
  return gulp.src(["./src/**/*.ejs", "!./src/**/_*.ejs"])
  // コンパル処理
  .pipe(ejs())
  .pipe(rename({extname: '.html'}))
  .pipe(htmlBeautify())
  // コンパイル後のパス
  .pipe(gulp.dest("./public/"))
}

exports.compileEJS = compileEJS;

package.jsonを作る

package.jsonに下記コードをすべてコピペすれば、使えます。

{
  "devDependencies": {
    "gulp": "^4.0.2",
    "gulp-ejs": "^5.1.0",
    "gulp-html-beautify": "^1.0.1",
    "gulp-rename": "^2.0.0"
  }
}

EJSをインストールする

VSCodeのターミナルに下記コマンドを入力リターンすると、EJSに必要なファイルがインストールされる。

npm install

具体的には、node_modulesフォルダとpackage-lock.jsonが新たにインストールされる。

各種EJSテンプレートファイル

ここで紹介するテンプレートファイルは、必要に応じて内容を変更して下さい。

EJSのコンパイルコマンド

VSCodeのターミナルに下記コマンドを入力リターンすると、ejsファイルからhtmlファイルにコンパイルされる。

npx gulp compileEJS

index.ejs|トップページ

<%- include("./parts/_header", {
  title: "DEMOサイト",
  description: "トップページのディスクリプション",
  path: "."
}) -%>
<%- include("./parts/_main-visual-top") -%>

<div class="section">
  <div class="inner">
    <h2 class="section__title">セクション</h2>
    <div class="section__lead">Section</div>
    <div class="section__body">
      <p>会社概要のコンテンツが入ります。</p>
    </div>
  </div>
</div>

<%- include("./parts/_footer") %>

index.ejs|下層ページ

<%- include("../parts/_header", {
  title: "会社概要",
  description: "会社概要ページのディスクリプション",
  path: ".."
}) -%>
    <div class="main-visual">
      <div class="main-visual__content">
        <div class="main-visual__text">会社概要</div>
      </div>
    </div>

    <div class="section">
      <div class="inner">
        <h2 class="section__title">会社概要</h2>
        <div class="section__lead">Company</div>
        <div class="section__body">
          <p>会社概要のコンテンツが入ります。</p>
        </div>
      </div>
    </div>

<%- include("../parts/_footer") %>

_header.ejs|共通パーツのヘッダー

<%# 変数宣言 -%>
<%_
const menus = [
  {
    name: "会社概要",
    path: `${path}/company/index.html`
  },
  {
    name: "お問い合わせ",
    path: `${path}/contact/index.html`
  },
];
_%>
<!doctype html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <title><%= title %></title>
    <meta name="description" content="<%= description %>">

    <!-- Font -->
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@400;500;700;900&display=swap" rel="stylesheet">

    <!-- CSS -->
    <link rel="stylesheet" href="<%= path %>/assets/css/style.css">
  </head>
  <body>
    <header class="header">
      <div class="header__inner inner">
        <h1 class="header__logo"><a href="<%= path %>/index.html">Logo</a></h1>
        <nav class="header__nav">
          <%_ menus.forEach(menu =>{ _%>
          <a class="header__link" href="<%= menu.path %>"><%= menu.name %></a>
          <%_ }) _%>
        </nav>
      </div>
    </header>

_footer.ejs|共通パーツのフッター

  <footer class="footer">
    <div class="footer__inner inner">
      <div class="footer__copyright">Copyright © 2023 Logo All rights reserved.</div>
    </div>
  </footer>
</body>
</html>

_main-visual-top.ejs|共通パーツのコンテンツ

<div class="main-visual is-top">
  <div class="main-visual__content">
    <div class="main-visual__text">トップページ</div>
  </div>
</div>
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

■清水WEB制作代表
■コーディング:WordPress(オリジナルテーマ制作等)・HTML・Sass・FLOCSS・JavaScript(jQuery)等
■集客力:YouTube/Instagram/ブログでそれぞれ登録者数16000人/フォロワー13000人/月間最大アクセス50000PVの集客実績があります
■文章作成:博士号所有、会社員時代は科学雑誌に寄稿していたので文章作成も得意です
■写真技術:Amazon Kindle出版で、写真集・撮影編集解説書を5冊好評発売中です

目次