PugでHTMLコーディングを効率化・メリットと使い方を知る
古いサイトのヘッダー改修で全ページを修正したり、微妙にことなるHTMLを繰り返し大量に書いたり(エディタがどんどん重くなる)、閉じタグ忘れを血眼になって探したことはないだろうか。
EmmetとSassでコーディングはかなり楽になったけれど、僕の作業を一番効率化してくれたのは、同時期に覚えたPugという技術だった。ここでは、Pugの概要とメリットを簡単に紹介したい。
Pugとは
Pug(パグ)は、HTMLを効率的に書くためのテンプレートエンジン。使い方はCSSで言うSassみたいなもの。拡張子 .pug
のファイルを書いてHTMLに変換する。
もともとはJade(ジェード)という名前で開発されていたものの、商標の関係で2016年あたりにPugとして再リリースされた。新しいPug(2018年3月12日現在v2.0.1)は繰り返しや属性などの書き方が若干変更されている。Jadeのコードを流用する場合は記法変更によるエラーに注意。
ちなみに、Vue.jsのテンプレートをPugで書くこともできるので、記法を覚えておいて損はない。
Pugの記法
Rubyのようにインデントのみで階層化を行い書いていくのが基本。
main#main
ul.btns
li
a.btn(href="/") ボタン
↓
<main id="main">
<ul class="btns">
<li><a href="/" class="btn">ボタン</a></li>
</ul>
</main>
コンパイルが必要
Pugはブラウザで認識されないので、普通のHTMLを書きだす(コンパイル)仕組みを作る。コンパイルは、タスクランナー系(gulpなど)やコンパイラーアプリ(Preprosなど)を用いて自動化するのが一般的。
Pugのメリット
ここでは、僕が便利になったと感じている特徴をリストアップしてみる。
閉じタグ忘れがなくなる
自動的に閉じタグが生成されるので、閉じタグ忘れが100%なくなった。Emmetを使い出して軽減できていたものの、修正しているうちに閉じタグ数がずれることもあったので。
書き方をCSSと統一できる
classは .
、idだと #
で書くのでCSSとの連携が取りやすい。
ファイルを分割管理できる
Sassと同じく別ファイルを読み込んで書き出せるのが便利。静的ページの共通ヘッダー・フッター修正も楽勝。以下では _header.pug
と _footer.pug
を別ファイルで作っていた場合を想定。
include section/_header.pug
main#main
ul.btns
li
a.btn(href="/") ボタン
include section/_footer.pug
↓
<header>
<h1>
<a href="#"><img src="img/logo.svg" alt="Pugの説明ページ|Pugの説明サイト" class="logo"></a>
</h1>
</header>
<main id="main">
<ul class="btns">
<li><a href="/" class="btn">ボタン</a></li>
</ul>
</main>
<footer>
<p class="copylight">© 運営会社名</p>
</footer>
変数で修正が楽になる
JavaScriptのように変数が使えるので、「サイト名が変更になりました。お手数ですが全ページ修正いただけますか」というありがちな無茶振りを楽に捌ける。変数を格納するファイルを別に作っておいて、全ページで最初に読むと楽。
- var title = "Pug(Jade)の説明ページ|色々と説明するサイト";
doctype html
html(lang="ja")
head
meta(charset="UTF-8")
title #{title}
body
header
h1
a(href="#")
img.logo(src="img/logo.svg" alt=title)
↓
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>Pug(Jade)の説明ページ|色々と説明するサイト</title>
</head>
<body>
<header>
<h1>
<a href="#"><img src="img/logo.svg" alt="Pug(Jade)の説明ページ|色々と説明するサイト" class="logo"></a>
</h1>
</header>
</body>
</html>
条件分岐を作れる
例えば、トップだけ h1
にして他のページは p
にするなどの条件分岐が可能。
- var page = "index";
case page
when "index"
h1 タイトル
default
p タイトル
↓
<h1>タイトル</h1>
繰り返しを楽に書ける
「同じ書き方だけどテキストと画像だけ変えていく」みたいな繰り返し作業はHTMLだとコピペ修正地獄となり苦しい。Pugでは each
を使うことでとても簡単に処理できる。
ul
each val in [1, 2, 3, 4, 5]
li= val
↓
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
変数を入れ子にしてデータベース化することで柔軟な制作が可能。
-
var nav = {
index : {
title : "HOME",
url : "/"
},
about : {
title : "ABOUT",
url : "about.html"
},
works : {
title : "WORKS",
url : "works.html"
},
/*service : {
title : "SERVICE",
url : "service.html"
},*/
contact : {
title : "CONTACT",
url : "contact.html"
}
}
nav.nav.is-global
each val in nav
a.nav-item(href=val.url)
span.text= val.title
↓
<nav class="nav is-global">
<a class="nav-item" href="/"><span class="text">HOME</span></a>
<a class="nav-item" href="about.html"><span class="text">ABOUT</span></a>
<a class="nav-item" href="works.html"><span class="text">WORKS</span></a>
<a class="nav-item" href="contact.html"><span class="text">CONTACT</span></a>
</nav>
mixin
Sassと同じようにmixinが使える。書き方は +
を使って呼び出すようになっている。
mixin pet(name)
li.pet= name
ul
+pet('cat')
+pet('dog')
+pet('pig')
↓
<ul>
<li class="pet">cat</li>
<li class="pet">dog</li>
<li class="pet">pig</li>
</ul>
Markdown(npmライブラリ必須)
npmライブラリの jstransformer-markdown-it
を併用することでPugの中でMarkdownが使えるようになる。残念ながらPreprosではこの手法が使えない。
.wysiwyg
:markdown-it
## ソースコード
まずはローカルで読み込む。
↓
<div class="wysiwyg">
<h2>ソースコード</h2>
<p>まずはローカルで読み込む。</p>
</div>
やりすぎ注意
HTMLを条件分岐・ファイル分割するのは楽しいので凝ってしまいがち。あまりに複雑な組み方にしてしまうと、引き継ぎはもとより自分でも思い出せなくなってしまう。
条件分岐は発生するルールを決め、ファイル分割はAtomic Designを意識して「ページ・セクション・モジュール」の3階層と決めると安定する。
参考
自分が作っているライブラリのデモサイトはだいたいPugで書いているので、具体的な書き方を知りたい場合は参考にしてほしい。