sitefinity

How to filter a list of Pages by Category to display as a navigation


In Sitefinity v12.x I would like to create a widget that allows the user to select one or more Categories (Hierarchical Taxons) to use as filter criteria, and after which the widget would query for Pages that have these Categories assigned to them. This seems simple enough on the surface but I can't seem to pull it all together.

I've added "Category" as a Custom Field to the Page data and I've created my test pages. What I'm struggling with is forming the query that can access the custom field "Category" and then compare those against the categories provided by the user.

I've tinkered for awhile but it seems the issue I'm having is retrieving the Categories assigned to a Page from within the Linq query. I've tried var categories = pageNode.GetValue("Category") on it's own and that works as expected. But when I try to use the .GetValue("Category") method in a Linq query this does not seem to be valid, here is an example of what I mean:

var pageManager = PageManager.GetManager();
var pages = pageManager.GetPageDataList().Where(pageData =>
        (pageData.Culture == "en" ||
        pageData.NavigationNode.LocalizationStrategy != Telerik.Sitefinity.Localization.LocalizationStrategy.Split) &&
        pageData.NavigationNode.NodeType == Telerik.Sitefinity.Pages.Model.NodeType.Standard &&
        pageData.NavigationNode.RootNodeId == Telerik.Sitefinity.Abstractions.SiteInitializer.CurrentFrontendRootNodeId &&
        pageData.Status == ContentLifecycleStatus.Live)
    .Select(x => x.NavigationNode);

foreach (PageNode page in pages)
{
    // This properly retrieves Categories assigned to a Page in the Debug window
    var categories = page.GetValue("Category"); 
}

// This does not work, error message below .Any() reads: 'object' does not contain a definition for 'Any' and no accessible extension method 'Any' accepting a first argument of type 'object' could be found
var categoryPages = pages
    .Where(pageData => pageData.GetValue("Category").Any())
    .ToList();

Is there a way I can use/access the Custom Field "Category" on a Page from within a Linq query? Or do I have to go about this some other way? Thank you in advance for any guidance!


Solution

  • Thank you for the tips everyone! I was able to sort it out by specifying the type of the Custom Value in the Linq query, like so: pageData.GetValue<TrackedList<Guid>>("Category"), here's what I came up with:

    var pageManager = PageManager.GetManager();
    var pages = pageManager.GetPageDataList().Where(pageData =>
            (pageData.Culture == "en" ||
            pageData.NavigationNode.LocalizationStrategy != Telerik.Sitefinity.Localization.LocalizationStrategy.Split) &&
            pageData.NavigationNode.NodeType == NodeType.Standard &&
            pageData.NavigationNode.RootNodeId == Telerik.Sitefinity.Abstractions.SiteInitializer.CurrentFrontendRootNodeId &&
            pageData.Status == ContentLifecycleStatus.Live && pageData.Visible == true)
        .Select(x => x.NavigationNode);
    
    var filteredPages = pages
        .Where(pageData => categoriesQuery.All(c => pageData.GetValue<TrackedList<Guid>>("Category").Contains(c)))
        .ToList();