microCMS

JekyllとmicroCMSでシンプルなJamstackニュースをつくる

チュートリアル
2020/02/26 松田 承一

本日はRubyの静的サイトジェネレータであるJekyll(ジキル)とヘッドレスCMSであるmicroCMSとを組み合わせてJamstack構成のニュースサイトを作成していきます。

静的サイトジェネレータといえばNuxt.jsNext.jsGatsbyJSGridsomeなどJavaScriptを利用するものが多いですが、実際にはRubyやGo、Pythonなど様々な言語の静的サイトジェネレータが存在しています。
StaticGenでは言語でフィルタリングして静的サイトジェネレータを探せるのでお気に入りの言語のものを試してみると良いでしょう。

なお本日利用するmicroCMSはREST APIベースのヘッドレスCMSであるため、Jekyllだけでなくどんな言語のサイトジェネレータからでも利用可能です。ぜひお試しください!

ニュースサイトの開発

まずはJekyll側の設定を行なっていきます。

環境構築

Jekyllのセットアップはとても簡単です。
JekyllのQuickstartなどにも記載があるように以下のコマンドを実行してください。

$ gem install jekyll bundler

プロジェクトの作成

次にプロジェクトを作成しましょう。

$ jekyll new jekyll-microcms-blog #プロジェクト作成
$ cd jekyll-microcms-blog #ディレクトリ移動

動作確認

あとは開発用のサーバを起動して内容を確認してみましょう。

$ bundle exec jekyll serve
$ open http://localhost:4000 # or 直接ブラウザを開く

ここまでで特に問題なければ以下のようなサイトを開くことができるでしょう。

これだけでJekyllを使ったサイトを起動させることができました。
開発中は上記のようにserveコマンドを使用すれば良いですが、Jekyllは静的サイトジェネレータですのでサイトそのものをワンコマンドでビルドすることもできます。

$ bundle exec jekyll build

このコマンドを実行すると_siteディレクトリ以下にビルド後のファイルが生成されます。treeコマンドで確認すると以下のような状態でしょう。

$ tree _site
_site
├── 404.html
├── about
│   └── index.html
├── assets
│   ├── main.css
│   ├── main.css.map
│   └── minima-social-icons.svg
├── feed.xml
├── index.html
└── jekyll
    └── update
        └── 2020
            └── 02
                └── 27
                    └── welcome-to-jekyll.html
7 directories, 8 files

実際のサイト公開時にはこれらのファイルをそのまま展開すれば良いですね!

トップページを作成する

それではmicroCMSでニュースを書いていけるように内容を修正していきましょう。
まずは今回の作業にあたって不要なファイルは削除します。

$ rm -rf _posts about.markdown index.markdown

また、デフォルト状態ではJekyllはminimaというテーマを使用しています。
今回は簡単のためテーマは一切使わずに全て自作して試していきますのでテーマ設定をコメントアウトします。
具体的には_config.ymlの33行目付近にある以下の行をコメントアウトしましょう。

theme: minima

コメントアウトは先頭に # を付けます。

# theme: minima

次に独自のレイアウトを作成します。今回は3つのレイアウトを作成していきます。
まずは全体のおおまかな構成がされた default.html です。

$ mkdir _layouts
$ touch _layouts/default.html

お使いのエディタで中身を以下のように記載してください。

<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <title>{{ page.title }}</title>
  </head>
  <body>
    {{ content }}
  </body>
</html>

これができたらトップページを作成していきます。
まずはmicroCMSを使わずに単純な表示をしてみましょう。

$ touch index.html

中身は以下のように記載します。

---
layout: default
title: Hello
---

<h1>トップページです</h1>

この状態で再度サーバを起動( $ bundle exec jekyll serve )し、http://localhost:4000/ を起動すると以下のようになります。

トップページにmicroCMSを組み込む

それでは先ほど作成したトップページにmicroCMSを組み込み、ニュース一覧を表示していきましょう。
まずはmicroCMS側の準備が必要です。

今回は以下のようなニュースAPIを作成します。
※microCMSの使い方はmicroCMSのはじめ方などをご覧ください。

  • サービス名:test
  • X-API-KEY:f573f510-1cdf-40e2-90fa-37f37b9b2639
  • APIエンドポイント:sample_news
  • フィールドは下記画像


上記APIは以下のようなcurlコマンドで内容を確認できます。

$ curl "https://test.microcms.io/api/v1/sample_news" -H "X-API-KEY: f573f510-1cdf-40e2-90fa-37f37b9b2639"

それではmicroCMSをJekyllに組み込んでいきましょう。今回はシンプルな方法であるプラグインを使った方法で実装していきます。

$ mkdir _plugins
$ touch _plugins/microcms.rb

以下のような内容になるようにお使いのエディタで記載をします。

require 'open-uri'

module MicroCMS
  class Generator < Jekyll::Generator
    def generate(site)
      # ニュースを取得
      result = JSON.load(open("https://test.microcms.io/api/v1/sample_news",
        "X-API-KEY" => "f573f510-1cdf-40e2-90fa-37f37b9b2639"
      ).read)

      # レイアウト側で使えるようにsite.dataに値を入れておく
      site.data.merge!({ "news" => result['contents'] })
    end
  end
end

なお、今回はシンプルであることを優先してプラグインであるmicrocms.rbにエンドポイント、X-API-KEY、データの格納先などをハードコードしてしまいましたが、実際には_config.ymlで設定できるようにしておいた方が良いケースもあるでしょう。
この辺りはプロジェクトに応じて柔軟に変更をしてください。

ここまででmicroCMSからのデータ取得ができていますのであとはトップページに表示してみましょう。
index.htmlの中身を以下のように変更します。ulタグ以降が追加した部分ですね。

---
layout: default
title: Hello
---
<h1>トップページです</h1>

<ul>
  {% for item in site.data.news %}
  <li>
    <a href="/news/{{ item.id }}">
      <img src="{{ item.image.url }}?h=100" />
      {{item.title}}
    </a>
  </li>
  {% endfor %}
</ul>

先ほどプラグインでデータ追加した site.data.news を読み取り、for文を使って表示しています。
なお、?h=100はmicroCMSに用意されている画像編集機能を使ったもので画像の縦サイズを固定して表示しています。
microCMSの画像編集機能

うまく動いていれば http://localhost:4000/ の内容が以下のように変わります。こちらで表示されている画像やテキストはmicroCMSで入稿したものです。

CSSなどは何も当てていないため非常に簡素なページですが、トップページにニュース記事一覧を表示することができました!

ニュース記事詳細を表示する

それでは最後にニュース記事の詳細を表示していきましょう。
まずは詳細画面用のレイアウトを作成していきます。

$ touch _layouts/news_index.html

中身は以下の通りです。シンプルにニュース内容を表示するだけのテンプレートですね。

---
layout: default
title: News
---

<h1>{{ page.news.title }}</h1>
<img src="{{ page.news.image.url }}?h=300" />
{{ page.news.content }}

続いてプラグインである _plugins/microcms.rb の修正も行います。

require 'open-uri'

module MicroCMS
  class Generator < Jekyll::Generator
    def generate(site)
      # ニュースを取得
      result = JSON.load(open("https://test.microcms.io/api/v1/sample_news",
        "X-API-KEY" => "f573f510-1cdf-40e2-90fa-37f37b9b2639"
      ).read)

      # レイアウト側で使えるようにsite.dataに値を入れておく
      site.data.merge!({ "news" => result['contents'] })

      # ニュース詳細画面を作成
      result['contents'].each do |news|
        site.pages << NewsPage.new(site, site.source, File.join('news', news['id']), news)
      end
    end
  end

  class NewsPage < Jekyll::Page
    def initialize(site, base, dir, news)
        @site = site
        @base = base
        @dir  = dir
        @name = 'index.html'
  
        self.process(@name)
        self.read_yaml(File.join(base, '_layouts'), 'news_index.html')
        self.data['news'] = news
      end
  end
end

追記したのは # ニュース詳細画面を作成 としてある部分と、NewsPageクラスの2箇所です。
ここで新たなニュースページを生成する処理が書かれています。

ここまでの記述をすれば以下のようなニュース詳細記事を表示できます。

最後にビルド後のファイルが入った _site ディレクトリの中の構成も確認しておきましょう。
以下のようになっていればOKです。

$ tree _site
_site
├── 404.html
├── feed.xml
├── index.html
└── news
    ├── 2f9PU-1f3
    │   └── index.html
    └── ULFTqLH-x
        └── index.html
3 directories, 5 files


以上ですごくシンプルなニュースサイトを作ることができました!
ソースコードはGitHubにも上げてありますので、ぜひ見てみてください。

おわりに

Rubyの静的サイトジェネレータであるJekyllとmicroCMSを組み合わせたニュースサイトを作りました。
microCMSの利点であるどんな言語やフレームワークからでも使えるを活用した事例だったのではないかと思います。
みなさまの参考になりましたら幸いです!

-----

microCMSは日々改善を進めています。
ご意見・ご要望は管理画面右下のチャット、公式Twitterメールからお気軽にご連絡ください!
引き続きmicroCMSをよろしくお願いいたします!

ABOUT ME

松田 承一
ウォンタ株式会社の代表 / 家族=👨‍👩‍👧 / ヤフー→大学教員など→現職 / 管理画面付きAPIがすぐに作れるmicroCMSというサービス作ってます。