Search code examples
sitecoresitecore8glass-mapper

Sitecore get all parent (ancestor) with little processing (performance)


I'm trying to come up with solution on getting all the ancestors for the context item. One option is to store _path in index and other option is to do similar to one below: http://www.glass.lu/Blog/GettingAncestors

I'm having no luck with getting the solution work for above (glass mapper) solution.

I got the index solution working but would like to avoid using index just to get the _path (collection of ancestors) as we don't have any other requirements to use index e.g. search etc.

Appreciate if someone could share the snippet for working solution or even better if Glassmapper has already included the above blog solution.


Solution

  • The most efficient way to check if one item is a descendant of another is to simply check that the current item property Paths.LongID starts with the LongID of the parent item:

    Item currentItem = Sitecore.Context.Item;
    IList<Item> menuItems = GetMenuItems();
    
    foreach (var menuItem in menuItems)
    {
        bool isActive = currentItem.Paths.LongID.StartsWith(menuItem.Paths.LongID);
    
        // do code 
    }
    

    This will work since the path GUIDs are unique for each item.

    Alternatively, if you want to use Glass models only then you can use the SitecoreInfoType.FullPath attribute:

    [SitecoreInfo(SitecoreInfoType.FullPath)]
    public virtual string FullPath { get; private set; }
    

    And then from your code you can simply check:

    Item currentItem = Sitecore.Context.Item; //or use SitecoreContext() to get a strongly types model
    IEnumerable<MenuItem> menuItems = GetMenuItems();
    
    foreach (var menuItem in menuItems)
    {
        bool isActive = currentItem.Paths.FullPath.StartsWith(menuItem.FullPath);
    
        // do code 
    }
    

    Just a word of warning, since each menu item now need code to run in order to determine state, this will make your menu component difficult to cache, resulting caching too many variations or caching per page. You would be better to move this logic into Javascript to set the menu state using the current page URL, this will allow your component to be cached once for all pages.