2022/5/5
Remix と Cloudflare Workers で Craft CMS の詳細ページを表示する #craftcms
先日の続き。
https://remix-cloudflare-worke…
とりあえずサイトと同じ article/[slug] で詳細ページを表示するという前提。
app/routes/article/$slug.jsx を用意して
export const loader = async ({ params }) => {
let res = await fetch(`https://example.com/hogehogeapi`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'hogehoge',
},
body: JSON.stringify({
query: `
query($slug: [String]) {
entry(siteId:1,slug:$slug){
title
id
url
uri
slug
... on article_article_Entry {
id
articlebody {
... on articlebody_richeditor_BlockType {
id
typeHandle
richeditor
}
... on articlebody_asset_BlockType {
id
typeHandle
asset {
url
path
title
}
}
... on articlebody_code_BlockType {
id
code
typeHandle
}
... on articlebody_rel_article_BlockType {
id
typeHandle
rel_article {
id
title
uri
}
}
}
}
}
}`,
variables: {
"slug": params.slug,
},
}),
})
return res.json()
}
こんな感じで該当のデータを取り出す。
params に渡ってくる slug を variables に渡して、 Query の方で slug をつかって該当エントリを取り出す。
記事の本文部分(articlebody)は Craft CMS の Matrix フィールドで管理していて、ここの取り出しがなんとも冗長になってしまうのはスキル不足。
<div key={data.entry.id}>
<h1>{data.entry.title}</h1>
<div>
{data.entry.articlebody.map((articlebody) => {
if( articlebody.typeHandle == "richeditor") return <div key={articlebody.id} dangerouslySetInnerHTML={createMarkup(articlebody.richeditor)} />;
else if( articlebody.typeHandle == "code") return <div key={articlebody.id}>{articlebody.code}</div>;
else if( articlebody.typeHandle == "asset") return <div key={articlebody.id}><img key={articlebody.id} src={articlebody.asset[0].url} alt={articlebody.asset[0].title}/></div>;
else if( articlebody.typeHandle == "rel_article")
return (
<div key={articlebody.id}><ul>
{articlebody.rel_article.map((article) =>(
<li>
<Link to={`/${article.uri}`} prefetch="intent">
{article.title}
</Link>
</li>
))}
</ul></div>
);
})}
</div>
</div>
それぞれコンポーネント用意しておいてそちらに記述を書くとかできるんだろうな、、、
meta周りの制御
meta タグ周りを
export const meta = ({data}) => {
if (!data) {
return {
title: "mersy note",
description: "mersy @ singapore",
};
}
return {
title: `${data.data.entry.title} | mersy note`,
description: `${data.data.entry.title}`,
};
};
こんな感じで上書きしたり設定できるのは楽そう。
Next.js とかでももちろんできる話だけど。
CMS側で入力した埋め込みコンテンツの取り扱い
CMSから入力した物をうけとると script 周りを embed するようなのもあったりで、それの扱いが面倒だなぁ、、、と思ってしまう。
- Reactでスクリプトタグを含んだHTMLを挿入する(SSG/SSR対応)
https://zenn.dev/akira_miyake/… - Reactでscriptタグを含むHTMLを挿入し、scriptも動作させる | Counts the Clouds
https://countstheclouds.com/po… - Reactでインスタグラム投稿の埋め込みを行った時にハマったこと
https://zenn.dev/someone7140/a…
ここまでしないといけないのか、、、という感じではあるが。。。
そう思ってしまうのは単に自分のスキル不足なんだろうな。
色々触ってみたり、記事を読んでいると Twig ベースで考えつつ Hotwire みたいなのがいいんじゃないかっていう気もするんだけど。
Hotwireのススメ
React製SPAをフルSSRでStimulusとTurboに書き換えた話
https://zenn.dev/mast1ff/artic…
フロントエンド中心だと特にそこは悩まないのかも知れないが。。。
パフォーマンスをどうこうしようとなると js 周りの方に話がもどってくることになるのかなぁ、、、