概要
HugoとGraphCMSを組み合わせてコンテンツを生成していく。
そしてGithub Actionsで自動ビルドし、生成した静的ファイルをGithub Pages公開するのが最終目的である。
Hugo
スタティックサイトジェネレータのHugoを最近よく利用している。
Hugoの魅力は豊富なテーマや高速ビルドが挙げられる。
一方、特性上GatsbyやNuxt.js等ではよく利用されているヘッドレスCMSとの直接連携はできない。
GraphCMS
ヘッドレスCMSのGraphCMSはContentfulやCosmicJS等と比較して以下の優れた点がある。
- 無料区分枠で利用できるAPIコール数が多い。
- リッチコンテンツをhtmlでWYSIWYGエディタで書くことができる
- そしてなんといってもGraphQLが使える
- またレスポンスのjsonがシンプルな構造をしているので扱いやすい
逆にイケていないところは
- イケていると思ったWYSIWYGエディタがとても使いづらい(笑)
- RestfulAPIに慣れていてGraphQLってなんじゃらほいと思うと使いづらい(笑)
- Webhookのpayloadが自由にカスタマイズできないためGithubのAPIが利用できない。
などがある。上記Webhookの制限によりGraphCMS単体ではGithub Pagesで公開することはできない。
これらのデメリットが問題にならない場合は超絶オススメである。
利用条件については変更される場合があるので随時確認していただきたい。
GraphCMSによるコンテンツ作成
まずサインアップだがGithubやGoogleアカウントがあればすぐに可能である。
完了すればGraphCMSにログインする。
そして画面下部のほうにあるCreate a new project
に移動。
いくつかテンプレートがあるが今回はBlank
を用いてスクラッチで作成する。
Name
はプロジェクト名、Description
は説明、リージョンは特に理由がない限りAsia(Tokyo)
を選ぶ。
入力したらCreate project
をクリック。
次にプランの選択画面。フリープランで使う場合はFree forever
を選びSelect plan
を実行。
Invite your team members
というメンバを招待する画面になるので特に不要であればInvite later
をクリック。
そうするとプロジェクトの管理画面が表示される。そして左側のメニューを選んで操作をする。
スキーマ定義
まずはコンテンツのスキーマを定義してブログのコンテンツを設計する。
メニューのSchema
を選ぶ。
左側にModels
、Assets
、Enumerations
が表示されているが基本はModels
でモデル作成を行う。
Models
横のAdd
をクリックするとCreate Model
というフォーム画面が表示されるのでDisplay name
を適当に入力。
ここではpost
とした。
するとAPI ID
とPlural API ID
が自動的に入力される(ここではPost
とPosts
)。
この2つはGraphQLの呼び出し時に使い分ける。
-
Post (API ID)
: 単一のコンテンツを呼び出す場合、つまりID指定でコンテンツの詳細を取得する場合 -
Posts (Plural API ID)
: 複数のコンテンツを呼び出す場合、つまり一覧表示など複数のコンテンツを取得する場合
最初はこれを知らずにリストを取得する場合もPost
を使ってしまいドハマりした。
すべて入力したらCreate Model
をクリック。
Add Fields
というメニューが表示されるのでモデルのフィールドを追加していき設計する。
種類は以下の通り(縦長に表示されるので切り貼りした)
早速フィールド追加に取り掛かる。
まずはタイトル。Single line text
をクリックするとダイアログが表示されるので以下のように入力する。
VALIDATIONS
タブをクリックして属性を追加する。ここではMake field required
にチェックをした。
その他のフィールドも追加し、以下のような構成になった。
-
title
: ブログのタイトル -
slug
: スラグ。マルチバイト圏では使いづらいがURLがクリーンになるから採用 -
date
: 投稿日-
DateTime
型でやってもよいがそこまでそこまで細かい情報が不要だし、入力も面倒なので日付のみとした
-
-
eyecatch
: 投稿の看板画像- 今回の案件では投稿の一覧を画像で表示するため、必須項目としている
-
body
: ブログ本文-
RitchText
を使うとhtml形式でで書けるが、使いやすいMarkdown
採用
-
-
tag
: タグ
今回の案件では不要なので作っていないが、よくあるブログの構成としてはカテゴリーがある。
その場合、別途モデル定義してReference
で参照(いわゆるリレーショナル)するのが一般的かもしれない。
しかし、単純に文字列情報のみであるならば左メニューのModels
で定義するよりはEnumerations
で作成してDropdown
フィールドを使うほうが、クエリーがシンプルになる。
今回はタグもモデル定義せずに複数行入力できるSingle line text
で実装している。
Hugo側が勝手にタグの処理してくれるのでこれで十分である。
ちなみにこれらをモデルで定義したほうがよいのは、文字情報以外に属性を追加したい場合、例えばi18n(国際化)などがある。
また下書きはGraphCMS側で行っているのでフラグ管理はしていない。
コンテンツの作成・更新・公開などのタイムスタンプ情報はシステムフィールドで持っているので投稿日として使っても良い。
投稿者も私しかいないのでフィールド定義はしないが、これもシステムフィールドで持っているので表示できる。
これらの情報はShow system fields
トグルをオンにすると見ることができる。
コンテンツ作成
ここまでできたのでコンテンツの作成に取り掛かる。
ダッシュボード左メニューのContent
をクリック。
Create Item
をクリック。
そして適当に入力したのが下の様子(画像はLorem Picsumより)。
ここで注意してほしいのは画像ファイル。eyecatch
の箇所で表示されているようにアップロード時はDraft
状態になる。
そのためコンテンツをPublished
状態にするだけでなく画像も同様にPublished
にする。
一旦、コンテンツを保存する。Save
は下書き保存。Save and publish
が公開。
取り敢えずSave
で保存して左メニューのAssets
をクリック。
チェックを入れてPublish
ボタンをクリック。
Published
状態になれば先程のコンテンツに戻りPublish
をクリックして公開する。
GraphQLで作成したコンテンツの取得
先程投稿したコンテンツをGraphQLで取得してみる。
まず左メニューAPI Playground
をクリック。
ここで最初は途方にくれるが、まずExplorer
タブをクリックし、先述したPlural API ID
の名称、ここではposts
を選択する(post
ではない)。
そして適当にフィールドをクリックしてこんな感じのクエリーを作成する。
query MyQuery {
posts {
id
title
slug
date
eyecatch {
url
}
body
tag
}
}
そして真ん中のプレイボタンをクリックして実行。
右側に結果がjson形式で返ってくるのがわかる。
これを素にHugoのコンテンツを作成するのだが次回はHugoの設定を解説する。