XM Cloud で管理している記事の RSS フィードを作成する

今回は XM Cloud のコンテンツに関して、GraphQL から記事の一覧を取得して RSS フィードを作成する手順を紹介します。

前提条件

今回は RSS フィードのサンプルを作ることを前提として、最小限のフィールドとサンプルで作成をしていきます。実際のページテンプレートに同様のフィールドを設定すれば、記事だけでなく様々な RSS を実装することが可能です。

前提条件は以下のようにします。

JSS 22.0 の Next.js は 14.1 でサイト全体としては Page Router で構築されています。Page Router と App Router は共存することが可能です。RSS に関しては GraphQL を利用してデータを取得、XML でデータを返すという実装をしたいと考えています。そこで今回は App Router で実装していきます。

News テンプレートの作成

テンプレートの作成にあたって、Page テンプレートを複製して新しく Article テンプレートを作成します。/sitecore/templates/Project/Tailwindcss/Page のテンプレートを右クリックして、Duplicate をクリックしてください。

Image

今回は News というテンプレートで作成します。既存の Title はそのまま利用する形として、以下の3つの項目を追加してください。

これでテンプレートが完成です。実装においては、News のテンプレートを利用してアイテムを作成することができるように、どのタイプの下に作れるのか、なども定義する必要がありますが、今回は RSS フィードを作成するのが目的のため省略します。

サンプルのアイテムを作成する

今回は5つほどの記事をサンプルとして作成をして、RSS として表示するように作っていきます。実際に対象となるコンテンツの本数が増えた場合は、複数回に分けて GraphQL でデータを取得する必要が出てきますが、RSS の最小限のサンプルを作るのが今回のコンセプトのため省略します。

今回は RSS のサンプルを以下のような形でいくつかのページの下に作成をしてみました。上記で作成した News テンプレートを利用して、いくつかのパスでアイテムが作成されているのがわかります。

Image

Postman を利用してデータを取得

上記のアイテムに関して、GraphQL からデータを取得するクエリを作成していきます。条件は以下の通りとなります。

それでは実際にクエリを作成していきます。

News コンテンツ一覧の取得

問い合わせとしては、Sitecore が管理しているアイテムに対して News テンプレートとして利用している ID で問い合わせをします。以下の問い合わせとなります。

graphql

今回は $templateId 対して、GraphQL Variables として以下のデータを設定しています。

json

以下の結果を取得しました。

json

5つアイテムを作成したはずですが、このテンプレートで作っているアイテムの数は 6 となっています。これは後ほど修正します。

英語のアイテムを取得

続いて対象となるコンテンツを英語飲みに絞り込みをします。言語を切り替えて別の RSS を作成する形も考えられるため、この値も GraphQL Variables として持つように以下のように変更します。

json

続いて言語の絞り込みをする際には、where でテンプレート ID に対して AND のルールを追加して、言語に関してしていするようにします。

graphql

結果は同じく 6 が今回も返されました。実際に他の言語のコンテンツを作成しても、Total の数字が変わらない形になりますので、絞り込みができているかの確認は CMS 上で別の言語を作成して確認をしてください。

アイテムのフィールドを追加する

アイテムのデータを取得する際の GraphQL に関して、項目を今回は絞って実行したいと思います。まずは id および URL を取得するようにします。

graphql

これで実行をすると6つのアイテムの path を確認することができます。結果を見ると、実は以下のアイテムの取得ができていることがわかります。

json

つまりテンプレートを作成して、そのテンプレートの定義の __Standard-Values のアイテムが同じ ID を利用していることになります。そこで、今回はコンテンツツリーの配下のアイテムのみを取得するように、Where に siteRootId を追加して変数として持てるようにします。

graphql

この時の Variables 配下の通りです。

json

この _path の value に関しては、コンテンツツリーのトップのアイテムの ID を利用しています。これにより、Article のアイテムでもツリーの配下のみのデータを取る形となります。

続いて必要なフィールドのデータを取るために、results の下を以下のように書き換えます。

graphql

これで RSS で必要となるデータが揃ってきました。

公開日順で取得

取得しているデータのうち、publishDate の項目を新着順にするための並び順を Where の中に記述をします。

以下が、完成した GraphQL の問い合わせとなります。

graphql

Next.js 経由で GraphQL を呼び出す

まず GraphQL の Endpoint を利用してデータを取得するための汎用関数を用意します。

ここでは fetchGraphQL が用意されており、動作は以下の通りです。

今回は .env.local に以下の定義を追加します。

text

これで fetchGraphQL を利用することが可能となりました。

rss.xml の作成

今回は Next.js の App Router を利用するため、ルートのパスで rss.xml を返すことを想定して、以下のパスに route.ts ファイルを作成します。

インターフェイスの作成

前回、最後に取得したデータをもとに返ってくる Json のデータを扱うための Interface をまず作成します。今回は以下のように作りました。

Query の作成

前回動作した GraphQL のクエリに関して、パラメーターを渡して呼び出すために、以下のように作成をします。

これを呼び出す際には、言語、サイトのルートの ID および対象となるテンプレートの ID の値を利用して、必要となるデータを取得するためのクエリが生成されます。

データを取得する

これまで用意したコードを利用して、以下のようにデータを取得することができる関数を用意します。fetchGraphQL を呼び出しているため、import { fetchGraphQL } from 'src/utils'; のコードも追加してください。

GET 関数の作成

最後に、リクエストされた際にデータを返す GET 関数を作成します。今回は Json のデータを取得できているのかを確認するために、以下のようなコードをまず用意しました。

この結果を確認するために、npm run start:connected のコマンドを実行したあと、http://localhost:3000/rss.xml にアクセスをするとデータが取れていることを確認できました。

Image

データを加工する

取得したデータを利用して RSS 形式のデータで結果を表示するように route.ts ファイルを変更していきます。今回はパッケージとして、以下のパッケージを利用します。

以下のコマンドを実行してパッケージを追加します。

sh

まず RSS が利用する URL を以下のように定義します。

続いて GET の中で、feed で必要となる情報を設定していきます。

続いて、作成した feed に対して、取得したデータを追加していきます。

最後に、生成された feed のデータをレスポンスとして返します。

実際に Postman を利用して http://localhost:3000/rss.xml にアクセスをすると、以下のようにデータの取得ができています。

Image

日付の修正

Sitecore で管理している日付のデータは、以下のような文字列になっています。

この結果、日付に関しては Invalid Date という結果が表示されています。これを修正するために、日付のデータに関して正規表現で扱えるように変換をします。

データを渡す部分を以下のように書き換えます。

これで正しく日付も表示ができるようになりました。

Endpoint および API キーが無効の場合

これまでデータを利用して実行して、という形で問題なく動いていましたが、 GRAPH_QL_ENDPOINT および SITECORE_API_HOST が空の場合(初回 Build の状況)では Build エラーが発生してしまいます。これを回避するために、try - catch を追加して、Build の際にエラーが出ないように、処理が正しくできなかった場合はリダイレクト処理をするように、サンプルのコードを更新しました。

まとめ

今回は RSS を実装するために、データの取得、利用して RSS のデータを加工する、という形で仕上げました。URL に関しては Next.js App Router を利用して作成しているため、今回はルートに rss.xml となっていますが、パスを切ったり、異なる RSS の場合はファイル名を変更することが可能です。ある程度汎用性を持たせるために、言語、テンプレートの ID そしてサイトのルート ID をパラメータとして呼び出すようにしてあります。