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 するようなのもあったりで、それの扱いが面倒だなぁ、、、と思ってしまう。

ここまでしないといけないのか、、、という感じではあるが。。。
そう思ってしまうのは単に自分のスキル不足なんだろうな。


色々触ってみたり、記事を読んでいると Twig ベースで考えつつ Hotwire みたいなのがいいんじゃないかっていう気もするんだけど。

Hotwireのススメ ~React製SPAをフルSSRでStimulusとTurboに書き換えた話~
https://zenn.dev/mast1ff/artic...

フロントエンド中心だと特にそこは悩まないのかも知れないが。。。

パフォーマンスをどうこうしようとなると js 周りの方に話がもどってくることになるのかなぁ、、、