弊社で扱う案件は静的なページやシステムのフロント部分のみ(バックエンドは外部)ということが多いのですが、ちょくちょく「NEWSを管理画面から編集できるようにしたい」だったり「バナーを簡単に変更できるようにしたい」といった要望をいただくことがあります。
このような要望を頂いた場合、ほとんど「じゃあWordPressですね!」となっていました。たしかにWordPressは導入しやすく、様々なプラグインも使えるため便利でシェアでもトップなのは確かです。しかし人気があるゆえに悪意を向けられることが多いことも確かです。ある程度の規模があり、プラグインを駆使して様々なコンテンツを管理する必要があるならWordPressが良い候補になるとは思いますが、NEWSやバナーの編集がしたいというだけでWordPressを導入するのはかなりオーバースペックだと思います。
そこで今回はWordPressに変わるCMSとしてヘッドレスCMSのmicroCMSを使ってみたので、その触りはじめの部分をまとめようと思います。
データの取得方法
本記事ではWordPressとmicroCMS(ヘッドレスCMS)との違いについて深く触れません。ただ今回は少し工夫を入れてSSGでページを構築しようと思うので、他の構成と併せてそこだけ軽く触れたいと思います。
まずは一番見慣れているであろうWordPressです。特別書くこともないのですがDBサーバから記事データを読みWebサーバでHTMLを生成して返す方針です。Webサーバ側でページの内容が構築されるSSR(サーバーサイドレンダリング)ですね。
microCMSを使った場合は、まずWebサーバはCMS管理されている部分が空のHTMLを返します。次にHTMLに書かれた処理を元にブラウザはmicroCMSのAPIにコンテンツ内容をリクエストします。その後必要に応じて画像などもリクエストしてページが完成します。こちらはクライアント側で初回のレンダリングが行われるためCSR(クライアントサイドレンダリング)となります。
一方今回実装した方針は、microCMSのwebhook機能を用いてコンテンツが更新された際に用意しておいたWebサーバAPIが叩かれ、Webサーバー側からmicroCMSにリクエスト、事前にHTMLファイルを生成するという構成になっています。ユーザのアクセス時には事前に用意していたHTMLを返すだけになります。事前にHTMLを生成しておく、こちらがSSG(スタティックサイトジェネレート)ですね。
本来であれば生成したファイルはCDNに設置したり、流行りのフレームワークなどを使いたかったのですが、今回は諸事情によりピュアなPHPと普通のレンタルサーバーでスクラッチしていきます。
実装
それでは作っていきたいと思います。今回は実装する上で要所となる箇所、「webhook」と「コンテンツ取得」、「ページ生成」周りをピックアップして書いていこうと思います。
Webhook
まずはWebhookです。これを設定することでコンテンツの編集が行われたことを通知してもらいHTMLの書き出しにつなげていきます。ちなみに、Webhookを使うことで各種チャットサービスやメール、CloudflareやGitHub Actionsなどのサービスにつなげることもできるのでご自身の環境に合わせて設定することができます。
Webhookの設定は「コンテンツ(API)」の各コンテンツの「API設定」から「Webhook」と遷移することで設定画面に行くことができます。表示された画面にある「追加」ボタンを押すことで設定を追加することができます。今回は独自のAPIを叩いてもらうため「カスタム通知」を選択します。
すると下記画像のような画面になるので、名前や叩き先のURLを入力します。
この時シークレットという文字列も入力できるのですが、こちらはWebhookが第三者から叩かれていないかを確認する際に使用するため、基本的に設定しておくと良いと思います。文字列自体は特に指定はないようですが、今回は意味のないランダムな文字列を設定しておきました。
これでmicroCMS側の設定は完了です。次に実際に叩かれる側を実装します。コンテンツの取得やページ生成は次以降の項で触れるため、ここではシークレットが一致するかの確認するコードを掲載します。
$rawBody = file_get_contents('php://input'); $expectedSignature = hash_hmac('sha256', $rawBody, MICROCMS_SECRET); $signature = $_SERVER['HTTP_X_MICROCMS_SIGNATURE']; if(!hash_equals($signature, $expectedSignature)) { exit; } // コンテンツ取得の処理に続く
上記がリクエストヘッダで渡されるシークレットを確認する処理で、基本的にWebhook処理の先頭に書くことになるかと思います。コード内の`MICROCMS_SECRET`の部分はご自身のシークレット文字列を別途定数で定義しておくなど対応してください。
コンテンツ取得
次に叩かれるPHPの処理を書いていきます。と、その前にSDKのインストールを行います。これを使うことで簡単にmicroCMSとの連携を実装することができます。インストールにはcomposerを使用しました。
$ composer init $ composer require microcmsio/microcms-php-sdk
次はコンテンツを取得するコードです。先程インストールしたSDKを呼び出して、ご自身のドメインとAPIキーを記述して使用します。下記のコードでコンテンツを取得することができます。
require_once('vendor/autoload.php'); $client = new \Microcms\Client( "YOUR_DOMAIN", // YOUR_DOMAIN is the XXXX part of XXXX.microcms.io "YOUR_API_KEY" // API Key ); $contents_list = $client->list("hoge")->contents;
上記コードの`hoge`と書いている部分で取得するコンテンツを指定することができます。これはコンテンツAPIを作成した際に設定した文字列となります。また、コード内の`YOUR_DOMAIN`と`YOUR_API_KEY`はそれぞれ、管理画面URLの`.microcms.io`の前と「権限管理」内の「◯個のAPIのキー」から確認することができます。
ページ生成
次にページ生成です。今回はHTMLテンプレートを用意してその中のキーワードをmicroCMSで登録したものと置換することでページを生成してみます。
実際に作ってみたものが以下になります。
<div> <div> <img src="<!--TEMPLATE IMGSRC -->" width="<!--TEMPLATE IMGWIDTH -->" height="<!--TEMPLATE IMGHEIGHT -->"> </div> <div> <h3> <!--TEMPLATE CARDTITLE --> </h3> <p> <!--TEMPLATE CARDDESCRIPTION --> </p> </div> </div>
ご覧の通り動的に変わる部分は`<!–TEMPLATE 〇〇〇〇〇 –>`という記述にしています。`〇〇〇〇〇`というキーワードに合わせてmicroCMSでの入力値と置換することでHTMLを生成することができます。置換は以下のように作成しました。
function replace_template_keyword($html='', $keywords_list=[]) { foreach ($keywords_list as $keyword => $value) { $html = str_replace("<!--TEMPLATE {$keyword} -->", $value, $html); } return $html; } $TEMPLATE_CARD = file_get_contents('../path/to/card.html'); $keywords_list = [ 'IMGSRC' => $content->sampleimage->url, 'IMGHEIGHT' => $content->sampleimage->height, 'IMGWIDTH' => $content->sampleimage->width, 'CARDTITLE' => $content->title, 'CARDDESCRIPTION' => $content->content, ]; $html_card = replace_template_keyword($TEMPLATE_CARD, $keywords_list);
こちらで$contentに格納したmicroCMSの入力値に置換しています。単純に置換しているだけなので特別書くこともないのですが、テンプレートで用意した`card.html`を読み込み、置換用のキーワード配列を用意してまとめて置換するという処理を行っています。今回は置換の際に何もしていませんが必要に応じてサニタイズなども行ってください。
余談ですがコンテンツが画像の場合はAPIから画像の縦横サイズも取得しているためそちらも記述してあげるとレイアウトシフトを避けられて良いかと思います。
結果
項目に出しては見たものの、今回はサーバ側の処理が主となっていて載せるものがないですね…。蛇足感が否めないですがWebhookが叩かれた結果ファイルが増えた様子でも載せておきます。
今回は触れませんでしたが、テンプレートを用意してWebhookで処理することでコンテンツごとの詳細ページを作成することができます。使い方は色々ですね。
おわりに
今回はmicroCMSを使ってPHPでSSGという方針で書いてきました。CMSという点でWordPressと比べてしまうと機能は少ないので適用できる範囲できない範囲があると思いますが、適用できる範囲ではドキュメントも充実しているので導入しやすく、セキュリティやメンテナンス面でも扱いやすいのでありがたい存在です。
ドキュメントが充実しているので…この記事の存在意義は…。