How to change the sequence of content items from multiple content types on the home page?

2025/01/17 12:14 PM

Hello everyone,

I am working on a project using Xperience by Kentico 30.0.1. I have the following scenario and need some guidance:

I have created two different content types, each having two fields.

  • Example:

    • Content Type A (Fields: Title, Description)
    • Content Type B (Fields: Image, Caption)
  • I have added two content items for each content type.

    • Example:

      • Content Type A: Content A1, Content A2
      • Content Type B: Content B1, Content B2
  • These content items are being rendered on the home page. Currently, the sequence is content of content type A first and then content of content type B

  • Requirement:
    Now content editor want to render content of content type B first and then content of content type B without making changes to the code. How can he/she can achieve same?

    I want a solution that can be managed through the Xperience admin interface or configuration.

    Any guidance or examples would be greatly appreciated.

Thank you,
Cpatel

Answers

2025/01/17 5:05 PM

It largely depends on how you model those relationships between the Home Page and your Content Type A and Content Type B.

This is similar to the Section System problem, where you want to select from multiple 'section types' and render them out in any order that the user decides.

Luckily, Xperience by Kentico makes that pretty easy thanks to the Pages and Reusable Content Field type. This allows you to specify your content types (Content Type A and Content Type B), and allow users to select any of those pages or reusable content items.

This is stored then as an ordered ContentItemGuid array in the database.

The last step is to make sure to include the linked files in your content query getting your page (in this case, the home page), and to use the IContentQueryExecutor to map the results which will gather and map (in order) your linked items, just as long as you include the WithLinkedItems(#) extension.

The Page and Reusable Content gets mapped to an IEnumerable<IContentItemFieldSource>, but it is actually mapped to the proper class, so you can use Type checking to retreive.

Here's a code snippet where i have a Testing.WebPage (IE your home page), that has a Field SectionsSystemSections that is of type Pages and Reusable Content and allows my 3 section page types (IE your Content Type A and Content Type B)

On the home page i selected various sections and ordered them.

var testPage = new ContentItemQueryBuilder().ForContentType(Testing.WebPage.CONTENT_TYPE_NAME, query => 
    query.WithLinkedItems(100, o=> o.IncludeWebPageData())
        .ForWebsite(_websiteChannelContext.WebsiteChannelName, includeUrlPath: true)
        .Where(where => where.WhereEquals(nameof(WebPageFields.WebPageItemID), 7))
        .TopN(1)
        )
    .InLanguage("en");
var mappedToPage = await _contentQueryExecutor.GetMappedWebPageResult<Testing.WebPage>(testPage);
if (mappedToPage.Any()) {
    var firstItem = mappedToPage.First();
    foreach(var section in firstItem.SectionsSystemSections) {
        if(section is Section.TestA testA) {
            var testing = testA.SectionTestAName;
        } else if(section is Section.TestB testB) {
            var testing = testB.SectionTestBName;
        } else if(section is Section.Widget widget) {
            // If you don't see the WebPageItem values, make sure your .WithLinkedItems has the optional ConfigureOptionsAction (query.WithLinkedItems(100, o=> o.IncludeWebPageData()))
            // Partial Widget Page <inlinewidgetpage web-page-id="@webPageID" initialize-document-prior="true"></inlinewidgetpage>
            // requires the WebPageItemID
            var testing = widget.SystemFields.WebPageItemID;
        }
    }
}

To answer this question, you have to login first.