Insights

Bulk Loading Items With Sitecore SXA Branch Templates

Bulk Loading Items With Sitecore SXA Branch Templates

Let's say you have a requirement to load items into Sitecore from an external source. And each item would represent a page complete with a title and content and other fields. Trouble is, your pages are built with SXA and things like the content need to go in a Rich Text component stored in the Data folder under each component. How do you do it?

With ease, as it turns out.

Setup

The Branch Template

The first thing that we will need is a Branch Template, one that has all the appropriate components already loaded onto a page that they will be associated with.

Sitecore content tree

In our case, we have a Two Column Content Page with an associated Rich Text component added into the Data folder. Nothing crazy.

Root Node For Content

Now we need a location for where the content can be loaded into. In our case, we're just loading it into this Articles subfolder.

Sitecore content tree Demo>Articles

Coding The Import

Creating The Item

Now, I'm not going to focus on how the content is obtained, but rather what we do with it after. So in our case, we've imported the data via an API, obtained the JSON data and converted it to a List<Article>.

Perhaps we even have an additional requirement that each article is loaded into a subfolder designated by the year that it was published and that the Name be associated with the article's ID from the source. Your requirements may vary.

You might be asking, why not use a Bucket? Well, if we loaded into a bucket, in my experience, the synch process actually disassociates the SXA components stored in the Data folder from the item and creates a mess. Hence why we're going about it this way.

public void CreateItems(List<Article> articleList, Item rootItem, Database db)
{
    //Disable the indexing
    IndexCustodian.PauseIndexing();

    // Disable security to allow for importing
    using (new SecurityDisabler())
    {
    if (db != null && rootItem != null)
    {
        // Get the item of the branch template 
        BranchItem template = db.GetItem(new ID(Templates.Article.TemplateID));
        if (template != null)
        {
        foreach (Article article in articleList)
        {
            // Ensure we are generating a safe to use name.
            var itemName = ItemUtil.ProposeValidItemName(article.Identifier);

            // Get year of article to know where it should go
            // 'GetYearFolder' returns the item of the folder - if it doesn't exist, it creates it
            DateTime release = GetReleaseDateTime(article);
            var year = release.Year.ToString();
            var parentItem = GetYearFolder(rootItem, year, db);

            // Check if article already exists
            Item doesItemExist = db.GetItem(parentItem.Paths.Path + "/" + itemName);
            if (doesItemExist != null) continue;

            // Create item
            Item newItem = parentItem?.Add(itemName, template);

            // Update item and related items
            UpdateItem(newItem, article, db);

            // Update the Rich Text
            UpdateRichText(newItem, article, db);
        }
        }
    }
    }
    // Resume indexing
    IndexCustodian.ResumeIndexing();
}

Next up we will look at the code for updating the primary item, i.e. article.

Updating The Item

Here's we're simply updating the appropriate fields for each article. In our case we have to update the Title, Content (which we're using to store the summary of the article to improve Solr search results), Aritlce ID, and Date. With regard to the Content field; due to the fact we're storing our main body of the article in an SXA component in the Data folder, Solr by default doesn't pick that up. We would have to create a computed field or extension to update the appropriate Solr index information.

public void UpdateItem(Item item, Article article, Database db)
{
    using (new SecurityDisabler())
    {
    //Enter into the item editing state
    item.Editing.BeginEdit();

    //Now you can edit the item field values as belwo
    item["Title"] = article.Title;
    
    item["Content"] = article.Summary;
    item["Article ID"] = article.Identifier;
    item.Fields["Date"].Value = GetReleaseDateTime(article).ToString("yyyyMMddTHHmmssZ");
    
    //once you are done with the editing, come out of editing satate then
    item.Editing.EndEdit();
    }
}

If you're curious about what is happening inside GetReleaseDateTime I've attached that as well, but it's more of a proprietary function based upon the format of the date that's coming in.

private DateTime GetReleaseDateTime(Article article)
{
    string releaseDateStr = article.ReleaseDateTime; //2021-09-23T17:19:24Z
    DateTime releaseDateTime = DateTime.ParseExact(releaseDateStr, "yyyy-MM-dd'T'HH:mm:ss'Z'", CultureInfo.InvariantCulture);
    return releaseDateTime;
}

Next up is updating the Rich Text item in the Data folder.

Update The Rich Text Component

As we are using the Branch Template as the "template" for which to generate each item from, and it already has a Rich Text item in the Data folder, each item we create will also have that same item with the same name. Hence we can update it in the following manner.

public void UpdateRichText(Item item, Article article, Database db)
{
    using (new SecurityDisabler())
    {
    // Point to the Rich Text item
    Item rtItem = db.GetItem(item.Paths.Path + "/Data/Rich Text");

    //Enter into the item editing state
    rtItem.Editing.BeginEdit();

    // Add the article content
    rtItem["Text"] = article.Content;

    rtItem.Editing.EndEdit();
    }
}

Result

We can run this import in a number of ways, i.e. through Tasks, Api Controllers, etc but we can cover that in another article. I want to show you how it looks after it's run.

You can see here that each article is loaded into a subfolder, designated by the year of the article and the Rich Text item is loaded with the appropriate content. In my case, "Test content".

Rich text component in the Sitecore content tree

And that's all it takes. Nothing crazy. You certainly might have more fields to fill or might have a more complicated sub-structure or heaven forbid a more complicated API interface to get the data. The main thing is, it's very easy to dynamically generate items utilizing page branches and having them associated with SXA components with the corresponding information.

👋 Hey Sitecore Enthusiasts!

Sign up to our bi-weekly newsletter for a bite-sized curation of valuable insight from the Sitecore community.

What’s in it for you?

  • Stay up-to-date with the latest Sitecore news
  • New to Sitecore? Learn tips and tricks to help you navigate this powerful tool
  • Sitecore pro? Expand your skill set and discover troubleshooting tips
  • Browse open careers and opportunities
  • Get a chance to be featured in upcoming editions
  • Learn our secret handshake
  • And more!
Sitecore Snack a newsletter by Fishtank Consulting
 

Meet David Austin

Development Team Lead | Sitecore Technology MVP x 3

📷🕹️👪

David is a decorated Development Team Lead with Sitecore Technology MVP and Coveo MVP awards, as well as Sitecore CDP & Personalize Certified. He's worked in IT for 25 years; everything ranging from Developer to Business Analyst to Group Lead helping manage everything from Intranet and Internet sites to facility management and application support. David is a dedicated family man who loves to spend time with his girls. He's also an avid photographer and loves to explore new places.

Connect with David