解釈の順番

29 January 2017 tomjoht tomjoht

Jekyllの主な仕事は、あなたのテキストファイルを静的Webサイトに変換することです。LiquidやMarkdown、その他の変換を行い、静的HTMLを作成し出力します。

この変換プロセス中の、Jekyllの解釈の順番を理解することは重要です。「解釈の順番」は、何がレンダリングされるのか、どのような順序でレンダリングされるのか、そしてコンテンツの変換にどのような規則が適用されるのかを意味します。

要素が変換されない場合は、解釈の順番を分析して問題を解決できます。

解釈の順番

Jekyllは以下の順番でサイトを作成します。

  1. サイト変数 Jekyllはファイルを調べてsite, page, postやコレクションオブジェクトといったサイト変数を設定します。(これらから、パーマリンク、タグ、カテゴリなど詳細の値を決定します)
  2. Liquid front matterを含むページのLiquidフォーマットを処理します。次のようにLiquidを識別できます。
    • Liquid タグ {%から%}まで。例えば、{% highlight %}{% seo %}タグはブロックを定義することもインラインにすることもできます。 ブロック定義タグには対応する終了タグも付きます — {% endhighlight %}など。
    • Liquid 変数 2つの中括弧で囲まれた部分。例えば、{{ site.myvariable }}{{ content }}
    • Liquid フィルタ Liquid 変数内でのみ使用できる、変数名の文字列の後で縦棒(|)から始まる部分。例えば、{{ "css/main.css" | relative_url }}中のrelative_urlフィルタ。
  3. Markdown 設定ファイルで指定されたMarkdownフィルタを用いてJekyllはMerkdownをHTMLに変換します。Jekyllがファイルを変換するためには、ファイルにMarkdownファイル拡張子とfront matterが必要です。
  4. レイアウト (設定ファイルや)ページのfront matterで指定されたレイアウトに、コンテンツを押し込みます。コンテンツはレイアウト内の{{ content }}タグ部に入ります。
  5. ファイル 生成されたコンテンツを_siteのディレクトリ構造内のファイルに書き込みます。 ページ、ポスト、およびコレクションは、パーマリンクの設定に基づいて構造化されます。_で始まるディレクトリ(_includes_dataなど)は通常、出力時には隠されます。

誤った構成が問題を引き起こすシナリオ

Jekyllサイトの構築で、多くの場合は解釈の順番を考える必要はありません。レンダリングが上手くいかない場合にこれらの詳細が重要になります。

以下のシナリオでは、発生する可能性がある潜在的な問題を強調しています。これらの問題は解釈の順番の誤解から来ており、簡単に修正することができます。

レイアウト上で割り当てられた変数はページ上ではレンダリングされません

レイアウトファイル(_layouts/default.html)で変数を割り当てたとします。

{% assign myvar = "joe" %}

レイアウトを使用するページで、その変数を参照します。

{{ myvar }}

変数はレンダリングされません。なぜなら、まずLiquidをレンダリングしてからレイアウトのプロセスに移行するという順番で解釈するためです。Liquidがレンダリングされる時点では、変数はまだ割り当てられていません。

このコードを動かすためには、変数の割り当てをページのfront matterで行います。

インクルードファイルのMarkdownは処理されません

_includes/mycontent.mdというMarkdownファイルがあるとします。Markdownファイルでは、Markdownのフォーマットで書かれています。

This is a list:
* first item
* second item

以下のように、HTMLファイルに先ほどのファイルをインクルードします。

{% include mycontent.md %}

Markdownは処理されません。なぜなら、Liquid(include)タグがまず処理され、mycontent.mdがHTMLファイルに挿入されるためです。Markdownはそれから処理されることになります。

ですが、HTMLページに挿入したため、Markdownは処理されません。Markdownの変換プロセスは、Markdownファイルでのみ行われます。

コードを動かすためには、HTMLファイルにインクルードするファイルはHTML形式にします。

highlightタグはMarkdownの処理を必要としません。以下のインクルードコンテンツがあるとします。

{% highlight javascript %}
console.log('alert');
{% endhighlight %}

highlightタグはLiquidです。(Liquidはコンテンツを構文強調表示のためにRougeに渡します。)その結果、このコードはHTMLにシンタックスハイライト処理され変換されます。JekyllはhighlightタグにMarkdown処理のプロセスを必要としません。

LiquidとJavaScriptを混合するとレンダリングされません

LiquidのassignタグをJavaScriptで使おうとしているとします。

<button onclick="someFunction()">Click me</button>

<p id="intro"></p>

<script>
{% assign someContent = "This is some content" %}
function someFunction() {
    document.getElementById("intro").innerHTML = someContent;
}
</script>

assignタグはサイトのLiquidレンダリング中のみ使用可能ですので、これは動きません。このJavaScriptの例では、HTMLページでユーザーがボタン(”Click me”)をクリックしたときに実行されます。Liquidロジックはもはや有効ではなく、assignタグは何も返しません。

しかしながら、Jekyllサイトの変数やLiquidを、後からスクリプト実行時に渡す事もできます。例えば、someContent: "This is some content"のfront matterプロパティがあるとします。次のようにできます。

<button onclick="someFunction()">Click me</button>

<p id="intro"></p>

<script>

function someFunction() {
    document.getElementById("intro").innerHTML = "{{ page.someContent }}";
}
</script>

Jekyllがビルドするときに、someContentプロパティをスクリプトの値に渡し、{{ page.someContent }}"This is some content"に変換します。

JekyllがビルドするときにLiquidをレンダリングすることを覚えておいてください。Liquidはブラウザで実行時のユーザーイベントでは利用できません。

YAMLでのLiquid使用についてのメモ

LiquidはYAMLやfront matterではレンダリングされないことを覚えておいてください。(これは解釈の順番とは関係ありませんが、要素のレンダリングに関する一般的な問題ですので、言及する価値があります。)

例えば、highlightタグを_data/mydata.ymlファイルで使用したい場合を考えます。

myvalue: >
  {% highlight javascript %}
  console.log('alert');
  {% endhighlight %}

ページにこの値を挿入します。

{{ site.data.mydata.myvalue }}

これは、構文を強調表示するコードサンプルではなく、文字列として表示されます。 コードをレンダリングするには、代わりにインクルードを使用することを検討してください。