star back image
people4
電飾 電飾
moon
men
microCMSで、APIとかJSONを体験しよう

【microCMS】APIとかJSONを体験しよう

BLOG WEBログ
読了約:43分

流行りのクラウドAPIサービス「マイクロCMS」を利用したことはありますか?
https://microcms.io/

クラウド上のCMSに画像などを登録して、APIを読み取ってホームページに表示させるというミッションになります。

CMSってなんですか。

※CMSはContents Management Systemの略です。
参考:日立ソリューションズ
https://www.hitachi-solutions.co.jp/digitalmarketing/sp/column/cms_vol01/

簡単なブログを作成したいです。
APIといえばWPのブラグインのアレかな?

WordPressのAPIブラグインを入れて、jsonで表示させるアレに近い感じかな?あれ。
WPでテストした遠い記憶が微かに浮かびます。

夢かも。

WordPressをインストールしなくていい。
それだけで便利そうです。

WordPressがいらない。活用方法など初めてなのでわからないことばかりですが、今回試してわかったことは2点でした。

・簡単ポイント
WordPressをインストールしなくていいのが楽である。
(データベースの設定不要、WordPressのバージョン管理不要。)

・面倒ポイント
ページに表示させるためのコードを書くのが面倒である。
(白紙のhtmlからページ作成をします、インターネットのサーバーが必要です。)

参考の日立のサイトでは、CMSを使うとコスト削減になるという話です。
コスト削減は運用コスト面かなぁ思います。

表示させるページを作るのが大変で、初回の構築費用は結構なコストが必要な印象です。プログラムが得意な方はそうでもないのでしょうか。

microCMSは無料で3個までAPI体験できる

少ない要件なら「無料」でCMS運用が可能です。

無料:Hobbyプラン
https://microcms.io/pricing

どうやって使うのか、ざっくり以下の2項目となります。

❶ microCMSにAPIを作成し情報を登録する。
❷ 情報表示のコードを書いたhtmlファイルをFTPでネットにUPする。

❷のコードを書くのは気が重いです。
APIって何ですか?

参考:APIの例えばこんな使い方・活用方法
https://microcms.io/features/link-api

検索や参考を拝見すると、phpとかjavascriptやPythonなど、好きなものを使ってjsonを読み取って表示させたら良いですよ。という話です。

好きなものと言われても困りませんか。

今回はjavascriptを利用することにしました。

❶ microCMSにAPIを作成し情報を登録しよう!

microCMSの「無料アカウント登録」をしてからログインすると、よく使われそうなテンプレートが用意されておりました。

microCMSの「サービスを作成」でテンプレートを利用できる図

テンプレートから「バナー」と「ブログ」のAPIを追加したいと思います。

microCMSで、バナーのAPIを作成してみた時の図

コンテンツ(API)+の下に、{}バナーというAPIが作成されました。

・ブログのAPIも追加
上にある「ブログ」も押してみました。すると、同時に2つAPIが追加されました。

microCMSで、ブログの初期作成時のサンプル登録されていた図

サンプル記事が1つ「公開中」でした。

microCMSのカテゴリの初期作成時の内容の図

カテゴリは3つ登録がありました。
記事の内容の種類(カテゴリー)を決めるのに使うのでしょう。

無料の枠は3つまでなので、API追加はここで終わりです。
※APIの「バナー」を「お知らせ」に名前変更しました。

ブログ記事を増やします
「+追加」ボタンを押して、サンプル記事をコピー量産しました。

microCMSで、ブログのサンプル記事をコピー量産したところの図

それをastrowaveのホームページ上に表示させてみようと思います。

3記事を増やして1つを「下書き」に。
あとで使うため。

ここまではクラウド上で思ったより簡単に進められましたね。

❷ 情報表示のコードを書いたhtmlファイルをFTPでネットにUPしよう!

簡単なブログを表示させるため、ブログTOPページとブログ記事詳細ページの、2ページ分のファイルを作成しました。

・/microcms/index.php
https://astrowave.jp/microcms/
・/microcms/blog-detail.php
https://astrowave.jp/microcms/blog-detail.php?id=7u3b6lplvld

※/microcms/blog-preview.php ←(オプション)

上記2ファイルにコードを記述し、FTPソフトでサーバーにUPします。

【共有1】ブログTOPページを表示するコードを作成しよう

トップページ(index.php)の要件は以下です。

https://astrowave.jp/microcms/

・このブログのバナー{お知らせ}の表示
・カテゴリー名の表示
・公開の記事の表示(コンテンツ内容はいらない)
・公開の記事の「詳細ページ」へリンクをつける

html

<!-- content -->
<section class="main">
  <div id="result1"></div>
</section>

<!--Categories-->
<section class="categories">
  <div id="result1_2"></div>
</section>

<!--記事内容-->
<section class="content">
  <div id="result1_3"></div>
</section>

idの部分に情報が出力される想定です。
ページの差し込みたい部分へ入れましょう。

css

<style>
.mv-box img {
  width: 100%;
  height: auto;
}
.list img {
  width: 100%;
  height: auto;
}
.content .list figure {
  margin: 0;
}
.categories #result1_2 {
  display: flex;
}
.categories .list {
  position: relative;
}
.categories .list::before {
  content: "";
  position: absolute;
  top: 0;
  right: 0;
  height: 100%;
  width: 1px;
  background: #b4b4b4;
}
.categories .list:first-child::after  {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  width: 1px;
  background: #b4b4b4;
}
.categories .stores-list-ttl {
  padding: 5px 15px;
  margin: 0;
}
#result1_3 {
  display: flex;
  flex-wrap: wrap;
  margin: 30px 0 0;
}
#result1_3 .list:nth-child(even) {
  width: 49%;
  margin: 0 0 0 1%;
}
#result1_3 .list:nth-child(odd) {
  width: 49%;
  margin: 0 1% 0 0;
}
</style>

表示崩れしないよう最低限のcssです。お好きに変えてOK。

javascrit

<script>
window.onload = function() {

  const API_KEY = '●●●●●●●●●●●●'; // APIキーを設定
  const API_URL_BASE = 'https://astrowave.microcms.io/api/v1';

  let apiUrl;

  apiUrl = 'https://astrowave.microcms.io/api/v1/banner/?limit=100';
  headers = { 'Content-Type': 'application/json', 'X-MICROCMS-API-KEY': API_KEY };

  // APIエンドポイントとパラメータを確認
  console.log(`Fetching from URL: ${apiUrl}`);


  // Fetch requests
  fetch(apiUrl, { method: 'GET', headers: { 'Content-Type': 'application/json', 'X-MICROCMS-API-KEY': API_KEY } })
    .then(response => {
      if (!response.ok) {
        throw new Error('Network response was not ok');
      }
      return response.json();
    })
    .then(data => {
      renderData1(data);
      renderData1_2(data);
      renderData1_3(data);
    })
    .catch(error => console.error('Fetching error:', error));


    function renderData1(data) {
      const result1 = document.getElementById('result1');

      // 画像を含む他の要素のレンダリング方法を定義するテンプレート関数
      const html = `
        <div class="mv-box">
          <div class="image">
            ${data.image ? `<img src="${data.image.url}" alt="Image">` : ''}
          </div>
          <div class="info-link">
            <a href="${data['url']}" class="" target="_blank">${data['url']}
              <svg class="up-arrow" xmlns="http://www.w3.org/2000/svg" width="11.318" height="11.046" viewBox="0 0 11.318 11.046"><g transform="translate(-113.655 0.652)">
              <path d="M6,0V6H0" transform="translate(118.273 6.048) rotate(-90)" fill="none" stroke="#111" stroke-width="1.4"/>
              <path d="M14,0H0" transform="translate(114.15 9.899) rotate(-45)" fill="none" stroke="#111" stroke-width="1.4"/></g>
              </svg>
            </a>
          </div>
          <div class="info-box">
            <p class="top-txt">${data['description']}</p>
          </div>
        </div>
      `;

      // HTMLをDOMに挿入
      result1.innerHTML = html;

    }

    // Categoriesの内容
    function renderData1_2(data) {
      fetch('https://astrowave.microcms.io/api/v1/categories?limit=100', {
        method: 'GET',
        headers: {
          'Content-Type': 'application/json',
          'X-MICROCMS-API-KEY': API_KEY
        },
      })
      .then(response => response.json())
      .then(data => {
        const result1_2 = document.getElementById('result1_2');
        const contents = data.contents;
        let html = '';

        contents.forEach(item => {
          html += `
            <div class="list">
              <p class="stores-list-ttl">${item['name']}</p>
            </div>
          `;
        });

        result1_2.innerHTML = html;
      })
      .catch(error => {
        console.error('Error fetching data:', error);
      });
    }

    // 記事内容
    function renderData1_3(data) {
      fetch('https://astrowave.microcms.io/api/v1/blogs?limit=100', {
        method: 'GET',
        headers: {
          'Content-Type': 'application/json',
          'X-MICROCMS-API-KEY': API_KEY
        },
      })
      .then(response => response.json())
      .then(data => {
        const result1_3 = document.getElementById('result1_3');
        const contents = data.contents;
        let html = '';

        contents.forEach(item => {
          // updatedAtの日時を取得し、フォーマットを変更
          const updatedAt = new Date(item.updatedAt);
          const formattedDate = `${updatedAt.getFullYear()}/${String(updatedAt.getMonth() + 1).padStart(2, '0')}/${String(updatedAt.getDate()).padStart(2, '0')}`;

          html += `
            <div class="list">
              <a href="/microcms/blog-detail.php?id=${item.id}" class="blog-title">
                <div class="list-eyecatch">${item.eyecatch ? `<img src="${item.eyecatch.url}" alt="Image">` : ''}</div>
                <p class="list-category"><span class="catego">${item['category'].name}</span> ${formattedDate}</p>
                <p class="list-ttl">${item['title']}</p>
              </a>
            </div>
          `;
        });

        result1_3.innerHTML = html;
      })
      .catch(error => {
        console.error('Error fetching data:', error);
      });
    }

};
</script>

記述が長いのは3つ分のAPIを繋げて記述しているからです。

警告。長すぎです!短くできないんですか。

すみません、目がかすんでしまって限界です。
解説はAIに投げ込んで聞いてください。
以下のように出力されました。

3つのAPIが出力されたブログTOPページの説明図

4記事のうち1件は「下書き」なので、3件のブログが表示されています。

次はスキーマについての情報を書きたいと思います。

【APIスキーマ】スキーマってなに?

「スキーマ」って知ってますか?必要になります。

初耳です。

上の【共有1】のjavascriptを眺めていると以下の部分が、HTMLを吐き出しているコードなんだろうなぁと、察しがつくと思います。

contents.forEach(item => {
// updatedAtの日時を取得し、フォーマットを変更
const updatedAt = new Date(item.updatedAt);
const formattedDate = `${updatedAt.getFullYear()}/${String(updatedAt.getMonth() + 1).padStart(2, '0')}/${String(updatedAt.getDate()).padStart(2, '0')}`;

html += `
<div class="list">
<a href="/microcms/blog-detail.php?id=${item.id}" class="blog-title">
<div class="list-eyecatch">${item.eyecatch ? `<img src="${item.eyecatch.url}" alt="Image">` : ''}</div>
<p class="list-category"><span class="catego">${item['category'].name}</span> ${formattedDate}</p>
<p class="list-ttl">${item['title']}</p>
</a>
</div>
`;
})

html += `以降の記述でしょうか。

はい。テキストの黄色い部分。
${item.●●●●.url}とか、${item[‘title’]}とか見慣れない記述があると思いますが、その部分がmicroCMSで登録したものに差し代わります。

${item['category'].name}とありますが、${item.category.name}でもOK。
${item['title']}も、${item.title}で表示されます。
好きな方でどうぞ。

${item.●●●●.url]の、●●●●の部分に入るのが「APIスキーマ」というものです。

どこにあるのですか?

microCMSのどこで確認するのでしょうか。

ここにあります。
ブログのスキーマを確認しましょう。

コンテンツは「ブログ」のところで、[API設定]というボタンが右上にあります。

API設定でスキーマを確認するには、「API設定」ボタンから

ページ遷移したらAPI設定メニューの「APIスキーマ」を選んでください。

microCMSでAPIスキーマを確認している図

赤ラインの引きました「フィールドID」の英文字を利用をします。

${item.●●●●.url]の、●●●●の部分に、${item.title}のように適用していってください。

下の画像は記事入力中のmicroCMSの管理画面ですが、表示名の数だけちゃんとフィールドIDは用意されていますよ、と言う図です。

microCMSでAPIスキーマを確認している図2

API「カテゴリ」やAPI「お知らせ」のスキーマも同じように確認できます。
「API_KEY」や「API_URL_BASE」は、目立つところに表示されているので場所は割愛します。

補足:
apiUrl = 'https://astrowave.microcms.io/api/v1/banner/?limit=100';

上記のAPIをgetしてくるURLのお尻に付いている「?limit=100」があります。
これはリミットを増やしています。
microCMSでは有料にしないと10件までの制限がかかっていて、これをつけないとそれを超える情報を表示してくれません。

100件まで無料で登録して使えるということです。

公式
https://help.microcms.io/ja/knowledge/only-10contents-from-get-api

100件は想像以上にすごいです。
このastrowaveブログも1年かけても100記事にできませんでした。

次はブログ記事ページの情報を表示させるコードです。

【共有2】ブログ記事ページを表示するコードを作成しよう

個別のブログ記事ページ(blog-detail.php)の要件は以下です。

https://astrowave.jp/microcms/blog-detail.php?id=7u3b6lplvld
個別に詳細ページを表示するには、URLのお尻にブログ記事の「id」を追加することで見れます。

・キャッチの画像の表示
・タイトル名の表示
・作成日付の表示
・コンテンツ内容の表示
・NEXT / PREVの機能追加

「id」ってなんですか?

microCMSで、記事のIDの確認の方法

ブログの「id」は「コンテンツID」と呼ばれているようです。
記事を増やしたら自動で割り振られるので、あまり意識することはありませんが、microCMSの管理画面や、URLのお尻に確認することができます。

html

<!-- content -->
<section class="blog-detail">
    <div id="result1_3"></div>
    <div id="pagination">
      <a id="prevPost" href="#" style="display: none;">PREV</a>
      <a id="nextPost" href="#" style="display: none;">NEXT</a>
  </div>
</section>

css

<style>
.blog-detail img {
  width: 100%;
  height: auto;
}
.blog-detail figure {
  margin: 0;
}
#pagination {
  display: flex;
  margin: 20px 0 0;
}
#pagination a {
    background: #eee;
    border-radius: 9999px;
    position: relative;
    display: flex;
    justify-content: space-around;
    align-items: center;
    margin: 0 auto;
    max-width: 250px;
    padding: 10px 25px;
    font-family: "Noto Sans Japanese";
    color: #333333;
    line-height: 1.0;
    text-decoration: none;
    transition: 0.3s ease-in-out;
    font-weight: 500;
}
#pagination a:hover {
    background: #333333;
    color: #FFF;
}
#pagination a#nextPost:after {
    content: '';
    width: 5px;
    height: 5px;
    border-top: 3px solid #333333;
    border-right: 3px solid #333333;
    transform: rotate(45deg) translateY(-50%);
    position: absolute;
    top: 50%;
    right: 20px;
    border-radius: 1px;
    transition: 0.3s ease-in-out;
}
#pagination a#prevPost::before {
  content: '';
  width: 5px;
  height: 5px;
  border-top: 3px solid #333333;
  border-right: 3px solid #333333;
  transform: rotate(-135deg) translateY(50%);
  position: absolute;
  top: 50%;
  left: 15px;
  border-radius: 1px;
  transition: 0.3s ease-in-out;
}
#pagination a#nextPost:hover:after,
#pagination a#prevPost:hover:before {
  border-color: #FFF;
}
</style>

簡易なNEXT / PREVボタンのcssです。

javascript

<script>
window.onload = function() {
  const API_KEY = '●●●●●●●●●●●●'; // APIキーを設定
  const API_URL_BASE = 'https://astrowave.microcms.io/api/v1';

  const urlParams = new URLSearchParams(window.location.search);
  const postId = urlParams.get('id');

  // 全てのブログ投稿を取得
  fetch(`${API_URL_BASE}/blogs?limit=100`, {
    method: 'GET',
    headers: { 'Content-Type': 'application/json', 'X-MICROCMS-API-KEY': API_KEY }
  })
  .then(response => response.json())
  .then(data => {
    const posts = data.contents;
    const currentIndex = posts.findIndex(post => post.id === postId);

    // 現在の投稿データを表示
    const post = posts[currentIndex];
    renderPostDetail(post);

    // 前後の投稿を設定
    if (currentIndex > 0) {
      const prevPost = posts[currentIndex - 1];
      document.getElementById('prevPost').href = `/microcms/blog-detail.php?id=${prevPost.id}`;
      document.getElementById('prevPost').style.display = 'block';
    }

    if (currentIndex < posts.length - 1) {
      const nextPost = posts[currentIndex + 1];
      document.getElementById('nextPost').href = `/microcms/blog-detail.php?id=${nextPost.id}`;
      document.getElementById('nextPost').style.display = 'block';
    }
  })
  .catch(error => console.error('Error fetching data:', error));

  // 現在の投稿詳細を表示する関数
  function renderPostDetail(post) {
    const postDetail = document.getElementById('result1_3');
    postDetail.innerHTML = `
      <div class="image">
        ${post.eyecatch ? `<img src="${post.eyecatch.url}" alt="Image">` : ''}
      </div>
      <h1>${post.title}</h1>
      <p>${new Date(post.updatedAt).toLocaleDateString()}</p>
      <div>${post.content}</div>
    `;
  }
}
</script>

こんな感じで出力されました。

満足です。

【共有3】記事の下書きを見たい(オプション)

ステータスが「下書き」の記事の表示を確認することはできるのでしょうか。その方法は公式に書いてありました。

公式:下書き・予約投稿、draftKey、画面プレビュー
https://blog.microcms.io/draftkey_and_preview/

WordPressでは普通にあるプレビュー機能、それはないので作る必要があります。

下書き(blog-preview.php)の要件は以下です。

https://astrowave.jp/microcms/blog-preview.php?id=y9dkkqgsrd&draftkey=GSiWE4aa8
「下書き」をプレビューするには、URLのお尻に「id」と「draftKey」を追加すると確認できます。

・キャッチの画像の表示
・タイトル名の表示
・作成日付の表示
・コンテンツ内容の表示
・NEXT / PREVはいらない

html

<!-- content -->
<section class="blog-detail">
  <div id="result1_3"></div>
</section>

javascript

<script>
window.onload = function() {

const API_KEY = '●●●●●●●●●●●●'; // APIキーを設定
const API_URL_BASE = 'https://astrowave.microcms.io/api/v1';

const urlParams = new URLSearchParams(window.location.search);
const id = urlParams.get('id');
const draftKey = urlParams.get('draftkey');

let apiUrl;

if (id && draftKey) {
    apiUrl = `${API_URL_BASE}/blogs/${id}?draftKey=${draftKey}`;
} else {
    apiUrl = 'https://astrowave.microcms.io/api/v1/blogs/?limit=100';
}

console.log(`Fetching from URL: ${apiUrl}`);

fetch(apiUrl, {
  method: 'GET',
  headers: {
    'Content-Type': 'application/json',
    'X-MICROCMS-API-KEY': API_KEY
  }
})
.then(response => {
  if (!response.ok) {
    throw new Error('Network response was not ok');
  }
  return response.json();
})
.then(data => {
  renderData1_3(data);
})
.catch(error => console.error('Fetching error:', error));

function renderData1_3(data) {
  // 単一記事データを直接使用
  renderPostDetail(data);

  function renderPostDetail(post) {
    const postDetail = document.getElementById('result1_3');
    postDetail.innerHTML = `
      <div class="image">
        ${post.eyecatch ? `<img src="${post.eyecatch.url}" alt="Image">` : ''}
      </div>
      <h1>${post.title}</h1>
      <p>${new Date(post.updatedAt).toLocaleDateString()}</p>
      <div>${post.content}</div>
    `;
  }
}
};
</script>

「下書き」を見るためにはjavascriptで、draftkeyを利用することになります。

「draftKey」はどこにあるのでしょう。
この言葉も初耳ですよ。

microCMSでdraftkeyを確認する場所の図

「下書き」のブログを開いてください。draftKeyは「下書き」にすると自動で付与されるようです。

以下のように非公開の「下書き」なブログを確認することができました。

下書きを出力の図

ちょっと記事が長かったでしょうか。

ブログについては以上になります。

初体験タグ<pre>

<pre>タグ知ってますか?microCMSでファーストコンタクトしました。
文字が改行されなくて一癖あったのでメモとなります。

Perl Web開発者のHTML・CSS入門
https://webdesign.perlzemi.com/blog/20200208090352.html

pre {
  white-space: pre-wrap;
  word-break:break-all;
}

このcssを適用することで改行してくれました。

【AI】イラストを描いてもらった

今回の記事のキャッチ画像で使わせてもらいます「Memeplex.app」で作成した画像です。誰でもgoogleアカウントでログインして使えます。

この記事にピッタリなイラストのための考えたリクエストは、「マイクロコンピュータが増殖して宇宙船を覆ってしまった」です。

マイクロなので見えないのかも?
なんかカッコイイからいいかな。

選んだモードは以下の3つです。

  • 画風指定なし
  • ハリウッドSF風
  • UnrealEngine5風

参考サイト置き場

APIの仕組みが分かる(Pythonコード付き)
https://qiita.com/Saku731/items/6ae290f72e98723f165d