追記 2022/8/23: コレクションの名前に「documents」を使っていましたが、この名前はJekyll自身が別の意味で使う変数になっていたので、「chapters」に変更しました。
また、_config.ymlの中で使っていたsort_byキーはJekyll4.0以降で可能ですが、GitHub のJekyllのバージョンは3.9.2でまだサポートされていません。
そこでsort_buキーを使わないように変更しました。
追記 2022/8/19: GitHub にあげる場合、baseurlの設定が必要な場合があります。
修正点は2つで(1)_config.ymlにbaseurlを設定する(2)レイアウトにrelative_urlフィルタを追加する、です。
baseurlの解説はJekyllを勉強中(9) にあります。
この記事中のプログラムは修正済みです。
今回は、レイアウトについて説明します。
あわせて、Jekyllが採用しているテンプレート言語のLiquidについても簡単な説明をします。
ファイルの構成と配置
このシリーズで例にとりあげてきた「Jekyll tutorial for beginners」の構成を考えてみます。
このうちドキュメントは「_chapters」フォルダに入れることにします。
ディレクト リ名の最初にアンダースコア(_
)がつくのは、Jekyllのコレクションという機能を使うからです。
+--- _config.yml
+--- index.md
+--- about.md
+--- toc.md
+---_chapters
| +--- doc1.md
| +--- doc2.md
| + ... ... ...
+---assets
| +--- css
| +--- images
| +--- js
+---_site
... ... ...
トップディレクト リ以下のファイル構成が出力ディレクト リ_site以下に反映されます。
ただし、Markdown =>HTML、Scss=>Css と変換して生成されます。
生成されたページ相互に行き来できるようリンクを付けなければなりません。
コンテンツ内上部にリンクを横並びに設置する方法を取ることにします。
このリンクのことをコンテンツ・ナビゲーション(短くして「コナビ」)と呼ぶことにします。
これは、このブログの中での呼び方で、一般に使われるものではありません。
複数のファイルで同じコナビが使われるので、コナビはレイアウトに記述するのが良いです。
レイアウトhome.html
「index.md」「about.md」「toc .md」の3つのファイルのコナビを記述するレイアウトを「home.html」とします。
新たに_layoutsフォルダを作り、その下にhome.htmlを置きます。
---
layout: default
---
< ul class = "nav" >
< li >
< a href = {{ "/index.html" | relative_url }}> トップページ </ a >
</ li >
< li class = "nav" >
< a href = {{ "/about.html" | relative_url }}> Aboutページ </ a >
</ li >
< li class = "nav" >
< a href = {{ "/toc.html" | relative_url }}> 目次 </ a >
</ li >
</ ul >
{{ content }}
フロントマターにlayout: default
があるので、デフォルトのレイアウトのコンテンツにhome.htmlのレイアウトが設定されます。
それぞれのページへのリンクが順序なしリストになっています。
リンクにかかっているフィルターの説明は「Jekyllを勉強中(9)」にあります。
クラスnav
のスタイルシート は「style.scss」に記述し、assets/css
フォルダに置きます。
---
---
@import "{{ site.theme }}" ;
ul .nav {
display : flex ;
}
li .nav{
list-style : none ;
margin-left : 20px ;
}
(注意)このファイルの内容はcss ですが、インポートするファイルがscssなので、拡張子はscssにします。
site.theme
は_config.yml
で設定したthemeキーの値で、「jekyll-theme-leap-day」です。
同名のScssファイルがテーマに含まれています。
「index.md」「about.md」「toc .md」のフロントマターのレイアウト設定をdefaultからhomeに変更します。
ここまでで、index.mdを表示するとコンテンツの最初に3つのリンクが横並びに表示されます。
コンテンツ・ナビゲーション
コレクション
Jekyllにはコレクションという機能があります。
コレクションはページ(またはそのページを生成するファイル)を整理し、管理できるようにします。
例えば「doc1.md」「doc2.md」・・・は「チュートリアル のドキュメント」という括りでまとめられます。
これらを「_chapters」ディレクト リの下に入れることにより、他のファイルと区別でき、ルートディレクト リもすっきりします。
そしてコレクションは_config.yml
の中で定義します。
コレクション名はディレクト リ名から先頭のアンダースコアを取ったものになります。
collections :
chapters :
output : true
コレクションは「collections」をキーとするハッシュで表す
この例では「chapters」がコレクション名で、更にその属性がハッシュで表される
デフォルトではコレクションは出力されないので「output: true」で出力されるようにする
この定義により、Liquidのタグなどでsite.documents
が「documentsコレクション」を表すようになります。
Base URL
_config.ymlにBase URLの設定をします。
Base URLの説明は「Jekyllを勉強中(9)」にあります。
baseurl : /jekyll-tutorial-for-beginners
ドキュメントのレイアウト
ドキュメントではコナビに「前の章」「次の章」を加えます。
また、コナビはコンテンツの最初と最後につけることにします。
2箇所に同じコナビをつけるので、コナビを独立したファイルにし、レイアウトの中でインクルードします。
インクルード
インクルード対象のファイルは「_include」ディレクト リに置きます。
コナビを表すファイルは下記のリストのようになり、_include/doc_nav.html
に保存されます。
<ul class="nav">
<li>
<a href={{ "/index.html" | relative_url }}>トップページ</a>
</li>
<li class="nav">
<a href={{ "/about.html" | relative_url }}>Aboutページ</a>
</li>
<li class="nav">
<a href={{ "/toc.html" | relative_url }}>目次</a>
</li>
{% if page.chap > 1 %}
<li class="nav">
<a href="doc{{page.chap|minus: 1}}.html">前の章</a>
</li>
{% endif %}
{% if page.chap < site.chapters.size %}
<li class="nav">
<a href="doc{{page.chap|plus: 1}}.html">次の章</a>
</li>
{% endif %}
</ul>
上から10行まではhome.html
のレイアウトに書いた内容と同じです。
{%raw%}{%
と%}
{%endraw%}で囲まれたものはLiquidのタグと呼ばれます。
ここにはプログラムのコントロール ・フロー(if, else, unlessなどの条件分岐)などを書くことができます。
{% if page.chap > 1 %}
< li class = "nav" >
< a href = "doc{{page.chap|minus: 1}}.html" > {{chap}}前の章 </ a >
</ li >
{% endif %}
ifの条件は「そのページの章(chap)が1より大きい」すなわち「第2章以降」で、このときは「前の章」が存在します。
条件が成立する時にifとendifで囲まれた部分が出力されますが、その出力内容は「前の章へのリンク」です。
例えば第3章の前は第2章で、ファイル名は「doc2.html」(変換後なので拡張子は.mdではない)になります。
数字の2にあたる部分はLiquidのオブジェクト({%raw%}{{
と}}
{%endraw%}で囲まれた部分)で表されています。
{{page.chap|minus: 1}}
縦棒|
は前にも出てきた「フィルター」というもので、左の出力を右の入力につなげます。
このときフィルターの動作はパイプの右側に記述します。
「minus」は引き算をします。
例えば第3章では「page.chap」は3なので、「minus: 1」はそこから1を引き、2になります。
Liquidには算術演算子 が無く、計算はフィルターを使って行います。
{% if page.chap < site.chapters.size %}
<li class="nav">
<a href="doc{{page.chap|plus: 1}}.html">次の章</a>
</li>
{% endif %}
ほとんど同じですが、site.chapters.size
のところが新たな内容です。
変数site
にコレクション名をつけ、更にsize
をつけています。
site.chapters
はchaptersコレクションに属するページの配列を返す
size
は文字列の文字数や配列の要素数 を返す。
本来パイプ(|
)とともに使われるフィルターだが、
タグ(<%raw%}{%
と%}
{%endraw%}で囲まれた部分)では、ドット(.
)記法が使える。
章の数が配列のサイズより小さい、すなわち「最後の章ではない」ときに「次の章」をコナビに入れます。
ドキュメントのレイアウト
ドキュメントのレイアウトはdocument.html
です。
---
layout: default
---
{% include doc_nav.html %}
< h1 > 第{{page.chap}}章 {{page.title | escape}}</ h1 >
{{ content }}
{% include doc_nav.html %}
前に作ったdoc_nav.html
を2ヶ所でインクルードしています。
インクルードのおかげで短くさっぱりした記述になっています。
コナビとコンテンツの間に「第何章」というタイトルをh1タグで入れました。
escapeフィルタは「Jekyllを勉強中(9)」で説明されています。
ドキュメント
ドキュメント(doc1.mdなど)のフロントマターにはchapなどを入れます。
例えば、第1章のドキュメントのフロントマターは次のようになります。
---
layout: document
title: Jekyll、GitHub Pagesとは
description: JekyllとHitHub Pagesの基礎知識
chap: 1
---
レイアウトはdocument.htmlを使う
タイトルとディスクリプションを指定=>default.html(document.htmlの親レイアウト)で使われる
chapは章の番号を表す=>document.htmlで使われる
目次
目次の生成にはforループを使います。
以下はtoc.md
のソースコード です。
---
layout: home
title: 目次
description: チュートリアルの目次
---
## 目次
{% assign chaps = site.chapters | sort: "chap" %}
{% for doc in chaps %}
- [{{doc.chap}}章 {{ doc.title | escape }} ]({{ doc.url | relative_url }} )
{% endfor %}
下3行が目次を生成する部分です。
site.chapters
はchaptersコレクションに含まれるページの配列。
この配列を章の番号順にソートするために、フィルターが使われている。
| sort: "chap"
はフロントマターのchapキーの値で配列をソートしたものを値とする。
(このソートされた配列は元の配列とは別オブジェクト)。
変数chapsにソート済み配列が代入される
for文は変数docに次々と配列要素を入れてループする
{{doc.chap}}
はそのページの章番号になる
{{doc.title}}
はそのページのタイトル
{{doc.url}}
はそのページのURLアドレスになる
このようにして、各章へのリンクがリストとして生成されます。
Leap dayの日本語対応
Leap dayのJavascript (jQuery )は、見出しが日本語のときに上手く動作しません。
修正は、次のようにします。
assets/js
ディレクト リを作る
Leap dayのgemの場所を調べる($ bundle info jekyll-theme-leap-day
でパスが表示される)
Leap dayのassets/js/main.js
を最初に作ったassets/js
の下にコピーする
下記のようにmain.jsを修正する
... ... ...
... ... ...
$(window ).resize(sectionHeight);
var tag_number = 1;
$(function () {
$("section h1, section h2, section h3" ).each(function (){
$("nav ul" ).append("<li class='tag-" + this .nodeName.toLowerCase() + "'><a href='#tag_" + String (tag_number) + "'>" + $(this ).text() + "</a></li>" );
$(this ).attr("id" ,"tag_" +String (tag_number));
++tag_number;
$("nav ul li:first-child a" ).parent ().addClass("active" );
} );
} );
... ... ...
... ... ...
変更箇所は4ヶ所です。
var tag_number = 1;
$(function()から2-3行目のString(tag_number)に置き換える部分(2ヶ所)
++tag_number
手作業では間違いやすいのでコピペするのが良いと思います。
ここまでで、Jekyllの使い方がかなり分かってきたのではないでしょうか。
次回はJekyllでブログを書く方法を扱おうと思います。