Jekyllで作るWebサイトのURLをいい感じにする方法

この記事の効能
- 一つ一つのページに任意のURLを設定出来るようになります
- 各ページに一定のルールでURLを割り振れるようになります
- 公式に書いてあるPermalinks, Front Matterあたりの仕組みを理解できます
- ついでに関連するCollectionsという機能をやんわり理解できます
仕組みを知る
変換対象となるディレクトリ構成
Jekyllのルールに則ったディレクトリにコンテンツ(ファイル)を配置すると、Jekyllはそのファイルを静的ページ(HTML)に変換してくれます。そして静的ページ1つ1つに対してURLが付与されます。
例えば記事のように蓄積されていくコンテンツの場合、_posts以下にコンテンツファイルを配置することで記事ごとのHTMLを生成してくれます。
.
├── _config.yml
|
(省略)
|
├── _posts
| ├── 2018-04-01.md
| └── 2018-04-02-how-to-use.md
URL生成のルールとファイル命名ルール
Jekyllはコンテンツのファイル名をもとにURLを自動生成します。そのため、コンテンツファイルは<year4桁>-<month2桁>-<day2桁>-<タイトル>.mdと命名する必要があります。
これをもとにJekyllは/year4桁/month2桁/day2桁/タイトル.htmlというURLのHTMLを生成します。加えて、記事にカテゴリを指定している場合は/カテゴリ/year4桁/month2桁/day2桁/タイトル.htmlというURLのHTMLを生成します。
例
- 2018-04-01.md
→/2018/04/01.html - 2018-04-02-how-to-use.md
→/2018/04/02/how-to-use.html - 2018-04-03.mdに「diary」カテゴリを指定
→/diary/2018/04/03.html - 2018-04-04-cooking.md「diary」「recipe」カテゴリを指定
→/diary/recipe/2018/04/04/cooking.html
このURL生成ルールをJekyllの設定的には/:categories/:year/:month/:day/:title.htmlと表現します。
1つ1つの記事に任意のURLを付与する
上述のURL生成ルールがJekyllのデフォルトなのですが、このルールを無視して記事ごとに独自のURLを付与することができます。記事の冒頭でタイトルなどを定義する領域( = Front Matter )にpermalinkという項目を追記します。
2018-04-01.md
---
title: Jekyllの使い方
permalink: /article/how-to-use
---
こうすることでファイル名の日付を無視して/article/how-to-useというURLで記事を生成してくれます。
余談ですが、このFront Matterはテンプレート内で使える変数を宣言することができます。たとえば複数人から入稿されるサイトにて記事内にWriter名を表示したい場合は、以下のようにFront Matterを利用できます。
_posts/2018-04-01.md のFrontMatterにwriterという項目を定義
---
title: Jekyllの使い方
permalink: /article/how-to-use
writer: aloerina
---
_layouts/post.html テンプレートからpage.writerという変数で値を利用
<h1>{{ page.title }}</h1>
<!-- 省略 -->
<p>{{ page.writer }}</p>
すべてのpostsに一定のルールでURLを付与する
Front Matterを使えば記事1つ1つに個別のURLを設定できました。しかしこれを毎回書くのは面倒くさいですよね。そこで_config.ymlを使ってFrontMatterのデフォルト値を指定します。「URLを/artilce/<タイトル名>.htmlとする」例を使って解説します。
_config.ymlの設定例
defaults:
- scope:
path: ""
type: "posts"
values:
permalink: /article/:title.html
ポイント1: Front Matterのデフォルト値を指定する
Front Matterのデフォルト値を指定するdefaultsには、大きく2つの項目があります。どのファイルに対してデフォルト値を設定するかを表すscopeと、どんなデフォルト値にするかを表すvaluesです。
valuesほうが理解は簡単で、FrontMatterに書くときと同じように書けばOKです。URLを指定したいならpermalink: xxxxと、カテゴリを指定したいならcategories: xxxxxと書くだけです。上述したwriterのような独自の変数をここで定義することもできますし、複数の項目を並べて指定することもできます。
今回はURLにタイトルを入れたいので:titleという変数を使いましたが、他にもpermalinkの指定に使える変数があります。
| 変数名 | 説明 |
|---|---|
| :year | Postのファイル名から取得できる年 |
| :month | Postのファイル名から取得できる月 |
| :i_month | Postのファイル名から取得できる0埋めしない月 |
| :day | Postのファイル名から取得できる日 |
| :i_day | Postのファイル名から取得できる0埋めしない日 |
| :short_year | Postのファイル名から取得できる年の下2桁 |
| :title | Postのファイル名から取得できるタイトル |
| :categories | Postに対して指定されたカテゴリ もしカテゴリが存在しない場合は無視 |
| :date | /:categories/:year/:month/:day/:title.html Jekyllに組み込まれているPermalink 何も指定しない場合はこれが適用される |
| :pretty | /:categories/:year/:month/:day/:title/ |
| :none | /:categories/:title.html |
ポイント2: FrontMatterのデフォルト値の適用範囲を指定する
scopeはpathとtypeという2つの要素を持ちます。valuesとは違いこれら以外の要素を追加することはできません。
pathとはどのディレクトリにあるファイルに対してデフォルト値を適用するのかを表します。上の例のように空文字にした場合はすべてのファイルが適用対象になります。空文字でもいいのですが必須の項目です。
typeはpath内にあるファイルのうち、該当するタイプのファイルに対してデフォルト値を適用するという絞込を行う機能です。そのためtypeはなくてもOKな項目です。ちなみに_posts以下にあるファイルには内部的にpostsというタイプが割り当てられています。
つまり今回の設定例では、全ファイルの中でpostsタイプのファイルにpermalinkをデフォルトとして適用するとなるわけです。
pathとtypeを組み合わせてデフォルト値の適用範囲を設定できるわけですが、このtypeが聞きなれず設定の仕方も少し厄介なので次項でまとめてみます。
ポイント3: Collectionsの機能を使ってtypeを追加する
Webサイトは記事ページ(Jekyll内ではpostsと呼ばれるもの)だけですべてがまかなえるわけではなく、たとえば写真や制作物を載せるページであったり、Documentを載せるページであったりと、様々な様式のページが必要になることがあります。これを表現するのがtypeという概念であり、typeを定義するものがCollectionsです。
実は_config.ymlには内部的に以下のような設定を持っています。
collections:
posts:
output: true
これは「postsというタイプを用意して、これをJekyllの変換対象とする」ということを表現しています。そしてこのtype名に_をつなげた_postsディレクトリ以下にあるファイルが、postsタイプのファイルとなります。
つまりtypeを増やしたい場合は以下の2つの作業が必要ということになります。
- Collectionにtypeを定義する
- 定義したtype名の先頭に
_をつけたディレクトリを用意する
この機能により、最初に記した「変換対象となるディレクトリ」を増やすことができ、またpathと組み合わせてdefaultsの適用範囲を柔軟に指定できるようになるわけです。
まとめ
- Jekyllのコンテンツファイルには命名ルール(
:year-:month-:day-:title.md)がある - Jekyllはデフォルトで
/:year/:month/:day/:title.htmlというURLを生成する - 記事個別にURLを指定する場合はFront Matterを使う
- 記事一括でURLを指定する場合は
_config.ymlにdefaultsを指定するvaluesでデフォルト値を定義するscopeでデフォルト値の指定範囲を定義するpathは適用対象となるディレクトリを表すtypeはpath内にあるファイルをさらに絞り込むのに使う
- typeを増やすには
_config.ymlにCollectionsを指定する- 何も指定せずとも
postsタイプだけは内部的に定義されている - Collectionsにtypeを指定したら、
_type名というディレクトリを用意する
- 何も指定せずとも
けっこう複雑で理解するまでに苦労しましたが、わかってしまえば自在にURLを設定することができて便利でした。このブログのソースもGithub上で公開していますので、ご参考にどうぞ。