吉本式 Web制作のコーディングガイドライン

美しいコーディング・設計をするためのガイドラインコンテンツです。

Pugのファイル設計について(LPなどの1ページ案件)

Pugのファイル設計は、SCSSファイルの設計に比べて複雑ではありません。
実務を通して、色々と試してみましたが、ルールが統一されていれば、基本的には自分(チームや会社)が見やすいファイル設計で問題ないと思っています。
複雑なファイル設計にはならないので、第三者が見てもすぐにどのようなファイル設計になっているか理解できるはずです。
ただし、ルールが統一されているというのは重要なポイントです。
ルールが統一されていなければ、第三者が見たとき(引き継いだとき)に、どのようなファイル設計になっているのか判断ができません。

私の場合、LPなどの1ページ案件と、コーポレートサイトのような複数ページ案件で、ファイル設計のルールを分けています。
LPなどの1ページ案件に関しては、include(インクルード)ファイルを分けなくても問題ないと個人的には思っています。
そうなると、ファイル設計はとてもシンプルになります。

それでは今回はまず、LPなどの1ページ案件のPugのファイル設計について、パターンを提案してみます。

1ページ案件(LPなど)のファイル設計 : 設定ファイルのみをインクルード

  • pug
    • _config.pug
    • index.pug

とてもシンプルなファイル設計ですが、1ページ案件なので問題ないと思っています。
ただし、ルートディレクトリや画像ディレクトリなどのパス設定などは、_config.pugファイルにまとめて外部化します。
1ページであれば、直接index.pugに記述しても問題はないと思われますが、Pug言語に限らず、設定コードの管理は外部化するという癖をつけておいたほうが良いです。

_config.pug
- var ROOT_PATH = '/';
- var IMG_PATH = ROOT_PATH + 'img/';

設定ファイルである_config.pugファイルには、変数ROOT_PATHと変数IMG_PATHを用意します。
変数ROOT_PATHにはルートディレクトリを、変数IMG_PATHには画像ディレクトリを設定しておきます。

_config.pug
- 
var GLOBAL_MENU = {
ABOUT: ROOT_PATH + 'about/',
PRODUCT: ROOT_PATH + 'product/',
NEWS : ROOT_PATH + 'news/',
CONTACT: ROOT_PATH + 'contact/'
}

コーポレートサイトのような複数ページの案件であれば、上のようにグローバルメニューなどのリンク系をまとめておくと便利です。
その他、外部管理しておくと便利な変数などが出てくるようであれば、この_config.pugファイルで管理してください。

1ページ案件(LPなど)のファイル設計 : head要素内、header要素、footer要素、script要素をインクルード

  • pug
    • _config.pug
    • include
      • _head.pug
      • _header.pug
      • _footer.pug
      • _script.pug
    • index.pug
index.pug
include ./_config
- var page = pagelist['home'];

doctype html
html(lang="ja")
head
include ./include/_head
body
include ./include/_header
main.main
・・・ コンテンツのマークアップ
include ./include/_footer
include ./include/_script

LP案件の場合、私は普段、このような分け方で実装をしています。
main要素内のコンテンツ部分に関しては、直接index.pugファイルに記述します。
2行目の変数pageに、ページ情報をpug.config.jsから取得し代入していますので、その情報を使ってhead要素内のコードを次のように設定します。

_head.pug
meta(charset="UTF-8")
title #{page.title}
if page.description !== ''
meta(name="description" content=page.description)
if page.og.title !== ''
meta(property="og:title" content=page.og.title)
・・・ 省略
if page.twitter.title !== ''
meta(name="twitter:title" content=page.twitter.title)
・・・ 省略
link(rel="stylesheet" href=ROOT_PATH+"css/style.css")
if page.name == 'home'
link(rel="stylesheet" href=ROOT_PATH+"css/home/style.css")
if page.name == 'page'
link(rel="stylesheet" href=ROOT_PATH+"css/page/style.css")

meta要素に関しては、if文を使用して、情報が空だった場合は、コードを出力しないようにしています。
cssのlink要素も同様に、page.nameを参照し、該当ページに該当のcssファイルを読み込むようにします。
_script.pugも同様の記述になります。

_script.pug
script(src=ROOT_PATH+"js/plugins.js")
script(src=ROOT_PATH+"js/main.js")
if (page.name == 'home')
script(src=ROOT_PATH+"js/home.js")
if (page.name == 'page')
script(src=ROOT_PATH+"js/page.js")

全ページ共通で読み込むjsファイルはそのまま記述し、該当ページのみ使用するjsファイルに関しては、if文でpage.nameを比較し、該当のjsファイルを読み込むようにします。

1ページ案件(LPなど)のファイル設計 : コンテンツを分けてインクルード

  • pug
    • _config.pug
    • include
      • _head.pug
      • _header.pug
      • _footer.pug
      • _script.pug
      • _kv.pug
      • _search.pug
      • _menu.pug
      • _share.pug
      • _contact.pug
      • _news.pug
    • index.pug
index.pug
include ./_config
- var page = pagelist['home'];

doctype html
html(lang="ja")
head
include ./include/_head
body
include ./include/_header
main.main
include ./include/_kv
include ./include/_search
include ./include/_news
include ./include/_contact
include ./include/_share
include ./include/_menu
include ./include/_footer
include ./include/_script

赤字となっている箇所がコンテンツ要素になっており、includeファイルとして外部化しています。
以前までは、私もこのようなファイル設計で実装していましたが、現在は分けていません。
理由としては、コンテンツ部分は案件ごとに異なっており、毎回外部化するという手間がかかるためです。
一方、head要素内、header要素、footer要素、script要素に関しては、どの案件でも出てきますので、テンプレ化ができます。

Pugにはテンプレート機能があります。
先ほどhead要素内、header要素、footer要素、script要素に関してはテンプレ化ができると解説しましたので、これらをテンプレート機能を使ってもう少しファイル設計を細分化できます。
ここからは、以前解説した「Web制作の開発環境とファイル構成について」のサンプルデータにはないファイルになりますので、もし興味があれば、次の解説を読みながら更新してみてください。

Pugのテンプレート機能を使用したファイル設計

  • pug
    • _config.pug
    • _layout.pug
    • include
      • _head.pug
      • _header.pug
      • _footer.pug
      • _script.pug
    • index.pug

_layout.pugファイルを用意します。
このファイルは、テンプレートファイルになりますので、共通部分をこのファイルに記述します。

_layout.pug
block config
doctype html
html(lang="ja")
head
block head
include ./include/_head
body
include ./include/_header
block content
include ./include/_footer
block script
include ./include/_script

Pugのテンプレート機能についての詳しい解説は割愛します。
興味があれば、調べてみてください。(難しいものではありません)
block部分が共通部分ではない可変コードになります。
この可変コードの部分を各ページごとに記述していきます。
それでは、_layout.pugを読み込むindex.pugをみていきます。

index.pug
extends ./_layout // _layout.pugを読み込みテンプレートとして使用する

block config
include ./_config
- var page = pagelist['home'];

block append head
link(rel="stylesheet" href=rootPath+"css/home/style.css") // index.htmlにのみ必要なcssファイル

block content
// main
main
p TOPページのメインコンテンツ
// /main

block append script
script(src=rootPath+"js/home.js") // index.htmlにのみ必要なjsファイル

index.pugは上のようなコードになります。
このテンプレート機能を使った記述方法にすることで、_head.pugと_scrpit.pugでページごとに分岐していたcssファイル、jsファイルの読み込みをindex.pugに記述することができます。
そのため、_head.pugと_scrpit.pugには、サイト共通で読み込む必要のあるcssファイル、jsファイルのみを記述すれば良いので、次のように書き換えます。

_head.pug
meta(charset="UTF-8")
title #{page.title}
if page.description !== ''
meta(name="description" content=page.description)
if page.og.title !== ''
meta(property="og:title" content=page.og.title)
・・・ 省略
if page.twitter.title !== ''
meta(name="twitter:title" content=page.twitter.title)
・・・ 省略
link(rel="stylesheet" href=ROOT_PATH+"css/style.css") // サイト共通のcssファイル
_script.pug
script(src=rootPath+"js/plugins.js") // サイト共通のjsファイル
script(src=rootPath+"js/main.js") // サイト共通のjsファイル

以上がPugのテンプレート機能を使用したファイル設計になります。
次の記事では、コーポレートサイトなどの複数ページ案件のPugのファイル設計について解説したいと思います。