Tailwind Logo

Create RSS feeds for articles managed by XM Cloud - Part 1

XM CloudNext.js

Published: 2024-07-04

In this article, we will show you how to get a list of articles from GraphQL and create an RSS feed for XM Cloud content.

Prerequisite.

We will be creating a sample RSS feed with a minimum of fields and samples. By setting similar fields in the actual page template, it is possible to implement various RSS feeds as well as articles.

The prerequisites are as follows

  • Retrieve the following items from the target template as RSS feeds
    • Title
    • Description
    • PublishedDate
    • URL
    • Image
  • Implement using the Next.js App Router

As for the sample code, we will implement it in the https://github.com/haramizu/sitecoredemo-jp repository.

Next.js in JSS 22.0 is 14.1 and the entire site is built with Page Router, Page Router and App Router can coexist. For RSS, we would like to use GraphQL to retrieve data and return the data in XML. Therefore, we will use the App Router for this implementation.

Create News Template

In creating a template, duplicate the Page template to create a new Article template. Right-click on the /sitecore/templates/Project/Tailwindcss/Page template and click Duplicate.

xmcrss01.png

In this case, we will use the News template. The existing Title should be used as is, and the following three items should be added.

  • Description - Multi-line Text
  • PublishDate - Datetime
  • Image - Image

The template is now complete. In the implementation, it is necessary to define which type of items can be created under which type so that items can be created using the News template, but since the purpose of this project is to create an RSS feed, this is omitted.

Create a sample item

This time, we will create a sample of about five articles and display them as RSS. If the number of target contents actually increases, it will be necessary to acquire data using GraphQL multiple times, but since the concept of this project is to create a minimal sample of RSS, this will be omitted.

In this case, we have created RSS samples under several pages in the following manner. You can see that the items are created in several paths using the News template created above.

xmcrss02.png

Get data using Postman

We will create a query to retrieve data from GraphQL for the above items. The conditions will be as follows

  • Get a list of the contents of the News template ID
  • Get English items
  • Data display of item's fields
  • Sort by date

Now we will actually create the query.

News Retrieve content list

The query is made to an item managed by Sitecore using the ID used as the News template. The query will be as follows

GraphQL
query Search ($templateId: String!){
    search(
        where: {
            name: "_templates"
            value: $templateId
            operator: EQ
        }
    ) {
        total
    }
}

This time, the following data is set as GraphQL Variables for $templateId.

JSON
{
    "templateId": "B9453B23-0E09-4D98-99C0-EAA0F16DD6DA"
}

The following results were obtained

JSON
{
    "data": {
        "search": {
            "total": 6
        }
    }
}

You should have created 5 items, but the number of items you are creating in this template is 6. This will be corrected later.

Get English items

Next, the target content is narrowed down to English language drinkers. Since it is possible to switch languages and create other RSS feeds, the following changes are made to have this value as a GraphQL Variable.

JSON
{
    "language": "en",
    "templateId": "B9453B23-0E09-4D98-99C0-EAA0F16DD6DA"
}

Then, when narrowing down the language, add an AND rule for the template ID in the where to do so with respect to the language.

GraphQL
query Search($language: String!, $templateId: String!) {
    search(
        where: {
            name: "_templates"
            value: $templateId
            operator: EQ
            AND: { name: "_language", value: $language, operator: EQ }
        }
    ) {
        total
    }
}

The same result of 6 was returned this time. The total number will not change even if you actually create content in other languages, so please create another language in the CMS to check if you can narrow down the results.

Add a field for the item

We would like to focus on the GraphQL items when retrieving data for an item. First, we want to retrieve the id and URL.

GraphQL
query Search($language: String!, $templateId: String!) {
    search(
        where: {
            name: "_templates"
            value: $templateId
            operator: EQ
            AND: { name: "_language", value: $language, operator: EQ }
        }
    ) {
        total
        results {
            id
            url {
                hostName
                path
            }
        }
    }
}

Now when you run the program, you will see the paths of 6 items. The result shows that the following items have actually been retrieved.

JSON
{
  "id": "D6C15B8571874F96A684CA8655E615AA",
  "url": {
    "hostName": "xmcloudcm.localhost",
    "path": "/en/sitecore/templates/Project/Tailwindcss/PageType/News/__Standard-Values"
  }
}

In other words, you create a template, and the items in the __Standard-Values definition of that template use the same ID. So this time, we will add siteRootId to Where so that we can have it as a variable so that we only get items under the content tree.

GraphQL
query Search($language: String!, $siteRootId: String!, $templateId: String!) {
    search(
        where: {
            name: "_templates"
            value: $templateId
            operator: EQ
            AND: [
                { name: "_path", value: $siteRootId, operator: CONTAINS }
                { name: "_language", value: $language, operator: EQ }
            ]
        }
    ) {

Variables at this time are as follows.

JSON
{
    "language": "en",
    "siteRootId": "E66EE43B-398B-486E-9F7F-5FE36A4093D3",
    "templateId": "B9453B23-0E09-4D98-99C0-EAA0F16DD6DA"
}

For the value of _path, the ID of the top item in the content tree is used. This means that even if the item is an Article, data is taken only from the bottom of the tree.

Then rewrite under results to take the data for the required fields as follows

GraphQL
results {
    id
    url {
        hostName
        path
    }
    title: field(name: "Title") {
        value
    }
    publishDate: field(name: "PublishDate") {
        value
    }
    description: field(name: "Description") {
        value
    }
    image: field(name: "Image") {
        jsonValue
    }
}

Now you have all the data you need for RSS.

Retrieved by date of publication

Of the acquired data, describe the sort order of the publishDate items in the "Where" field in order of new arrivals.

The following is the completed GraphQL query.

GraphQL
query Search($language: String!, $siteRootId: String!, $templateId: String!) {
    search(
        where: {
            name: "_templates"
            value: $templateId
            operator: EQ
            AND: [
                { name: "_path", value: $siteRootId, operator: CONTAINS }
                { name: "_language", value: $language, operator: EQ }
            ]
        }
        orderBy: { direction: DESC, name: "publishDate" }
    ) {
        total
        results {
            id
            url {
                hostName
                path
            }
            title: field(name: "Title") {
                value
            }
            publishDate: field(name: "PublishDate") {
                value
            }
            description: field(name: "Description") {
                value
            }
            image: field(name: "Image") {
                jsonValue
            }
        }
    }
}

Summary

The length of this article has become quite long until I started to use GraphQL to retrieve the data. So, in this article, we will only get to the point of retrieving the data needed for RSS using GraphQL. In the next article, we will finish the process of returning RSS data after the data has been retrieved.

Related article

Tags