長くJekyllのことを書いてきましたが、今回で最後です。
今回は、Jekyllでサイトを作る上で中心となるLiquidのポイントを説明します。 Liquidには簡潔なドキュメントがありますので、参考にしてください。
Liquidの基本
Liquidはhtmlの中に埋め込みます。 ちょうどphp、あるいはRailsのeRubyに似ています。 埋めこむ対象が3つあります(オブジェクト、タグ、フィルター)。 また、Liquidが埋め込まれたHTMLをテンプレートと呼んでいます。
オブジェクト
オブジェクトは、何らかの情報を持っているものです。
オブジェクトは変数で参照されます。
例えば、page
という変数はページの情報を持っているオブジェクトを指しています。
その情報はドット記法で参照します。
page.title
ページのタイトルpage.description
ページのディスクリプション
オブジェクト「page」につけたドットの後の部分をプロパティといいます。 titleやdescriptionはpageオブジェクトのプロパティです。 ページのフロントマターに記述されたものはプロパティになり、ドット記法で参照することができます。
オブジェクトをHTMLの中に表示するには二重波カッコを使います。
{{ page.title }}
タグ
タグは制御構造(分岐、ループ)、テンプレート(コメント、raw)、変数への代入などです。 他の言語のステートメントにあたるものです。 タグを使うときは、それを出力することは原則としてありません。 タグは波カッコとパーセントで囲みます。
{% if page.title == "サンプル" %}
フィルター
フィルターは縦棒|
で左の出力を右に流すものです。
ちょうどシェル・スクリプトのパイプのようなものです。
出力結果はHTMLに表示することが多いので二重波カッコを使うことが多いです。
{{ page.title | escape }}
パイプの右側にフィルターの動作を記述します。 escapeはHTMLで特殊な意味を持つ記号をエスケープします。 例えば<を<と変更します。
フィルターは多くの動作をサポートしています。 他の言語、例えばRubyなどの演算子やメソッドの役割をフィルターが担っています。
Jekyllで使う変数
Jekyllで使える変数はJekyllのドキュメントに書かれています。 変数はLiquidで使います。
グローバル変数は次のとおりです。
- site => サイトの情報。_config.ymlに書かれた情報をもつオブジェクトを参照する(以下「オブジェクトを参照する」を略す)
- page => ページの情報。ページのフロントマターに書かれた情報
- layout => レイアウトの情報。そのフロントマターの情報
- content => ページのコンテンツ
- paginator => パジネーター。ブログ記事がたくさんある場合など、それをページに分割するときに使う
siteの情報を見るのに「site.url」(サイトのURL)のようにドット記法が使えます。 詳細はJekyllのドキュメントを参照してください。
Liquidのオペレーター
Liquidのオペレータはコントロールフロー(ifなど)やループ(for)の条件に使えます。
- ==
- !=
- >
- <
- >=
- <=
- or
- and
- contains => 左側の文字列が右側の文字列を含んでいればtrue
オペレータが複数ある場合は右から順に評価されます。
また、かっこ((
と)
)で評価順を変更することはできません。
Liquidには算術演算子(加減乗除)がありません。 その代わりにフィルターを使います。
タグ(Liquidの制御構造)
ここでは項目が多いので極めて簡単な説明だけになっています。 詳しい説明はLiquidのドキュメントを見てください。
コントロール・フロー
コントロール・フローは条件分岐です。 他の言語と同様の条件分岐ができます。 コントロール・フローは次の2種類です。
- if/unless (条件)〜 elsif/else 〜 endif
- case(条件)when 〜 [when 〜] else 〜 endcase
イテレーション(ループ)
ループをLiquidではイテレーションと呼んでいます。
- for (条件)〜 else 〜 endfor。 for文の中のelseは条件が成り立たなかった時に出力される
- break => ループを中止して外にでる
- continue => ループの現在の回をスキップして次の回にすすむ
- forループにはlimit/offset/range/reversedのオプションをつけることができる
- forの中でcycle (項目のリスト)を使うことができる。 項目は1回目はリストの最初の項目、2回めは2番めの項目・・・と出力される
- tablerow => ループの中でHTMLの表の行を出力する。 cols/limit/offset/rangeのオプションをつけることができる
tablerowはHTMLの表を作れるので便利です。 HTMLテンプレートらしい機能です。
テンプレート
- comment 〜 endcomment => コメントとして扱われHTML出力されない
- raw 〜 endraw => Liquidの解釈をせずにそのまま出力される。 例えば二重波カッコをそのまま出力したい場合に使う。
- liquid => 複数行にわたりLiquidの構文を書くことができる。
いちいち
{% %}
で囲まずにすむのがありがたい - echo => タグの中で用いられ、echoの次の要素を出力する。 フィルターを使える
- render => 他のテンプレートファイルを読み込む
変数
- assign => 変数への代入をする
- capture => 変数への代入をする
- increment/ decrement => 引数に変数をとり、0/-1からはじめて変数を1ずつ増加/減少させ、その値をHTMLに出力する。
JekyllのLiquidで良く用いられるフィルター
以下では、JekyllのLiquidで良く用いられる書き方を順不同で説明します。
default
パイプの左側からの入力がnil、false、空文字列のいずれかであるときに引数の値を出力し、それ以外は入力をそのまま出力します。
{{ page.title | default: 無題 }}
- ページタイトルが設定されていれば、その文字列を出力
- ページタイトルが設定されていなければ「無題」を出力
おそらく最も使われているフィルターです。
relative_url
ベースURLを加えたURLにします。
GitHubを例にとって説明します。
GitHub Pagesのサイトはhttps://ユーザ名.github.io/
以下に展開されます。
そのスペースを分割していくつかのサイトを構築する場合、ベースURLを個々のサイトにつけます。
例えば、そのサイトのベース名がjekyll-tutorial-for-beginners
であれば、そのサイトはhttps;//ユーザ名.github.io/jekyll-tutorial-for-beginners/
をベースとして展開されることになります。
URLの指定には3通りがあります。 例えばサイトのルートにあるabc.htmlは
- https;//ユーザ名.github.io/jekyll-tutorial-for-beginners/abc.html これを絶対URLといいます
- /jekyll-tutorial-for-beginners/abc.html これはいろいろの呼び方をされていますが、「The URL Standard」によると絶対URLの一種で、「path-absolute-URL string」(絶対パスURL文字列)というようです。 ですが、https:のついた絶対URLとは振る舞いが違います。
- 今かりに
https;//ユーザ名.github.io/jekyll-tutorial-for-beginners/abc.html
の画面を開いているとします。 そのとき、現在の画面のURLとabc.htmlのURLは最後の部分の違いだけです。 URLを単に「abc.html」と表現することを相対URLといいます。 現在画面のURLと相対URLを組み合わせると絶対URLを求めることができるので、これもURLの表現として可能です。
このうち2番めが問題になります。
/
(ルート)がどこに設定されるのかはサーバによります。
GitHubでは/
はhttps;//ユーザ名.github.io/
と解釈されます。
ですから、サイトのルートhttps;//ユーザ名.github.io/jekyll-tutorial-for-beginners/
はGitHubのルートとずれがあるわけです。
この差jekyll-tutorial-for-beginners
をJekyllではBase URLといいます。
relative_urlフィルターは流れてきた文字列の先頭にBase URLを付け加えます。 なお、Base URLは_config.ymlの中で定義します。
_config.yml での定義 baseurl: /jekyll-tutorial-for-beginners {{ "/assets/image/abc.png" | relative_url }} これにより、出力は次のようになる => /jekyll-tutorial-for-beginners/assets/images/abc.png
このことによって、サイトのルートがGitHubのルートに一致するようになります。 なお、baseurlのデフォルト値は空文字列です。
Base URLを定義するかどうかはサーバーサイトのルートの解釈で決まってきます。 また、URL表現の1,3番すなわちhttpsから始まる絶対URLまたは相対URLを使っている限りはこの問題は起きません。 ですから、複雑さを避けるには相対URLのみを使うのが良いと思います。
ただし、Liquidでpage.urlを参照すると/
から始まる絶対パスURLが帰ってくるので、relative_urlが必要になります。
absolute_url
文字列の先頭にsite.urlとsite.base_urlを加えます。 前提として_config.ymlにurlを登録することが必要です。
url: https://(ユーザ名).github.io
文字列の最後にスラッシュはつきません。 デフォルト値はhttps://lofalhost:4000です。
escape
escapeはHTMLで特別な意味を持つ文字をエスケープします。
- < => <
- > => >
- & => &
これ以外にもエスケープ文字はあるので、詳細はインターネットで調べてみてください。 とくに<と>が現れるとHTMLタグと解釈されてしまうので、文字そのものを出力するにはエスケープが必要です。 このときescapeフィルターをかけてやります。
例えばpage.titleにはエスケープしなければならない文字が入っているかもしれません。 page.titleはレイアウトの中で使うことが多いと思います。 その場合レイアウトの使用者は自分自身とは限りません。 あらかじめエスケープすべき文字が入っているかどうかわからないので、escapeは必須です。
strip_html
HTMLタグを取り去りたいときに使います。 markdownifyを使う後に使うことが多いと思います。 marakdownifyの説明は後でします。
{{ f.image_caption | markdownify | strip_html }}
「マークダウンをHTMLに変換してタグを取る」ということは、ベタなテキストを手に入れることになります。
replace
文字列置換です。 1番めの引数を2番めの引数に置換します。
{{ "暑いなあ" | replace: "暑い", "寒い" }} => 寒いなあ
split
文字列を引数をデリミタとして分割した配列にします。
{% assign ary = "abc, def, ghi, jkl" | split: ", " %} {% for s in ary %} {{ s }} {% endfor %} => abc def ghi jkl
結果は4行になっていますが、HTMLなのでブラウザ上の表示はつながってしまいます。 このように、コンマ区切りのデータを配列にするときに良くつかいます。
markdownify
これは、Jekyllが拡張したフィルターです。 マークダウンで記述された文字列をHTMLに変換します。 マークダウンで書かれたデータを処理するケースで使います。
date
タイムスタンプを別の形式の時刻表示に切り換えます。 形式の指定は引数の文字列で与えます。 形式にはstrftimeが用いられます。
{{ "2022-8-21" | date: "%Y 年 %m 月 %e 日" }} => 2022 年 08 月 21 日
remove
引数の文字列を削除します。
{{ "<p>abcd</p> | remove: <p> | remove </p> }} => abcd
シリーズの最後に
はじめてみたら9回も続くことになった「Jekyllを勉強中」は今回で終わります。 自分自身が勉強をしながらの説明だったので、不十分なところが多々ありましたことをお詫びします。
GitHubにチュートリアルをあげました。 このチュートリアルはCaymanをテーマに、Jekyllで作られています。 内容はこのブログとほとんど同じですが、構成を変え、説明をより分かりやすくなるように手直ししました。