开发者

Using LINQ to build Hierarchical Navigation for Repeater

开发者 https://www.devze.com 2023-02-22 04:47 出处:网络
I am trying to output a hierarchical navigation list of items from my CMS as follows: YEAR - MONTH - - ARTICLE 1

I am trying to output a hierarchical navigation list of items from my CMS as follows:

YEAR
- MONTH
- - ARTICLE 1
- - ARTICLE 2

The page is templated so that if you are on the year page you will see:

MONTH
- ARTICLE 1
- ARTICLE 2

Obviously, if you're on the month page you'll just see a link to the articles

I am trying to build a LINQ query to handle the logic, and to then build it within a DataTable to be handled by a Repeater. I am really struggling to get the logic sound so that I can build this in the correct way. Logically, LINQ appeared to be the easiest way to model this, although I am now having second thoughts. This is the code I've come up with to get the years and the necessary data so far.

var linqYears = from year in cont开发者_如何学JAVAextItem.Children
                select new
                {
                    Name = year.Fields["page title"],
                    URI = Sitecore.Links.LinkManager.GetItemUrl(year)
                };

What I need now is to get all months for the selected year, and then all the articles and build them into a repeater; I assume the easiest way to do this is through a DataTable/DataSet?

Any help would be greatly appreciated.

EDIT: To clarify my position:

The item contextItem is the page I am currently on. If I am on the root page and the year page is below me then contextItem.Children will return all children underneath it. For example, given this navigation if I am on ROOT:

ROOT
- YEAR
- - MONTH
- - - ARTICLE 1
- - - ARTICLE 2

Then contextItem.Children will be a collection consisting solely of YEAR


I'm not familiar with your structure but I assume here that year is the same type as contextItem. If so, this would work:

var linqYears = from year in contextItem.Children
                select new
                {
                    Name = year.Fields["page title"],
                    URI = Sitecore.Links.LinkManager.GetItemUrl(year),
                    Months = from month in year.Children
                             select new
                             {
                                 Name = month.Fields["page title"],
                                 URI = Sitecore.Links.LinkManager.GetItemUrl(month),
                                 Articles = from article in month.Children
                                            select new
                                            {
                                                Name = article.Fields["page title"],
                                                URI = Sitecore.Links.LinkManager.GetItemUrl(article)
                                            }
                             }
                };

I'm not sure about the repeater but have you considered using a ListView instead? Unless I'm misstaken you can bind that directly to your anonymous types. That only works if you do this selection inline of course. Otherwise I'd recommend creating a class that contains Name, URI and Children and replace Months and Articles respectively in the above code with Children.

Hope that helps.

EDIT: To make this solution work regardless of your current position in the hierarchy, you could do something like this:

First a class for your pages.

public class PageNode
{
    public string Name { get; set; }
    public Uri URI { get; set; }
    public List<PageNode> Children { get; set; } // This should be done with a private setter, but you get that...
}

Then you need methods similar to this:

public IEnumerable<PageNode> GetChildNodes(IEnumerable<ContextItem> children)
{
    return from c in children
           select new PageNode()
           {
               Name = c.Fields["page name"],
               URI = Sitecore.Links.LinkManager.GetItemUrl(c),
               Children = c.Children.Any() ? GetChildNodes(c.Children) : null
           };
}

public PageNode LoadNode(ContextItem item)
{
    return new PageNode()
           {
               Name = item.Fields["page name"],
               URI = Sitecore.Links.LinkManager.GetItemUrl(item),
               Children = item.Children.Any() ? GetChildNodes(item.Children) : null
           };
}
0

精彩评论

暂无评论...
验证码 换一张
取 消