HTMLサイトをJekyllに変換する

2017年2月10日 tomjoht tomjoht

Jekyllサイトのテーマを探している場合、既存のJekyllテーマに限定する必要はありません。 ほとんどすべての静的HTMLファイルをJekyll Webサイトに変換するのは非常に簡単です。

多くの点で、現在静的サイトであるサイトは*既に* Jekyll Webサイトです。 Jekyllを使用すると、ファイルの処理中にサイトの一部(ページをテンプレートに挿入する、ナビゲーション用のリストをレンダリングする、フィードとサイトマップを生成するなど)を自動化できます。

HTMLサイトをJekyllテンプレートに変換する方法を理解することで、Jekyllテーマの選択肢が大幅に広がります。 オンラインで*Jekyllテーマ*を検索する代わりに、サイト用のさまざまなHTMLテンプレートから選択し、必要に応じてHTMLテンプレートをJekyll化し、Jekyllで出力をビルドできます。

Webサイトには高度な機能とコントロールを備えることができますが、このチュートリアルではシンプルに保ちます。

Jekyll Webサイトとは?

まず、基本から始めましょう。 Jekyllサイトを非常に基本的なレベルまで分解すると、Jekyllサイトで何が起こるかが明確になります。 まだjekyll gemをインストールしていない場合は、インストールしてください

3つのファイルで構成される*基本的なJekyllサイト*から始めます

.
├── _config.yml
├── _layouts
│   └── default.html
└── index.md

これらの3つのファイルを`my_jekyll_site`というフォルダー、または自分に合ったフォルダーに手動で作成し、`default.html`を`_layouts`という名前のフォルダー内に配置します。

touch _config.yml index.md default.html
mkdir _layouts && mv default.html _layouts

お気に入りのエディターを起動し、`default.html`および`index.md`ファイルの内容を次のように入力します

_config.yml

name: My Jekyll Website

_layouts/default.html

<!DOCTYPE html>
<html>
  <body>
     {{ content }}
  </body>
</html>

index.md

---
title: My page
layout: default
---

# {{ page.title }}

Content is written in [Markdown](https://learnxinyminutes.com/docs/markdown/).
Plain text format allows you to focus on your **content**.

<!--
You can use HTML elements in Markdown, such as the comment element, and they won't
be affected by a markdown parser. However, if you create an HTML element in your
markdown file, you cannot use markdown syntax within that element's contents.
-->

次に`my_jekyll_site`に`cd`し、組み込みサーバーでサイトを提供します

cd my_jekyll_site
jekyll serve

Gemfileがある場合は、`bundle exec jekyll serve`と入力してBundlerを使用してください

サイトを提供すると、`http://127.0.0.1:4000/`(`http://localhost:4000/`と同じ)などのプレビューURLが取得されます。 サイトのファイルは、デフォルトで`_site`フォルダーにビルドされます。

これは、最も基本的な機能レベルのJekyllサイトです。 何が起こっているか voici

  • `_config.yml`ファイルには、Jekyllがサイトの処理に使用する設定が含まれています。 空の設定ファイルは、Jekyllサイトを構築するためのデフォルト値を使用します。 たとえば、MarkdownをHTMLに変換するために、Jekyllはkramdown Markdownフィルターを自動的に使用します。指定する必要はありません。
  • Jekyllは、frontmatterタグ(`index.md`のような2組の破線`---`)を持つファイルを検索し、ファイルを処理します(サイト変数の入力、Liquidのレンダリング、MarkdownからHTMLへの変換)。
  • Jekyllは、すべてのページと投稿のコンテンツを、frontmatterタグで指定されたレイアウト(`default`)の`{{ content }}`変数にプッシュします。
  • 処理されたファイルは、`_site`ディレクトリに`.html`ファイルとして書き込まれます。

Jekyllがファイルを処理する方法の詳細については、解釈の順序をご覧ください。

Jekyllサイトの仕組みを基本的に理解していれば、JekyllのほぼすべてのHTMLテーマを変換できます。 次のセクションでは、そのためのステップバイステップのチュートリアルを紹介します。

1. デフォルトレイアウトのテンプレートを作成する

HTMLテーマを見つけて、`default`レイアウトとして保存します。 既存のサイトを変換または複製する場合は、ページを右クリックしてソースコードを表示できます。

たとえば、会社のサイトを複製して、同じブランドのドキュメントサイトを作成するとします。 または、HTMLで構築した個人用サイトがあり、それをJekyllサイトにしたいとします。 サイトのHTMLソースコードを取得します。

サイトに関係なく、ライセンスを確認し、コードをコピーして使用するための権限があることを確認してください。

ソースコードをコピーして`default.html`というファイルに貼り付けます。 `default.html`ファイルを`_layouts`フォルダーに入れます。 これは、ページと投稿のデフォルトのレイアウトテンプレートになります。つまり、各ページまたは投稿は、Jekyllがサイトをビルドするときにこのレイアウトを使用します。

テンプレートを探すときは、テンプレートのHTML出力がほしいことに注意してください。 テンプレートにPHPタグまたはその他の動的スクリプトがある場合、これらの動的要素はHTMLまたはLiquidに変換する必要があります。 Liquidは、動的コンテンツを取得するためのJekyllテンプレートシステムです。

`default.html`をローカルブラウザで開き、サイトがオンラインと同じように見え、動作することを確認します。 CSS、JS、および画像パスを調整して機能させる必要がある場合があります。

たとえば、コピーしたサイトでパスが相対パスであった場合、同じアセットをJekyllサイトにダウンロードするか、クラウド内の同じアセットへの絶対パスを使用する必要があります。 (`src="//`などの構文では、ローカルブラウザで機能するには、`src="http://`などのプレフィックスが必要です。)

Jekyllは、パスより前にサイトURLを追加するためのフィルターをいくつか提供しています。 たとえば、次のようにスタイルシートの前に付けることができます

{{ "/assets/style.css" | relative_url }}

`relative_url`フィルターは、構成ファイルのbaseurl値(たとえば`blog`)を入力に追加します。 これは、サイトがドメインのルートではなくサブパスでホストされている場合に役立ちます(たとえば、`http://mysite.com/blog/`)。

`absolute_url`フィルターを使用することもできます。 このフィルターは、`url`*と*`baseurl`値を入力に追加します

{{ "/assets/style.css" | absolute_url }}

繰り返しますが、`url`と`baseurl`の両方をサイトの構成ファイルで次のように定義できます

url: http://mysite.com
baseurl: /blog

出力の結果は`http://mysite.com/blog/assets/style.css`になります。

ページの`url`プロパティはスラッシュ(`/`)で始まるため、`url`または`baseurl`プロパティの最後にはこれを省略してください。

このようにリンクパスにフィルターを付加する必要はありません。 サイト全体で相対リンクを使用することもできます。 アセットへのパスのコーディング方法を決定したら、正しくレンダリングされていることを確認してください。

ローカルの`default.html`ページはブラウザで適切に表示されますか? すべての画像、スタイル、およびその他の要素が正しく表示されていますか? もしそうなら、素晴らしい。 続けてください。 このテンプレートをすべてのページと投稿のレイアウトとして使用するか、必要なだけテンプレートを作成できます。

次のセクションでは、レイアウトの内容をブランクにし、Jekyllページで動的に入力されるプレースホルダータグに置き換えます。

2. レイアウトのコンテンツ部分を特定する

`default.html`で、ページコンテンツの開始位置(通常は`h1`または`h2`タグ)を見つけます。 これらのタグ内にあるタイトルを`{{ page.title }}`に置き換えます。

コンテンツ部分(ナビゲーションメニュー、サイドバー、フッターなどはすべて保持)を削除し、`{{ content }}`に置き換えます。

ブラウザでレイアウトを再度確認し、重要な`div`タグまたはその他の要素を誤って削除することによって、レイアウトが破損または変更されていないことを確認します。 変更は、タイトルとページコンテンツのみで、現在はブランクになっているか、プレースホルダータグが表示されています。

3. frontmatterタグを持つファイルをいくつか作成する

ルートディレクトリに`index.md`と`about.md`の2つのファイルを作成します。

`index.md`ファイルに、`title`および`layout`プロパティを含むfrontmatterタグを追加します。次のようにします

---
title: Home
layout: default
---

Some page content here...

テスト用に、同様のfrontmatterタグを持つ`about.md`という別のページを作成します。

ページにレイアウトを指定しないと、Jekyllはそのページをスタイルのない基本的なHTMLページとしてレンダリングします。

4. 構成ファイルを追加する

ルートディレクトリに`_config.yml`ファイルを追加します。 `_config.yml`では、必要に応じて使用するMarkdownフィルターを指定できます。 デフォルトでは、kramdownGitHub Flavored Markdown(GFM)プロセッサが使用されます。 他のフィルターが指定されていない場合、構成ファイルは自動的にデフォルト設定として次のように適用されます

markdown: kramdown
kramdown:
  input: GFM

Jekyllドキュメントには、追加のMarkdownオプションがありますが、必要になる可能性は低いです。

5. ページをテストする

では、`jekyll serve` を実行し、`index.html` と `about.html` ページを切り替えてみましょう。デフォルトのレイアウトが両方のページに適用されるはずです。

これで、コンテンツを個別のファイルに抽出し、ページの共通レイアウトを定義しました。

ページには必要な数のレイアウトを定義できます。そして、特定のページで使用したいレイアウトを指定するだけです。例えば、

---
title: Sample page
layout: homepage
---

このページは、`_layouts` フォルダ内の `homepage.html` テンプレートを使用します。

`_config.yml` ファイルで、ページ、投稿、または[コレクション](/docs/collections/)の[デフォルトのfrontmatterタグ](/docs/configuration/front-matter-defaults/)を設定することで、frontmatter変数でレイアウトを指定する必要がなくなります。いずれにせよ、デフォルトの設定はこのチュートリアルの範囲外なので、作業に戻りましょう。

6. サイト変数の設定

`{{ page.title }}` タグを使用してページタイトルを設定しました。しかし、他にも設定すべき `title` タグがあります。ページには、ブラウザのタブまたはウィンドウに表示される [title](https://moz.com/learn/seo/title-tag) タグもあります。通常、ここにページタイトルとサイトタイトルを記述します。

`default.html` レイアウトで、`head` タグの下にある `title` タグを探します。

<title>ACME Website</title>

次のサイト変数を挿入します。

<title>{{ page.title }} | {{ site.title }}</title>

`_config.yml` を開き、サイト名の `title` プロパティを追加します。

title: ACME Website

`_config.yml` ファイルに追加したプロパティは、`site` 名前空間を介してアクセスできます。同様に、ページのfrontmatterにあるプロパティは、`page` 名前空間を介してアクセスできます。値にアクセスするには、`site` または `page` の後にドット表記を使用します。

Ctrl + C でJekyllサーバーを停止し、再起動します。`title` タグが正しく設定されていることを確認してください。

設定ファイルを変更するたびに、変更を反映させるためにJekyllを再起動する必要があります。他のファイルを変更すると、Jekyllは再構築時に変更を自動的に取得します。

サイトに設定する他の変数がある場合は、同じ手順を繰り返します。

7. ページに投稿を表示する

ホームページに投稿のリストを表示するのが一般的です。まず、表示するコンテンツを作成するために、いくつかの投稿を作成しましょう。

標準の `YYYY-MM-DD-title.md` 投稿形式に従って、`_posts` フォルダにいくつかの投稿を追加します。

  • 2017-01-02-my-first-post.md
  • 2017-01-15-my-second-post.md
  • 2017-02-08-my-third-post.md

各投稿に基本的なコンテンツを追加します。

---
title: My First Post
layout: default
---

Some sample content...

次に、投稿を表示するレイアウトを作成しましょう。`_layouts` に `home.html` という新しいファイルを作成し、次のロジックを追加します。

---
layout: default
---

{{ content }}
<ul class="myposts">
{% for post in site.posts %}
    <li><a href="{{ post.url }}">{{ post.title}}</a>
    <span class="postDate">{{ post.date | date: "%b %-d, %Y" }}</span>
    </li>
{% endfor %}
</ul>

ルートディレクトリに `blog.md` というファイルを作成し、`home` レイアウトを指定します。

---
title: Blog
layout: home
---

この場合、`blog.md` の内容は `home` レイアウトの `{{ content }}` タグにプッシュされます。そして、`home` レイアウトは `default` レイアウトの `{{ content }}` タグにプッシュされます。

レイアウトの仕組み

レイアウトが別のレイアウトを指定する場合、最初のレイアウトの内容は2番目のレイアウトの `{{ content }}` タグに挿入されます。例として、互いに嵌め込むロシアの入れ子人形を考えてみてください。各レイアウトは、指定された別のレイアウトに収まります。

次の図は、Jekyllでのレイアウトの仕組みを示しています。

Concept of Jekyll layouts

この例では、`layout: docs` を指定するMarkdownドキュメント `document.md` のコンテンツは、レイアウトファイル `docs.html` の `{{ content }}` タグにプッシュされます。 `docs` レイアウト自体が `layout: page` を指定しているため、`docs.html` のコンテンツはレイアウトファイル `page.html` の `{{ content }}` タグにプッシュされます。最後に、`page` レイアウトが `layout: default` を指定しているため、`page.html` のコンテンツはレイアウトファイル `default.html` の `{{ content }}` タグにプッシュされます。

複数のレイアウトは必要ありません。`default` だけを使用することもできます。サイトの設計方法には選択肢があります。一般的に、ページと投稿にそれぞれ1つのレイアウトを定義しますが、これらの両方のレイアウトは `default` テンプレート(通常はサイトの上部と下部を定義します)を継承します。

ブラウザで `blog.html` にアクセスして、投稿のリストを確認します。ここで説明した方法を使用する必要はありません。`index.md` などの任意のページに `for` ループを追加して、これらの投稿を表示することもできます。ただし、他の機能のロジックがより複雑になる可能性があることを考えると、頻繁にコンテンツを入力するページ領域とは別にテンプレートにロジックを格納すると便利です。

レイアウトには、レンダリングされる_コンテンツ_のレシーバーとして機能する `{{ content }}` が少なくとも含まれている必要があります。

forループ

ところで、ここで `for` ループのロジックをもう少し詳しく見てみましょう。[Liquidのforループ](https://shopify.dokyumento.jp/liquid/tags/iteration/)は、最もよく使用されるLiquidタグの1つです。_forループ_を使用すると、Jekyllサイトのコンテンツを反復処理して結果を構築できます。 `for` ループには、ループ内での位置に基づいて、[特定のプロパティ](https://help.shopify.com/themes/liquid/objects/for-loops)(最初の反復や最後の反復など)も使用できます。

投稿を取得するための `for` ループでできることのほんの一部を紹介しただけです。たとえば、特定のカテゴリの投稿を表示する場合、投稿のfrontmatterに `categories` プロパティを追加して、それらのカテゴリを検索することで表示できます。さらに、`limit` プロパティを追加することで、結果の数を制限できます。次に例を示します。

<ul class="myposts">
{% for post in site.categories.podcasts limit:3 %}
    <li><a href="{{ post.url }}">{{ post.title}}</a>
    <span class="postDate">{{ post.date | date: "%b %-d, %Y" }}</span>
    </li>
{% endfor %}
</ul>

このループは、frontmatterに `podcasts` というカテゴリを持つ最新の3つの投稿を取得します。

8. ナビゲーションの設定

投稿を設定したので、次にページナビゲーションを設定しましょう。ほとんどのWebサイトには、サイドバーまたはヘッダー領域にナビゲーションがあります。

このチュートリアルでは、生成するページの単純なリストがあると仮定します。ページがほんの一握りの場合は、`for` ループを使用して `site.pages` オブジェクトを反復処理し、frontmatterプロパティで順序付けることで、それらをリストできます。

コード内でページのリストが表示される部分を見つけます。通常、これはさまざまな子 `<li>` 要素を持つ `<ul>` 要素です。コードを次のように置き換えます。

<ul>
  {% assign mypages = site.pages | sort: "order" %}
    {% for page in mypages %}
    <li><a href="{{ page.url | absolute_url }}">{{ page.title }}</a></li>
    {% endfor %}
</ul>

この例では、各ページに次のような `title` と `order` プロパティを含むfrontmatterがあると想定しています。

---
title: My page
order: 2
---

ここで、`order` プロパティはページのソート方法を定義し、`1` がリストの最初に表示されます。

別のデータファイルで管理しているページのリストを反復処理することもできます。これは、ページ数が多かったり、ページについて保存したい他のプロパティがある場合に適しています。

この方法でページリンクを管理するには、Jekyllプロジェクトに `_data` というフォルダを作成します。このフォルダに、例えば `navigation.yml` というファイルを作成し、次の内容を記述します。

- title: Sample page 1
  url: /page-1-permalink/

- title: Sample page 2
  url: /page-2-permalink/

- title: Sample page 3
  url: /page-3-permalink/

YAMLを書いたことがない場合は、すぐに慣れるでしょう。[YAMLでできること](https://learnxinyminutes.com/docs/yaml/)をご覧ください。

このデータファイルの各アイテムに追加のプロパティを必要に応じて保存できます。リストアイテムを表示したい順序に配置します。

データファイルからページのリストを出力するには、次のようなコードを使用します。

<ul>
    {% for link in site.data.navigation %}
    <li><a href="{{ link.url }}">{{ link.title }}</a></li>
    {% endfor %}
</ul>

ドキュメントサイトを構築する場合など、ナビゲーションに関するより高度な要件がある場合は、[ナビゲーションに関する詳細なチュートリアル](/tutorials/navigation/)を参照してください。

9. インクルードでサイトを簡素化する

`default.html` ファイルが巨大で扱いにくい場合があるとします。HTMLコードの一部を_インクルード_ファイルに配置することで、レイアウトを分割できます。

ルートディレクトリに `_includes` というフォルダを追加します。そのフォルダに、`sidebar.html` というファイルを追加します。

`default.html` レイアウトからサイドバーコードを削除し、`sidebar.html` ファイルに挿入します。

サイドバーコードが以前に `default.html` に存在していた場所に、次のように「インクルード」を取り込みます。

{% include sidebar.html %}

ヘッダーやフッターなど、テーマの他の要素もこのように分割できます。その後、これらの共通要素を他のレイアウトファイルに適用できます。こうすることで、コードの重複を避けることができます。

10. RSSフィード

JekyllサイトにはRSSフィードが必要です。 基本的なRSSフィードの構文は次のとおりです。JekyllでRSSファイルを作成するには、ルートディレクトリにfeed.xmlという名前のファイルを作成し、以下のコードを追加します。

---
layout: null
---

<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">

    <channel>
        <title>{{ site.title }}</title>
        <link>{{ site.url }}</link>
        <atom:link href="{{ page.url | prepend: site.url }}" rel="self" type="application/rss+xml" />
        <description>{{ site.description }}</description>
        <lastBuildDate>{{ site.time | date_to_rfc822 }}</lastBuildDate>
        {% for post in site.posts %}
        <item>
            <title>{{ post.title }}</title>
            <link>
                {{ post.url | prepend: site.url }}
            </link>
            <description>
                {{ post.content | escape | truncate: '400' }}
            </description>
            <pubDate>{{ post.date | date_to_rfc822 }}</pubDate>
            <guid>
                {{ post.url | prepend: site.url }}
            </guid>
        </item>
        {% endfor %}
    </channel>
</rss>

_config.ymlファイルに、titleurldescriptionのプロパティが設定されていることを確認してください。

このコードは、forループを使用して、最新の20件の投稿を調べます。投稿のコンテンツはエスケープされ、Liquidフィルタを使用して最後の400文字に切り詰められます。

default.htmlレイアウトで、ヘッダー内のRSSまたはAtomフィードへの参照を探し、作成したファイルへの参照に置き換えます。例えば、

<link rel="alternate" type="application/rss+xml"  href="{{ site.url }}/feed.xml" title="{{ site.title }}">

jekyll-feedというgemを追加することで、投稿フィードを自動生成することもできます。このgemはGitHub Pagesでも動作します。

11. サイトマップを追加する

最後に、サイトマップを追加します。ルートディレクトリにsitemap.xmlファイルを作成し、以下のコードを追加します。

---
layout: null
search: exclude
---

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">

    {% for page in site.pages %}
    <url>
        <loc>{{page.url}}</loc>
        <lastmod>{{site.time | date: '%Y-%m-%d' }}</lastmod>
        <changefreq>daily</changefreq>
        <priority>0.5</priority>
    </url>
    {% endfor %}

    {% for post in site.posts %}
    <url>
        <loc>{{post.url}}</loc>
        <lastmod>{{site.time | date: '%Y-%m-%d' }}</lastmod>
        <changefreq>daily</changefreq>
        <priority>0.5</priority>
    </url>
    {% endfor %}

</urlset>

ここでも、forループを使用して、すべての投稿とページを反復処理し、サイトマップに追加しています。

jekyll-sitemapというgemを追加することで、サイトマップを自動生成することもできます。このgemはGitHub Pagesでも動作します。

12. 外部サービスを追加する

(問い合わせフォーム、検索、コメントなど)必要なその他のサービスについては、サードパーティサービスを探してください。 リソースページにいくつかの統合を掲載しましたが、今日のSaaSとAPIの世界では、そのリストは無限です。

JekyllページはHTML、CSS、JavaScriptで構成されているため、埋め込む必要があるほとんどすべてのコードが問題なく動作します。

これらのサービスのコードを統合する際には、Jekyllサイトのページにフロントマタータグがない場合、Jekyllはそのページのコンテンツを処理しません。ページは、サイトをビルドするときに_siteフォルダに渡されるだけです。

Jekyllにページコンテンツを処理させたい場合(たとえば、サイトの設定ファイルで定義した変数を入力する場合)は、ページにフロントマタータグを追加するだけです。ページにレイアウトを適用したくない場合は、次のようにlayout: nullを指定します。

---
layout: null
---

13. まとめ

Webサイトはより高度な機能を実装できますが、このチュートリアルでは基本について説明しました。これで、完全に機能するJekyllサイトが完成しました。

サイトをデプロイするには、GitHub PagesNetlifyVercelRenderAmazon AWS S3s3_websiteプラグインを使用)、またはファイルをWebサーバーにFTP転送することを検討してください。

レイアウト、インクルード、アセットをRubyのgemにパッケージ化して、Jekyllテーマにすることもできます。

追加リソース

Jekyllサイトの作成に関する追加のチュートリアルを以下に示します。