BuzzingPixel

Ansel for Craft

Ansel for EE

Treasury

Construct

Category Construct

Dashboard (open an issue here)

All Issues

My Issues

News Contact
Log in

Logged in as

Licenses Purchases Profile Change Password Billing Portal Admin
Log Out
Software
Ansel for Craft Ansel for EE Treasury Construct Category Construct
Support
Dashboard (open an issue here) All Issues My Issues
News Contact
Log in
Logged in as:
Licenses Purchases Profile Change Password Billing Portal Log Out
Dashboard All Issues My Issues
Support Dashboard
  1. Home
  2. Home
  3. Support Dashboard
  4. View Issue

Getting the node ID for a parent of a parent...

#185 opened by SanctusMediaLtd

Subscribe

Details

See Comments

Public Issue

Visibility: Public
13 replies
Last reply by TJ Draper
Created 8/13/2020 8:11 AM
Updated 8/13/2020 11:50 AM
Construct 2.1.1
CMS Version: EE 5.3.2
PHP Version: 7.2.26
Additional Environment Details:

N/A

Description

I have a menu structure that's 3 levels deep. When showing something on the third level, I want a menu that shows everything on the second level inclusive – but NOT the very top level of the entire menu.

From the docs, there doesn't seem to be an easy way of doing this? Or am I missing something?

O.

Replies

  • TJ Draper

    Replied 8/13/2020 10:15 AM, Edited 8/13/2020 11:50 AM

    If you want everything on level 2, you could do something like this:

    {exp:construct:nodes tree_id="SOME_ID" parent_id="SOME_PARENT_ID"}
        {!-- Template Code Here --}
    {/exp:construct:nodes}
    

    But I may be misunderstanding what you're trying to do.

  • SanctusMediaLtd

    Replied 8/13/2020 10:21 AM, Edited 8/13/2020 11:50 AM

    I can't hardcode the parent_id because its a single template.

    Essentially, when a user clicks from the level 1 (the site's top menubar), I'm showing everything under that top level parent in a side bar navigation. For level 2 items, parent_id='{construct_route:node_parent_id}' works fine because the parent node happens to be the level 1 node.

    When I click a level 3 node, I only see the level 3 nodes in the right-hand bar, because the parent node of level 3 is on level 2. I need to see levels 2 and 3 in that sidebar, regardless of which level the active node is in...

    I hope that makes sense.

    O.

  • SanctusMediaLtd

    Replied 8/13/2020 10:24 AM, Edited 8/13/2020 11:50 AM

    (In other words, I need the level 1 parent ID, regardless of how many levels down I am, for the current node)

  • TJ Draper

    Replied 8/13/2020 10:39 AM, Edited 8/13/2020 11:50 AM

    Can you utilize the node_slug from a segment?

  • SanctusMediaLtd

    Replied 8/13/2020 10:46 AM, Edited 8/13/2020 11:50 AM

    I'm not sure how node_slug would help me :S

    here's what I have:

    {exp:construct:nodes
        tree_id="1"
        parent_id="{construct_route:node_parent_id}"
    }
        {if construct:level_count == 1}
            <ul class="pager">
        {/if}
    
            <li class="{if construct_route:node_id == construct:node_id}active{/if}"><a href="/{construct:node_full_route}">{construct:node_name}</a></li>
        
        {if construct:has_children}
            <ul class="kids">
        {/if}
        {construct:children}
        {if construct:has_children}
            </ul>
        {/if}
    
        {if construct:level_count == construct:level_total_results}
            </ul>
        {/if}
    {/exp:construct:nodes}
    

    So parent_id param almost needs a top_level_parent_id of sorts to make sure I always maintain the view of levels 2, 3, and beyond?

  • SanctusMediaLtd

    Replied 8/13/2020 10:46 AM, Edited 8/13/2020 11:50 AM

    Apologies for that last comment. Markdown not working as expected:

    {exp:construct:nodes tree_id="1" parent_id="{construct_route:node_parent_id}"}
        {if construct:level_count == 1}
            <ul class="pager">
        {/if}
    
            <li class="{if construct_route:node_id == construct:node_id}active{/if}"><a href="/{construct:node_full_route}">{construct:node_name}</a></li>
        
        {if construct:has_children}
            <ul class="kids">
        {/if}
        {construct:children}
        {if construct:has_children}
            </ul>
        {/if}
    
        {if construct:level_count == construct:level_total_results}
            </ul>
        {/if}
    {/exp:construct:nodes}
    
  • TJ Draper

    Replied 8/13/2020 10:55 AM, Edited 8/13/2020 11:50 AM

    If you have access to the node slug of the parent in the URL, you could do something like this:

    {exp:construct:nodes tree_id="1" node_slug="{segment_x}"}
        {if construct:node_level > 1}
            {if construct:level_count == 1}
            <ul class="pager">
            {/if}
                <li class="{if construct_route:node_id == construct:node_id}active{/if}">
                    <a href="/{construct:node_full_route}">{construct:node_name}</a></li>
                    {if construct:has_children}
                        <ul class="kids">
                            {construct:children}
                        </ul>
                    {/if}
                </li>
            {if construct:level_count == construct:level_total_results}
            </ul>
            {/if}
        {/if}
    {/exp:construct:nodes}
    
  • SanctusMediaLtd

    Replied 8/13/2020 10:59 AM, Edited 8/13/2020 11:50 AM

    I'm sorry, but nowhere in your response – or your documentation - have you explained what the node_slug parameter actually does...?

    Unfortunately though, it returns absolutely nothing in the format you've suggested.

  • TJ Draper

    Replied 8/13/2020 11:09 AM, Edited 8/13/2020 11:50 AM

    > Unfortunately though, it returns absolutely nothing in the format you’ve suggested.

    Can you elaborate? I'm happy to help if I can but I don't know what "nothing in the format you’ve suggested" means. Does it mean that the tag is not outputting anything?

    I realize the documentation could be more clear on node_slug. I'm sorry about that. It retrieves a node based on slug. So if you have the path to your level 3 node in the URL, one of those segments should be the slug. It's been a while since I've been in the code, it's possible that it won't retrieve children, might have to experiment a little. If it doesn't retrieve children, you could use a embed template to pass in the that ID to another construct tag in that embed.

    So since in my example I did {if construct:node_level > 1}, if you're not seeing any output from that tag, that may be why.

  • SanctusMediaLtd

    Replied 8/13/2020 11:24 AM, Edited 8/13/2020 11:50 AM

    Yes; I mean the tag returns nothing when the code is used in the way you've shown.

    > It retrieves a node based on slug. So if you have the path to your level 3 node in the URL, one of those segments should be the slug.

    I'm not sure I understand. Are you saying that if I pass in {segment_1} into the node parameter, it would use that as the "starting point"?

    I've tried applying your code verbatim, using segments 1 and 2 (and 3) on both level 2 and level 3 pages and the tag still has no output.

    I've tried applying the node_slug parameter to my existing tags, and that also doesn't work.

    It would seem we've maybe reached an impasse, as I thought this would maybe be "out-of-the-box" functionality.

  • TJ Draper

    Replied 8/13/2020 11:31 AM, Edited 8/13/2020 11:50 AM

    There's no doubt that this is missing functionality and I'm taking notes for what can be added in the next major version. That said, I have no doubt that what you're trying to do is possible with a little templating.

    Passing a segment into the node_slug parameter will retrieve a node based on the segment. Which is why, if the top level node's slug is in the URL, it could be useful. As I mentioned, my memory is unclear on whether it also will retrieve that node's children for output (and I'm not able to dig into that code or replicate a test situation right at this moment). If it doesn't retrieve the children, it may explain why my sample code is not producing any output since I had a conditional in there to limit to level 2 or higher.

    I understand though if you don't want to pursue this further.

    If you do want to pursue it, I would suggest maybe taking everything out from inside of the tag in my sample code and just outputting the node name to see if it's getting anything at all.

  • SanctusMediaLtd

    Replied 8/13/2020 11:38 AM, Edited 8/13/2020 11:50 AM

    Understood. I tried just running a simple loop (moving the UL element to the outside)...

    {exp:construct:nodes tree_id="1" node_slug="{segment_1}"}
    		            <li class="{if construct_route:node_id == construct:node_id}active{/if}">
    		                <a href="/{construct:node_full_route}">{construct:node_name}</a></li>
    		                {if construct:has_children}
    		                    <ul class="kids">
    		                        {construct:children}
    		                    </ul>
    		                {/if}
    		            </li>
    				{/exp:construct:nodes}
    

    ... that returns just the node specified by node_slug and nothing else; no children, as you thought might be the case.

    Embeds will put additional load on every page, which I'd rather avoid.

    I'm sorry to say I think we'll need to rip out Construct and put in NavEE, which can do what I need it to, in the timeframe we have remaining :( (We tried Construct because your UI is much cleaner and easier for our clients)

    For your own R&D, they have a start_nav_from_parent parameter, with a few related parameters to set the starting point and show as much or as little of the sub-navigation as required. Additionally, allowing Construct to 'read' the URL to see if it matches a manually entered URL would be good (again, NavEE can do this) rather than every EE template having to be in a Construct template.

    Thanks nonetheless for your help.

  • TJ Draper

    Replied 8/13/2020 11:50 AM

    Understood. I'm sorry about that.

    The only comment I'll offer — and I'm not suggesting you should reconsider, because I totally understand where you're coming from and it doesn't solve the root (heh) of the problem — is this: As someone who's spent a lot of time with EE from a performance perspective, and has helped rescue poorly performing EE sites and presented at conferences on the topic, the load increase from embeds has been severely overstated. The reason they've gotten a bad rap, and what led people to start thinking they were just bad and should not be used is because of what they enable. It's possible to compound tag loops that produce an unseemly amount of heavy queries, which can really bog down page load performance. As an example, let's say you have a channel entries tag that has a limit of 20. Then you put an embed in that loop. That embed has a channel entries tag with a limit of 20. You've just compounded your queries by a large amount. You can see where this gets out of hand. That's where embeds got a bad rap. As far as the burden of an embed, of course there is some, but it's not much by itself. It's barely noticeable, in fact. If you had embeds of just HTML, you'd have to have literally hundreds of embeds before you noticed a speed slowdown.

    But, like I said, that doesn't solve the real problem here, which is the deficiency of ways to get nodes in Construct and the potential unwieldiness of wrangling multiple templates just for the correct output of Construct's tags.

Use Markdown for formatting

Details

See Comments

Public Issue

Visibility: Public
13 replies
Last reply by TJ Draper
Created 8/13/2020 8:11 AM
Updated 8/13/2020 11:50 AM
Construct 2.1.1
CMS Version: EE 5.3.2
PHP Version: 7.2.26
Additional Environment Details:

N/A

Cookie Policy
Privacy Policy
Terms of Service

© 2023 BuzzingPixel, LLC. All rights reserved.