JavaScriptからPowerCMS XのAPIを容易に利用できる「PTRESTfulAPIClient」が配布されています。私が開発したもので、ブラウザ環境とNode.js環境どちらでも利用できます。本稿ではNext.jsでの利用を解説します。Next.jsの公式ドキュメント「Basic Features: Data Fetching | Next.js」が参考になりました。PTRESTfulAPIClientが提供する各メソッドの引数の詳細はREADMEをご確認ください。
準備
libs/pt-restful-api-client.js
にPTRESTfulAPIClientのファイルを配置した後、libs/client.js
でPTRESTfulAPIClientのインスタンスを作成しておきます。(※2021年11月8日追記:npmコマンドでもインスール可能になりました。)
import PTRESTfulAPIClient from './pt-restful-api-client';
export const client = new PTRESTfulAPIClient('https://jamstack.anothersky.pw/powercmsx/api', 1);
一覧ページ
オブジェクトの一覧ページ(例えばentry一覧)ではlistObjects
でオブジェクト一覧を取得します。PTRESTfulAPIClientがURLの組み立てやFetch APIの呼び出しを行うので、モデルとワークスペースを引数で指定するだけで済みます。記事数や並び順などのパラメーターも指定できます。
import Link from 'next/link';
import { client } from '../libs/client';
export default function Home({ entries }) {
return (
<ul>
{entries.map(entry => (
<li key={entry.id}>
<Link href={`/information/${entry.basename}`}>
<a>{entry.title}</a>
</Link>
</li>
))}
</ul>
)
}
export const getStaticProps = async () => {
const params = {
sort_by: 'published_on',
sort_order: 'desc',
limit: 6,
};
const response = await client.listObjects('entry', 1, params);
const data = await response.json();
return {
props: {
entries: data.items,
},
};
};
個別ページ
オブジェクトの個別ページ(例えばentryの個別ページ)ではgetObject
でオブジェクトのデータを取得します。サンプルコードではオブジェクトのIDではなく、ベースネームでオブジェクトを特定しています。カラムを指定しない時は全カラムのデータがレスポンスに含まれるので、モデル設計とページの出力状態によっては無駄が生じる可能性があります。パラメーターで必要なカラムを指定するのがよいでしょう。
import { client } from '../../libs/client'; export default function BlogDetail({ entry }) { return ( <> <h1>{entry.title}</h1> <div> <time dateTime={entry.published_on.replace(/(\d{4}-\d{2}-\d{2}).*/, '$1')}>{entry.published_on.replace(/(\d{4})-(\d{2})-(\d{2}).*/, '$1年$2月$3日')}</time> </div> <div
dangerouslySetInnerHTML={{ __html: entry.text, }} /> </> ); } export const getStaticPaths = async () => { const response = await client.listObjects('entry', 1); const entries = await response.json(); const paths = entries.items.map(entry => ({ params: { basename: entry.basename }, })); return { paths, fallback: false }; }; export const getStaticProps = async (context) => { const options = { cols: 'title,text,published_on', basename: context.params.basename, }; const response = await client.getObject('entry', null, 1, options); const entry = await response.json(); return { props: { entry, } } };
認証が必要な時
下書きのオブジェクトを取得する時など、認証が必要な場合は以下のコードで認証を行いアクセストークンを取得します。取得したアクセストークンはgetObject
メソッドなどの引数として渡します。認証に必要なユーザー名やパスワードは.env
に記述しておきます。
const name = process.env.CMS_USERNAME;
const password = process.env.CMS_PASSWORD;
const authResponse = await client.authentication(name, password);
if (!authResponse.ok) {
return res.status(401).json({ message: 'Authentication faild.' });
}
const authData = await authResponse.json();
const token = authData.access_token;