NodeアプリケーションのテンプレートとしてEJSを使用する方法

はじめに

Nodeアプリケーションを素早く作成する際には、アプリケーションをテンプレート化する迅速な方法が必要な場合があります。

Jadeは、Expressのデフォルトのテンプレートエンジンとして提供されていますが、Jadeの構文は多くのユースケースでは過度に複雑です。

埋め込みJavaScriptテンプレート(EJS)は、代替テンプレートエンジンとして使用できます。

この記事では、ExpressアプリケーションにEJSを適用し、サイトの繰り返し部分を含め、ビューにデータを渡す方法を学びます。

DigitalOcean App Platformを使用してGitHubからフロントエンドアプリケーションをデプロイします。DigitalOceanにアプリのスケーリングを任せましょう。

前提条件

この記事に従いたい場合は、以下が必要です:

このチュートリアルは元々、express v4.17.1 と ejs v3.1.5 向けに書かれました。Node v16.0.0、npm v7.11.1、express v4.17.1、および ejs v3.1.6 で検証されています。

ステップ 1 — プロジェクトのセットアップ

まず、ターミナルウィンドウを開いて新しいプロジェクトディレクトリを作成します:

  1. mkdir ejs-demo

次に、新しく作成したディレクトリに移動します:

  1. cd ejs-demo

この段階で、新しい npm プロジェクトを初期化できます:

  1. npm init -y

次に、express パッケージをインストールする必要があります:

  1. npm install express@4.17.1

次に、ejs パッケージをインストールします:

  1. npm install ejs@3.1.6

この時点で、Express と EJS を使用する新しいプロジェクトが準備されました。

ステップ 1 — server.js の設定

すべての依存関係がインストールされたので、アプリケーションを EJS を使用するように構成し、インデックスページと About ページのルートを設定しましょう。

server.js ファイルを新しく作成し、コードエディタで開き、次のコードを追加します:

server.js
var express = require('express');
var app = express();

// ビューエンジンをEJSに設定する
app.set('view engine', 'ejs');

// res.renderを使用してEJSビューファイルを読み込む

// インデックスページ
app.get('/', function(req, res) {
  res.render('pages/index');
});

// Aboutページ
app.get('/about', function(req, res) {
  res.render('pages/about');
});

app.listen(8080);
console.log('Server is listening on port 8080');

このコードはアプリケーションを定義し、ポート8080でリッスンします。

このコードはまた、ExpressアプリケーションのビューエンジンとしてEJSを設定します:

`app.set('view engine', 'ejs');`

コードがres.render()を使用してユーザーにビューを送信する方法に注目してください。 res.render()はビューをviewsフォルダーから検索します。したがって、pages/indexを定義するだけで十分です。完全なパスはviews/pages/indexです。

次に、EJSを使用してビューを作成します。

ステップ2 — EJSパーシャルの作成

構築するアプリケーションの多くの部分は再利用されるコードがあります。これらはパーシャルと見なされます。この例では、インデックスページとAboutページで再利用される3つのパーシャルがあります:head.ejsheader.ejsfooter.ejs。これらのファイルを作成しましょう。

viewsディレクトリを作成します:

  1. mkdir views

次に、partialsサブディレクトリを作成します:

  1. mkdir views/partials

このディレクトリ内に、新しい head.ejs ファイルを作成し、コードエディタで開いてください。以下のコードを追加してください:

views/partials/head.ejs
<meta charset="UTF-8">
<title>EJS Is Fun</title>

<!-- CSS (load bootstrap from a CDN) -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.2/css/bootstrap.min.css">
<style>
  body { padding-top:50px; }
</style>

このコードには、HTML ドキュメントの head 用のメタデータが含まれています。また、Bootstrap のスタイルも含まれています。

次に、新しい header.ejs ファイルを作成し、コードエディタで開いてください。以下のコードを追加してください:

views/partials/header.ejs
<nav class="navbar navbar-expand-lg navbar-light bg-light">
  <a class="navbar-brand" href="/">EJS Is Fun</a>
  <ul class="navbar-nav mr-auto">
    <li class="nav-item">
      <a class="nav-link" href="/">Home</a>
    </li>
    <li class="nav-item">
      <a class="nav-link" href="/about">About</a>
    </li>
  </ul>
</nav>

このコードには、HTML ドキュメントのナビゲーションが含まれており、Bootstrap の複数のクラスを使用してスタイリングされています。

次に、新しい footer.ejs ファイルを作成し、コードエディタで開いてください。以下のコードを追加してください:

views/partials/footer.ejs
<p class="text-center text-muted">&copy; Copyright 2020 The Awesome People</p>

このコードには、著作権情報が含まれており、Bootstrap の複数のクラスを使用してスタイリングされています。

次に、これらのパーシャルを index.ejsabout.ejs で使用します。

ステップ 3 — ビューに EJS パーシャルを追加する

3 つのパーシャルが定義されました。これらをビューに include できます。

別のファイルに EJS パーシャルを埋め込むには、<%- include('相対/ファイルへの/パス') %> を使用します。

  • ハイフン <%- を使用することで、EJS に生の HTML をレンダリングするよう指示します。
  • パーシャルへのパスは、現在のファイルからの相対パスです。

次に、新しいpagesサブディレクトリを作成してください。

  1. mkdir views/pages

このディレクトリ内に、新しいindex.ejsファイルを作成し、コードエディタで開いてください。次のコードを追加してください:

views/pages/index.ejs
<!DOCTYPE html>
<html lang="en">
<head>
  <%- include('../partials/head'); %>
</head>
<body class="container">

<header>
  <%- include('../partials/header'); %>
</header>

<main>
  <div class="jumbotron">
    <h1>This is great</h1>
    <p>Welcome to templating using EJS</p>
  </div>
</main>

<footer>
  <%- include('../partials/footer'); %>
</footer>

</body>
</html>

このファイルの変更を保存して、アプリケーションを実行してください:

  1. node server.js

ウェブブラウザでhttp://localhost:8080/にアクセスすると、インデックスページが表示されます:

次に、新しいabout.ejsファイルを作成し、コードエディタで開いてください。次のコードを追加してください:

views/pages/about.ejs
<!DOCTYPE html>
<html lang="en">
<head>
  <%- include('../partials/head'); %>
</head>
<body class="container">

<header>
  <%- include('../partials/header'); %>
</header>

<main>
<div class="row">
  <div class="col-sm-8">
    <div class="jumbotron">
      <h1>This is great</h1>
      <p>Welcome to templating using EJS</p>
    </div>
  </div>

  <div class="col-sm-4">
    <div class="well">
      <h3>Look I'm A Sidebar!</h3>
    </div>
  </div>
</div>
</main>

<footer>
  <%- include('../partials/footer'); %>
</footer>

</body>
</html>

このコードは、異なるテンプレートやページ間で再利用できるように、パーシャルがどのように構造化されるかを示すBootstrapのサイドバーを追加します。

このファイルの変更を保存して、アプリケーションを実行してください:

  1. node server.js

ウェブブラウザでhttp://localhost:8080/aboutにアクセスすると、サイドバー付きのAboutページが表示されます:

これで、Nodeアプリケーションからビューにデータを渡すためにEJSを使用できるようになりました。

ステップ4 — ビューとパーシャルへのデータの渡し方

基本的な変数とリストをインデックスページに渡すためのコードを定義しましょう。

コードエディタでserver.jsを開き、app.get('/')ルートの内部に次のコードを追加してください:

server.js
var express = require('express');
var app = express();

// ビューエンジンをejsに設定
app.set('view engine', 'ejs');

// res.renderを使用してejsビューファイルを読み込む

// インデックスページ
app.get('/', function(req, res) {
  var mascots = [
    { name: 'Sammy', organization: "DigitalOcean", birth_year: 2012},
    { name: 'Tux', organization: "Linux", birth_year: 1996},
    { name: 'Moby Dock', organization: "Docker", birth_year: 2013}
  ];
  var tagline = "No programming concept is complete without a cute animal mascot.";

  res.render('pages/index', {
    mascots: mascots,
    tagline: tagline
  });
});

// アバウトページ
app.get('/about', function(req, res) {
  res.render('pages/about');
});

app.listen(8080);
console.log('Server is listening on port 8080');

このコードは、mascotsという配列とtaglineという文字列を定義しています。次に、これらをindex.ejsで使用しましょう。

EJSで単一の変数をレンダリングする

単一の変数をエコーするには、<%= tagline %>を使用できます。

コードエディタでindex.ejsを再度開き、以下のコードを追加します。

views/pages/index.ejs
<!DOCTYPE html>
<html lang="en">
<head>
  <%- include('../partials/head'); %>
</head>
<body class="container">

<header>
  <%- include('../partials/header'); %>
</header>

<main>
  <div class="jumbotron">
    <h1>This is great</h1>
    <p>Welcome to templating using EJS</p>

    <h2>Variable</h2>
    <p><%= tagline %></p>
  </div>
</main>

<footer>
  <%- include('../partials/footer'); %>
</footer>

</body>
</html>

このコードは、taglineの値をインデックスページに表示します。

EJSでデータをループ処理する

データをループ処理するには、.forEachを使用できます。

コードエディタでindex.ejsを再度開き、以下のコードを追加します。

views/pages/index.ejs
<!DOCTYPE html>
<html lang="en">
<head>
  <%- include('../partials/head'); %>
</head>
<body class="container">

<header>
  <%- include('../partials/header'); %>
</header>

<main>
  <div class="jumbotron">
    <h1>This is great</h1>
    <p>Welcome to templating using EJS</p>

    <h2>Variable</h2>
    <p><%= tagline %></p>

    <ul>
      <% mascots.forEach(function(mascot) { %>
        <li>
          <strong><%= mascot.name %></strong>
          representing <%= mascot.organization %>,
          born <%= mascot.birth_year %>
        </li>
      <% }); %>
    </ul>
  </div>
</main>

<footer>
  <%- include('../partials/footer'); %>
</footer>

</body>
</html>

このファイルの変更を保存してから、アプリケーションを実行します。

  1. node server.js

Webブラウザでhttp://localhost:8080/を訪れると、mascotsを含むインデックスページが表示されます。

EJSへのデータの渡し方

EJSのパーシャルは、親ビューと同じデータにアクセスできます。ただし、注意が必要です。パーシャル内で変数を参照する場合は、そのパーシャルを使用するすべてのビューでその変数が定義されている必要があります。そうでない場合はエラーが発生します。

また、次のようにインクルード構文でEJSのパーシャルに変数を定義して渡すこともできます:

views/pages/about.ejs
...
<header>
  <%- include('../partials/header', {variant: 'compact'}); %>
</header>
...

ただし、変数が定義されていると仮定する際には注意が必要です。

常に定義されていない可能性のあるパーシャル内の変数を参照し、デフォルト値を与えたい場合は、次のようにします:

views/partials/header.ejs
...
<em>Variant: <%= typeof variant != 'undefined' ? variant : 'default' %></em>
...

上記の行では、EJSコードが、定義されている場合はvariantの値をレンダリングし、そうでない場合はdefaultをレンダリングしています。

結論

この記事では、EJSをExpressアプリケーションに適用し、サイトの繰り返し部分を含め、ビューにデータを渡す方法について学びました。

EJSを使用すると、追加の複雑さが必要ない場合にアプリケーションを構築できます。パーシャルを使用し、ビューに簡単に変数を渡すことができるため、素晴らしいアプリケーションを素早く構築できます。

追加情報については、EJSドキュメントを参照してください。さまざまなビューエンジンの利点と欠点を理解するには、JavaScriptテンプレートエンジンの比較:Jade、Mustache、Dustなどを参照してください。

Source:
https://www.digitalocean.com/community/tutorials/how-to-use-ejs-to-template-your-node-application