PugでHTMLのコーディングを効率化

2024年 7月 8日 Posted 野々瀨(フロントエンドエンジニア)

HTMLを新規で書いたり修正を行ったりする際、ページ数が多いとタグの記述などや同じ箇所と内容を修正するのに、すごく手間に感じることがあると思います。そこでそういった問題を和らげる「Pug」という、HTMLを効率的に書くことのできるテンプレートエンジンの一つをご紹介しようと思います。

Pugとは

Pug(パグ)とは、HTMLのコーディングを効率よく書くためのJavaScriptベースのテンプレートエンジンの一つです。以前はJadeという名前で知られていて、Hamlという別のテンプレートエンジンがあり、その影響を強く受けているテンプレートエンジンです。

公式ページ:https://pugjs.org/

メリット

Pugは次のようなメリットがあります。

簡単で少ない記述

Pugは簡単な構文で少ない記述をすることができます。閉じタグが必要なかったり共通する内容を変数にして共通化することで、記述量を少なくすることができます。

例えば次のようなHTMLがあるとします。

<!DOCTYPE html>
<html lang="ja">
  <head>
    <title>Page Title</title>
  </head>
  <body>
    <h1>Heading 1</h1>
    <p>Lorem ipsum dolor sit amet consectetur adipisicing elit.</p>
  </body>
</html>

これをPugで記述すると次のようになります。

doctype html
html(lang="ja")
  head
    title="Page Title"
  body
    h1="Heading 1"
    p="Lorem ipsum dolor sit amet consectetur adipisicing elit."

学習コストが低い

Pug専用の構文はありますものの、専用の構文は比較的少ないため、学習するためのコストは低めです。HTMLやCSS、JavaScriptを直接記述することもできます。

コードの再利用化

変数やファイル分割、ミックスインを使用することでコードを再利用可能なコードにすることができます。サイトタイトルを変数化したり、ヘッダーやフッターを別ファイルにしてテンプレートかしたりすることができます。

デメリット

Pugは次のようなデメリットがあります。

変換が必要

Pugはそのままでは使用できず、Pugから静的なHTMLに変換するコンパイルという作業が必要になります。

最初の環境を用意が必要

Pugを静的なHTMLに変換するには、コンパイラーというソフトウェアが必要です。コンパイラーをインストールし、コマンドやJavaScriptを使って変換処理を行います。環境を用意すること自体は、最初の1度きりだったりプロジェクトごとに用意したりするなど頻度は比較的少なめです。

コードが複雑になる可能性

条件分岐や繰り返し処理を行うことができますが、プログラミングを書くということになります。そのためコードが難しくなったり、複雑なコードになったりする可能性があります。

導入方法

PugはNode.jsで動作しますので、Node.jsとPugパッケージをインストールする必要があります。なお、PugパッケージはタスクランナーであるGulpを使用している場合、Gulp用のパッケージが存在しています。ここでは標準的なPugパッケージをご紹介します。

Node.jsの導入方法

Node.jsの公式Webサイトから環境に応じたインストーラーをダウンロードします。https://nodejs.org/en/download/

ダウンロード後、ダウンロードしたファイルを実行します。手順に従って進めていき、「Install」ボタンを押してインストールを開始します。

完了すると「Finish」ボタンが表示されますのでボタンを押します。

パッケージの導入方法

コマンドラインで次のコマンドを入力し実行することで、インストールすることができます。

npm i pug

コンパイル方法

pugモジュールを読み込みます。pug.renderFileメソッドを使用することで、PugファイルからHTMLファイルへとコンパイルします。pug.renderFileメソッドは第一引数にPugファイルのパス(必須)、第二引数に詳細のオプション(任意)を指定します。HTMLファイルはPugファイルと同じ階層で、同名のファイルに拡張子を「.html」に変えて保存されます。

const pug = require('pug');

pug.renderFile('foo/test.pug', {
  pretty : true
});

このコードは「foo/test.pug」というPugファイルをHTMLファイル(出力されるファイルは「foo/test.html」)としてコンパイルします。pug.renderFileメソッドの第二引数でprettyプロパティをtrueにすると、改行やインデントを付けるなどしてHTMLを整形します。

簡単な書き方

Pugの簡単な書き方を一部ご紹介します。ここでご紹介しきれなかった書き方については公式のドキュメントをご覧ください。

タグの指定

タグを指定するときは、タグ名をそのまま記述します。

Pug:

div
p
a

HTML:

<div></div>
<p></p>
<a></a>

入れ子(階層構造)

インデントを付けることで入れ子(階層構造)を作ることができます。またタグ名: タグ名とタグ名の前後にセミコロンと半角スペースを付けることでも、入れ子とすることができます。

Pug:

div
  p
  ul
    li: a
    li: a: span

HTML:

<div>
  <p></p>
  <ul>
    <li><a></a></li>
    <li><a><span></span></a></li>
  </ul>
</div>

テキスト

タグ名と挿入したいテキストの間に半角スペースを付けることで、テキストを入れることができます。

テキストの中にタグが含まれる場合、そのままHTMLとして出力されます。もしテキスト内のHTMLをエスケープしたい場合、タグ名="テキスト"とタグ名とテキストを区切っていた半角スペースをイコールにし、テキストをダブルクォーテーションでくくることで、エスケープすることができます。

Pug:

p Hello World !
p=Hello <b>World</b> !
p="Hello <b>World</b> !"

HTML:

<p>Hello World !</p>
<p>Hello <b>World</b> !</p>
<p>Hello &lt;b&gt;World&lt;/b&gt; !</p>

ID名やクラス名の付与

ID名やクラス名を付与する場合、タグ名#ID名タグ名.クラス名と記述することでそれぞれ付与することができます。また、タグ名を付けずに指定するとdiv要素として出力されます。

Pug:

p#foo
p.bar.baz
.qux

HTML:

<p id="foo"></p>
<p class="bar baz"></p>
<div class="qux"></div>

属性の付与

タグ名(属性="属性値")と記述することで、属性を付与することができます。タグ名(属性="属性値" 属性="属性値")と属性との間に半角スペースで区切ることで、複数の属性を記述することもできます。

Pug:

script(src="js/main.js" type="module" defer)

HTML:

<script src="js/main.js" type="module" defer></script>

コメントアウト

//または//-でその行をコメントアウトすることができます。//はHTMLのコメントアウトが出力され、//-はPug内でのみでHTMLには出力されないコメントアウトとなります。

Pug:

// コメントアウト(出力されるよ)
//- コメントアウト(出力されないよ)

HTML:

<!-- コメントアウト(出力されるよ)-->

変数の宣言と使用

- var 変数名 = 値と記述することで変数の宣言を行うことができます。また、変数名をそのまま記述することで使用することができます。

Pug:

- var PAGE_TITLE = "Hello World"

h1=PAGE_TITLE

HTML:

<h1>Hello World</h1>

外部Pugファイルの読み込み

include ファイルパスと記述することで、外部Pugファイルを読み込むことができます。

Pug:

include foo/bar.pug

p="Hello World"

HTML:

<h1>Page Title</h1>
<p>Hello World</p>

条件分岐

if 条件と記述することで条件に応じて分岐を行うことができます。if 条件の後に改行してインデントを付けて内容を記述することで、その条件に一致した時の内容を処理することができます。

また、ifによる条件ではなく別の条件を指定したいときはelse if 条件、いずれも一致しなかった時に分岐したいときはelseを記述します。

Pug:

- var category = 'foo'

if category == 'foo'
  p="fooだよ"
else if category == 'bar'
  p="いやbarだよ"
else
  p="いやいやどちらでもないよ"

HTML:

<p>fooだよ</p>

最後に

Pugについてすごく今更ながら書かせていただきました。Pug自身はGitHubを確認する限りでは、pugは2021年、pug-cliは2017年と更新が止まってしまっているため、これから導入しようと思うと採用は難しくなってくるかもしれません。また、昨今(というほどでもないが)ではReactのフレームワークで知られるNext.jsなどの静的サイトジェネレーター(Static Site Generator = SSG)で生成するパターンもあります。HTMLを効率的に記述するための一つの手段として、こんなのもあるんだということで知ってもらえたらと思います。