microCMSを使い超爆速でCMS機能を実装しよう【PHP/JS】

久しぶりです。最近JAMStackとかが流行ってる流れで**ヘッドレスCMS**が使われつつありますよね。
なので実際に使って爆速でCMS機能を実装してみたので察ンプルコードとかを紹介したいと思います。
初心者はもちろん非エンジニアでもわかるレベルで解説・紹介します。

**デモ：https://0115765.com/samples/php/MicroCMS_List.php**
サンプルコード

https://github.com/ichii731/php-examples/tree/main/microCMS-Demo

【更新】Micro CMSがPHP用のSDKパッケージが有るので本番環境ではそれらを使ったが堅実です。

https://document.microcms.io/tutorial/php/php-top

# microCMSとは
microCMSは**純国産のヘッドレスCMS**です。

https://microcms.io

ヘッドレスCMSとは表示する部分を排除したCMS(コンテンツ管理システム)のことです。
通常WordPressなどの一般的なCMSはフロントエンドとバックエンドのセットで構築されます。WordPressはテーマなどを使って見える部分を整備しますよね。
一方ヘッドレスCMSは表示する部分(＝フロントエンド)を提供せず自分で見える部分を作るので**自由度が格段に増します**。(公式サイトより)
![公式サイトより](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513165/d2696e34-c56a-c446-c8fa-4fddf5c81659.png)

そしてmicroCMSを使う場合は**コンテンツをmicroCMS側に保管するため保守管理が楽**です。

## ヘッドレスCMSの利点・欠点
**利点**としては以下のことが挙げれられます。

- **必要な部分だけ**導入できる
- データベース構築不要→保守不要
- **自由な言語・フレームワーク**を使うことができる
- バックエンドを構築する必要が無いため**フロントエンド部分の作成に専念できる**

つまり**「WordPressの導入するまでもないけどCMS機能ほしいなぁー！」レベル**の一部分に導入したい時、大活躍ですね。

また**欠点**はこんな感じです。

- 一から見える部分を作るのでコンテンツ表示部を作成・改変するには**それなりの言語的な知識を要する**

もちろんフロントエンド部分は自分で書かないといけないのでHTML/JSとかの言語やVueなりReactなりのフレームワークの知識も必要になってきます。逆に言えばエンジニアならもってこいのやつなんですね～


## microCMSの無料プラン
無料プランと有料プランが用意されており無料プランはこんな感じです。

- データ転送量：**100GB**
- API数：**10個**
- メディア最大容量：**40MB**
- コンテンツ数上限：**10000件**

→個人のポートフォリオやや中小企業のコーポレートサイト・オウンドメディアには十分ですね。その他の比較は公式サイトを見てください。

https://microcms.io/pricing

# 実際に作ってみる
それでは実際に作ってみましょう。

## コンテンツ(記事)を作成する
### アカウント作成
以下リンクからサインアップ出来ます。無料プランならクレカ登録もないので勝手に請求…なことにはならないのでご安心を。

https://app.microcms.io/signup

ログインしたら**新規サービスを作成**します。サービス名とサービスIDを任意の名前で設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513165/f983d78c-270c-a9d6-bd12-f69aa7fbef90.png)
プラン選択で無料のヤツにします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513165/3bc40924-1cb5-7694-d75c-3e4e0c363fcd.png)
次に**API基本情報を入力**します。今回はNewsというAPI名にしました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513165/0738d7cb-cb5d-77a1-55f1-913d03550a5d.png)
ブログ的な感じにしたいため**リスト形式**を選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513165/d9b4669a-4412-c40a-cbfe-be4dfa503c80.png)
最後に**APIスキーマを作成します**。今回はタイトルと本文を追加しました。
**更新日・投稿日などは元から入ってます**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513165/40019b66-2da5-3633-db4e-893cfc193180.png)

### 記事を書く
それではコンテンツを作成していきましょう。右上の作成から作れます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513165/79b6c744-47b4-f07a-2007-cd32c1962f6f.png)
ここは**WordPressのクラシックエディターと全く同じ操作**で記事を書けます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513165/70e5e317-900e-ae70-23cd-6b6e04c106ea.png)

斜め字・太字・下線・取り消し線はもちろん文字色・背景色・コード・**画像・YouTube埋め込みもできます！**
![rapture_20210910171555.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513165/7462cb42-5633-f9f0-ea94-f4d5d8f0d1ff.png)
![rapture_20210910171308.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513165/be5b7a97-e1bb-76ae-b1cf-cba44915eaab.png)
作成が完了したら公開をクリックして保存しましょう。**That's All！それでは見える部分を作っていきましょう！**

## 表示部分を作る

本来は**JAMStack**や**SSG(Static Site Generatin)を活用した環境**などで使われることが多い(むしろそっちメイン)ですが**今回は純粋なPHPのみ・JavaScriptのみで実装してみました**ので参考にしてみてください。
APIをfetchなりcUrlなりで取得して加工するだけなので超簡単です！

まぁNuxtJSで作ってNetlifyでホスティングする…みたいな記事しか無いしドキュメントもそれしか無いのであんまやる人がいないんでしょう…

※JAMStackとは…Netlifyが開発した、クライアントサイドJavaScript・再利用可能なAPI・マークアップ(markup)の3つをベースとしたクラウドネイティブなウェブ開発アーキテクチャである。(Wikiより)

## 【PHP】実装例
PHPで**計100行以内で実装してみた**のでコード例を紹介します。
Bladeを使いたかったからLaravelでやろうと思ったところですがバニラのPHPを使いました。
**[2021-10-10IDに該当する記事がない場合に表示する処理を追加]**
### 記事表示部分
**デモ：https://0115765.com/samples/php/MicroCMS_Content.php?id=w65rp7nbzn**

各記事のAPIエンドポイントは`https://[サービス名].microcms.io/api/v1/[API名]/[記事ID]`です。
クエリパラメータを使ってIDを認識してそれを元にcURLでAPIを叩いてHTMLとして加工します。
サンプルコード

https://github.com/ichii731/php-examples/tree/main/microCMS-Demo

```php:MicroCMS_Content.php
<?php
$id = $_GET['id'];

// クエリパラメータを取得
if (isset($id) == true) {
    GetContent($id);
} else {
    echo 'Set query parameters';
}

function GetContent($id)
{
    // cUrlでAPIを叩く
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, 'https://***************.microcms.io/api/v1/news/' . $id);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

    $headers[] = 'X-Api-Key: ***************************************';
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    $response = curl_exec($ch);
    curl_close($ch);

    // 取得したら表示
    $result = json_decode($response, true);
    if (isset($result) == true) {
        ShowHtml(
            $result['title'],
            $result['createdAt'],
            $result['updatedAt'],
            $result['body']
        );
    }else{
        echo "IDに該当する記事がありません";
    }
}
}

// コンテンツ表示部
function ShowHtml($title, $createAt, $updatedAt, $body)
{
    echo '<meta name="viewport" content="width=device-width, initial-scale=1.0">';
    echo '<h2>タイトル:' . $title . '</h2>';
    echo '<p>作成日:' . $createAt . '</p>';
    echo '<p>更新日:' . $updatedAt . '</p><br>';
    echo '<article style="background-color: aliceblue;">本文:<br>' . $body . '</article>';
}
```

### 記事一覧
**デモ：https://0115765.com/samples/php/MicroCMS_List.php**

記事一覧のAPIエンドポイントは`https://[サービス名].microcms.io/api/v1/[API名]`です。そこにAPIキーをGETで渡すだけです。

```php:MicroCMS_List.php
<?php
// cUrlでAPIを叩く
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://***************.microcms.io/api/v1/news');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

$headers[] = 'X-Api-Key: **************************************';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$response = curl_exec($ch);
curl_close($ch);

// 取得したら表示
$result = json_decode($response, true);
foreach ($result['contents'] as $contents) {
    $url = 'https://0115765.com/samples/php/MicroCMS_Content.php?id=' . $contents['id'];
    ShowHtml(
        $contents['title'],
        $contents['createdAt'],
        $url
    );
}

function ShowHtml($title, $createAt, $url)
{
    echo '<meta name="viewport" content="width=device-width, initial-scale=1.0">';
    echo '<h2>タイトル:' . $title . '</h2>';
    echo '<p>作成日:' . $createAt . '</p>';
    echo '<p>URL: <a href="' . $url . '">' . $url . '</a></p><hr>';
};
```

５分でできるかよとか言われそうですがcURLコマンドをPHPコードに変換してくれるサービスがあるので簡単なんですね～あとは`json_decode`してHTMLに入れるだけ。
### 動作確認
https://0115765.com/samples/php/MicroCMS_List.php にアクセスしたら記事一覧が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513165/cdc8026d-f0c2-19a7-7462-c04621ffd522.png)
各リンクをクリックすると該当IDの作成した記事が表示されます。ちゃんと出来てますね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513165/4d9f2554-c1ec-6316-1ed9-ce5269ecba3f.png)
LightHouseっていうChrome系ブラウザに搭載しているWebサイトの速度などを評価するヤツで測定してみましたが**Speedは100点になっており速度面でも問題なさそう**でした。
![rapture_20210910174325.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513165/e95df0a7-c9f7-45dc-5221-0d7c2e63f3ff.png)


※今回やってませんが一応XSS対策もしておいてくださいね。
とりまできました。
## 【JavaScript】実装例
PHPで十分だけど一応JavaScriptでも作ってみました。**Vueなどのフレームワークを使わずVanillaのJavaScriptを使った**ので勘違いなく…
ちなみにこっちのほうが簡単です。

```html:Content.html
<!DOCTYPE html>
<html lang='ja'>

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Content</title>
</head>

<body>
    <main>
        <h2 id='title'></h2>
        <p id='date'></p>
        <article id='body'></article>
    </main>
    <script>
        // 取得
        fetch('https://***********.microcms.io/api/v1/news/w65rp7nbzn', {
                headers: {
                    'X-API-KEY': '****************************************'
                }
            })
            .then(res => res.json())
            .then(json => {
                document.getElementById('title').innerHTML = 'タイトル:' + json.title;
                document.getElementById('date').innerHTML = '作成日:' + json.createdAt;
                document.getElementById('body').innerHTML = '本文' + json.body;
            })
    </script>
</body>

</html>
```
確認してみても大丈夫でした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513165/270c8040-2b7a-68e3-4b8b-c0ebf7a56c96.png)

### 注意事項
バニラのJSで作成すると**APIキーが丸見えになる**のでそこだけ注意してください。デモが無いのもそういうわけです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513165/20bf9c69-0c0c-c7d5-dc1e-5f5709c89f6f.png)
なので**サーバーサイドやSSGで開発することが必須になります！**
### 総括
超爆速で作ることができて正直感動しております()
最近有名なので是非使ってみてください！

https://github.com/ichii731/php-examples/tree/main/microCMS-Demo

[Twitter@ichii731](https://twitter.com/ichii731) | [ポートフォリオ](https://ic731.net)

あ、ちなみにAPIは記事管理画面で直接投げて確認できますよ～
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513165/5b15e2e1-4641-460f-8cf9-fcb2267ae48e.png)