Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • marie 22 posts 132 karma points
    Jan 23, 2018 @ 21:28
    marie
    0

    Generating content based on a different page's Multi-Node Tree Picker?

    I've successfully pulled information from pages based on whether or not the page references the current page (via a multi-tree node picker). The problem is that, because the code has to list the parents of the nodes with the multi-node tree picker property, I'm getting repeat information.

    For example, I'm on the landing page for a City, looking at Store X existing in that City, and Store X has Product A and Product B -- Store X is listed twice -- once as "Store X: Product A" and once as "Store X: Product B". I want it to be "Store X: Product A & Product B"

    Resource Node (Targeted with a Content Picker)
            --- Store X
            ------ Product A (contains necessary "City" info)
            ------ Product B (contains necessary "City" info)
    

    I'm not allowed to touch the structure of the Umbraco setup.

    Basically, I'd like to 1) get the Current Page to recognize a Multi-Node Tree Picker selection two levels down from the Resource Node and use it to determine what gets listed, and 2) loop only through the Store-level content with the ability to generate the Product content without repetition of the Store content.

    I'm sure I'm missing a very obvious solution here, but rather than staring at the code until I see it, I thought I'd try to get help moving things along.

    EDIT: I've replied with a more specific outline of the problem/sample of the code further down the page (second reply; the first one is a mess).

  • Mark 91 posts -18 karma points
    Jan 24, 2018 @ 11:07
    Mark
    0

    Show us the code you are using for the list, we can show you how to amend it to get the results you need.

  • marie 22 posts 132 karma points
    Jan 25, 2018 @ 14:13
    marie
    0

    It's code that gets the job done, but it's not good code. I was hoping someone else had something a bit cleaner.

        @{
    DynamicNode currentPage = new DynamicNode(Model.Id);
    DynamicNode rNode = new DynamicNode(AppLogic.GetSiteConfigValueInt("ResourceNode"));
    
    if (AppLogic.IsDNodeValid(currentPage) && AppLogic.IsDNodeValid(rNode))
    {
        DynamicNodeList items = new DynamicNodeList(rNode.Descendants().Where(x => x.NodeTypeAlias == "ResultPage").ToList());
    
    
    
        foreach (DynamicNode item in items)
        {
            List<DynamicNode> lList = new List<DynamicNode>(AppLogic.GetMultiTreeNodesFromCSV(item.GetPropertyValue("location")));
            List<DynamicNode> cList = new List<DynamicNode>(AppLogic.GetMultiTreeNodesFromCSV(item.GetPropertyValue("selectCategory")));
    
    
    
                foreach (DynamicNode cat in cList)
                {
    
                    foreach (DynamicNode l in lList.Where(x => x.Id.ToString() == (currentPage.Id.ToString())).Distinct())
                    {
    
                    }
                }
    
        }
    }
    
  • Mark 91 posts -18 karma points
    Jan 25, 2018 @ 16:51
    Mark
    0

    Hey Marie

    It is difficult to say where the issue is occurring as I cant relate your lists to your City/Store/Product objects.

    Also you have a few areas you could clean things up but, as a quick dirty hack try creating a new list of the results list using Distinct().

    If I understand your code:

    var dedupeList = items.Distinct();
    

    Should return a new list with no duplicate stores? If not try Distinct on the list that is causing the problem.

    As an aside, be careful when using .Descendants as this can be costly. If you know the Node Alias, try just searching up and down locally using Parent/Child.

  • marie 22 posts 132 karma points
    Jan 25, 2018 @ 20:58
    marie
    0

    Yeah, I was afraid that code wouldn't be helpful. Here's my attempt to clean it up to the basics:

    DynamicNode currentPage = new DynamicNode(Model.Id);
    
    DynamicNode rNode = new DynamicNode(AppLogic.GetSiteConfigValueInt("ResourceNode"));
    
    if (AppLogic.IsDNodeValid(currentPage) && AppLogic.IsDNodeValid(rNode))
    {
        DynamicNodeList PRODUCTS = new DynamicNodeList(rNode.Descendants().Where(x => x.NodeTypeAlias == "ProductPage").ToList());
    
        foreach (DynamicNode PRODUCT in PRODUCTS)
        {
            List<DynamicNode> CITYlist = new List<DynamicNode>(AppLogic.GetMultiTreeNodesFromCSV(PRODUCT.GetPropertyValue("location")));
    
            foreach (DynamicNode CITY in CITYlist.Where(x => x.Id.ToString() == (currentPage.Id.ToString())))
            {
                <p>@PRODUCT.Parent.Name</p>  /*result: the name of the first-level Store */
                <p>@PRODUCT.Name</p>  /*result: the name of the second-level Product*/
            }
    
        }
    }
    

    That second foreach loop correctly eliminates the "Product" pages that don't coincide with the Current Page based on their multi-node tree picker data on associated Cities. The first foreach loop allows a reference point for the second foreach loop.

    If there are seven results based on there being seven other pages on the site that reference this City, that's cool -- but the generated content on the page looks like:

    • Store A
    • Product A
    • Store A
    • Product B
    • Store A
    • Product C
    • Store B
    • Product A
    • Store B
    • Product C
    • Store C
    • Product A
    • Store C
    • Product C

    Which does have the right, relevant information, but isn't presented in the best way. I don't think the code can use Distinct because it's seeing all those combinations of Stores and Products as distinct (there is no duplicate of Store C holding Product C in this City), though it doesn't look distinct when rendered on the page.

  • Steve Morgan 1346 posts 4453 karma points c-trib
    Jan 31, 2018 @ 15:13
    Steve Morgan
    0

    Hi,

    You have some confusing logic and some confusing data structure there.

    I think what you need to do is a two stage approach - one to build up your data and then another to output it. First create a dictionary with a list of products underneath. As you loop through your city(?) you add the store(s) from the picker to the dictionary if it's not there and the products to the relevant store.

    Then loop through to output that.

    It's something like this:

    var storesAndProducts = new Dictionary

    // loop through and store to our dictionary - basically we look for the city as the key
    // if it's not there add it first then always add the product. 
    foreach(var city in cityList)
    {
        // if this cities' store(!?) is not in the Dictionary then add it
        if(!storesAndProducts.ContainsKey(city))
        {
            storesAndProducts.Add(city, new List<string>());
        }
    
        // get the product list for this store...
        var productList = storesAndProducts[city];
    
        // now add the current product to it
        productList.Add(product);
    }
    
    // Now we have this we can output each store with a concatenated list of products (here we use a list)
    foreach(var storeAndProductList in storesAndProducts)
    {
        <h3>@storeAndProductList.Key</h3>
        <ul>
            @foreach(var product in storeAndProductList.Value)
            {
                <li>@product</li>
            }
        </ul>
    }
    

    Sorry I can't amend your code - there's just too much going on in there but hopefully the above will make sense.

    Steve

Please Sign in or register to post replies

Write your reply to:

Draft