11tyによる当サイトの制作記録(その2・開発環境構築〜テンプレートファイルの作成)
はじめに
その1で記したとおり、当Webサイトは静的サイトジェネレーター「11ty」を使用して制作しました。生成したHTMLファイルをWebサーバーにアップロードして公開しています。公開までの大まかな過程は、下記5ステップに分けられます。
- ローカルで11tyでの開発環境の構築
- テンプレートファイルの作成
- コンテンツファイルの作成
- CSS、JavaScriptなど、サイトの装飾用ソースコードを作成
- ブラウザでのプレビューと装飾用ソースコードの修正
ここでは、これらのステップのうち、1と2について紹介します。
11tyの使用にあたっては、株式会社豆蔵のデベロッパーサイトや、ZennでKey5nさんが執筆されている「静的サイトジェネレータ 11ty を使いながら説明してみる」を参考にさせていただきました。
1. ローカルで11tyでの開発環境の構築
-
開発用のディレクトリをローカルに作成し、そのディレクトリ上でターミナルから
npm init -y
を実行します -
続いて
npm install --save-dev @11ty/eleventy
として、11tyをインストールします画像はインストールが済んだ直後の開発用ディレクトリ(例:
eleventy_test
)配下のファイル構成です。node_modules
ディレクトリ配下に@11ty
があります。
-
ここで、トップページ
index.html
に適用するコンテンツファイルindex.md
を開発用ディレクトリ直下に作成しますここではファイルの1行目に
Hello world!
と書きました。
-
この状態でターミナルから
npx @11ty/eleventy --serve
と実行すると、サイトのデータが生成されます開発用ディレクトリ配下に
_sites
ディレクトリが作成され、その配下にトップページindex.html
が生成されます。ターミナルには[11ty] Server at http://localhost:8080/
などと表示されます。サイトのデータの生成とともに、localhost
が立てられます。ウェブブラウザでhttp://localhost:8080
にアクセスすると、index.md
に書き込んだHello world!
が表示されます。
2. テンプレートファイルの作成
テンプレート、コンテンツ両ファイル間の紐付け
テンプレートファイルを作ってコンテンツファイルと紐付けると、11tyが後者の内容を前者に代入してHTMLを生成します。
紐付けには、まずコンテンツファイル冒頭で、---
で挟んだYAML記述部分(front-matter)を設けます。その中にlayout: sample
と記述しておき、キーlayout
の値sample
を名前に持つテンプレートファイルsample.liquid
を用意します。こうして紐付けが可能になります。
コンテンツファイル冒頭のYAML部分では、キー名がテンプレートファイル内での変数名、値が同じく変数の値となります。上記のlayout
キーは11tyで独自定義されているため特殊な扱いとなりますが、下図の通りYAML部分にtitle: テスト投稿
とし、テンプレートファイルで<h1>{{ title }}</h1>
とすると、HTML生成時にテスト投稿
が{{ title }}
に代入され、<h1>テスト投稿</h1>
と出力されます。
また下図の通り、コンテンツファイルでのfront-matter以後の内容は、自動的にcontent
キーの値として扱われます。テンプレートファイルで変数{{ content }}
と記述すると、HTML生成時にfront-matter以後の内容が変数に代入されて出力されます。
上記のしくみを利用して、サイトに必要なテンプレートファイルとコンテンツファイルを作成してゆきました。
Liquid形式でのテンプレートファイルの作成
当サイトにはHTMLに記述方法が近いLiquid形式での作成が容易と判断しました。
11tyのデフォルトの設定では、開発用のディレクトリ直下に_includes
というディレクトリを作ると、この配下のファイルはテンプレートファイルとして認識されます。
サイトの作成にあたって、大まかに「トップページ用」「各記事のページ用」「同一タグ記事一覧ページ用」の3種類のLiquidファイルを_includes
ディレクトリ配下に設けました。
開発用ディレクトリ/
├─ _includes/ // テンプレートファイル格納ディレクトリ
│ ├─ index.liquid // トップページ用
│ ├─ article.liquid // 各記事のページ用
│ └─ tag_dummy.liquid // 同一タグ「dummy」記事一覧ページ用
├─ node_modules/
├─ package-lock.json
├─ package.json
├─ _site/ // 生成ファイル格納ディレクトリ
└─ index.md // コンテンツファイルの1つ(当頁1.で作成)
ソースコードの一例
トップページ用のテンプレートファイルindex.liquid
は下記のようなソースコードです。
{% include ... %}
は、他のテンプレートファイルをインポートする記述です。
コードブロックやページの部分ごとに子要素となるテンプレートファイルを設けることで、極力保守性を確保しました。
各子要素のテンプレートファイルの紹介は割愛しますが、例えば3行目の{% include "head/_for_index.liquid" %}
には、HTMLの<head>
タグの範囲内の内容を記しています。
<main>
タグ範囲内の中盤は、過去10記事を見出しにして載せられるようにしています。
9行目、{% for item in collections.topItems %}
のcollections
は、コンテンツファイルのfront-matterで設けた特定のタグなどをキーに集めた配列様のオブジェクトです。これに対し{% for %}
と{% if %}
を組み合わせれば、オブジェクトに格納されている要素と、Liquidファイルに記したHTMLタグとの組み合わせで、条件に合った内容の一覧を作成することもできます。
<!DOCTYPE html>
<html lang="ja">
{% include "head/_for_index.liquid" %}
<body>
<main>
{% include "body/header.liquid" %}
{% assign itemCount = 0 %}
{% assign limit = 10 %}
{% for item in collections.topItems %}
{% assign segArr = item.page.url | split: "/" %}
{% for elem in segArr %}
{% if elem == "articles" %}
{% if itemCount <= limit %}
{% if itemCount < 1 %}
{% include "body/article_area.liquid" %}
{% assign itemCount = itemCount | plus: 1 %}
{% elsif itemCount < 5 %}
{% include "body/section_area.liquid" %}
{% assign itemCount = itemCount | plus: 1 %}
{% elsif itemCount < 10 %}
{% include "body/topic_area.liquid" %}
{% assign itemCount = itemCount | plus: 1 %}
{% endif %}
{% endif %}
{% endif %}
{% endfor %}
{% endfor %}
{% include "body/footer.liquid" %}
</main>
{% include "body/realtype_script.liquid" %}
</body>
</html>
この後は、コンテンツファイルの作成、CSSやJavaScriptといったサイト装飾用ソースコードの作成、ブラウザでのプレビューと装飾用ソースコードの修正です。これらの内容は、引き続き「その3」として後日アップしたいと思います。