Search code examples
c#sitecoresitecore7

Sitecore 7 - Maintain navigation based on specific parent item throughout subpages


This is kind of an odd question to phrase, but I think it's easier to understand if I explain: I haven't worked in Sitecore 7 in quite a while and am working on building side navigation for the subpages. This is how the subpages are setup in the site tree:

  • Products (level 1)
  • Product Super Category (level 2) (not a page that is viewed on the site--this is more for organization)
  • Product Category (level 3)
  • Product Listing (level 4)
  • Product (level 5)

If I am on the Products landing page, then I get all the product categories (I have completed this functionality already). When I am on a Product Category page, I get all the Product Listings (the children of the Product Category template) (this functionality is working).

When I am on a Product Listing page or a Product page, however, I am confused on how to maintain the same navigation I have featured on the Product Category page. I understand I need to check the parent of the current page I am on, but I am not sure of the best way to do it.

This is what I had started, which works for the Product Category page in that it gets all the Product Listing children and all the Product children.

    private void Page_Load(object sender, EventArgs e)
    {
        var db = Sitecore.Context.Database;
        this.currentItem = Sitecore.Context.Item;

        //get the product
        var productCategoryItem = db.Items.GetItem(this.currentItem.ID);
        var productListings = productCategoryItem.Children
            .Where(d => d.TemplateID.ToString() == productListingTemplateID);

        ProductCategories.DataSource = productListings;
        ProductCategories.DataBind();

    }

     protected void ProductCategories_ItemDataBound(object sender, RepeaterItemEventArgs e)
    {

        var catItem = e.Item.DataItem as Item;
        Repeater categoriesRepeater = e.Item.FindControl("CategoriesRepeater") as Repeater;
        var catProducts = catItem.GetChildren();

        if (catProducts.ToList().Count == 0)
        {
            return;
        }

        categoriesRepeater.DataSource = catProducts;
        categoriesRepeater.DataBind();
    }

UPDATE: This code works the way I want it to but I find it repetitive and not clear enough when I get down to the Product pages. I can't specify a Product item ID or template ID as the products use different templates (don't know why but this is how they were set up. Still, Product pages are children of Product Listing pages, and Product Listing pages are children of Product Category pages, and so on):

  if (currItem.TemplateID.ToString() == productCategoryTemplateID.ToString())
        {
            productCategoryItem = db.Items.GetItem(currItem.ID);
        }
        else
        {
            if (currItem.TemplateID.ToString() == productListingTemplateID.ToString())
            {
                productCategoryItem = db.Items.GetItem(currItem.ParentID);

            }
            else
            {
                productCategoryItem = db.Items.GetItem(currItem.Parent.ParentID);
            }
        }
        var productListings = productCategoryItem.Children
               .Where(d => d.TemplateID.ToString() == productListingTemplateID);

        ProductCategories.DataSource = productListings;
        ProductCategories.DataBind();

While I have ideas on how to do this with if statements, I don't want the code to become repetitive and tedious. Would it be possible to accomplish what I want with some sort of while loop?


Solution

  • It looks like you are trying to create a method that returns the relevant product listings based on your current context item. One option would be to introduce an ancestor query (note that this uses C#6 syntax for string formatting)

    productListings = currItem.Axes.SelectItems($"ancestor-or-self::*[@@templateid='{productCategoryTemplateID}']/*[@@templateid='{productListingTemplateID}']")
    

    The template check at the end of the query is only required if product category items can have children other than product listings