Menu Manager - giving an ID to the first item in the list

For questions and problems with the CMS core. This board is NOT for any 3rd party modules, addons, PHP scripts or anything NOT distributed with the CMS made simple package itself.
Post Reply
liquid
Forum Members
Forum Members
Posts: 59
Joined: Sun Aug 07, 2005 10:20 pm

Menu Manager - giving an ID to the first item in the list

Post by liquid »

I need to get the menu manager to style the first element in the menu list with a different ID than the other menu items. Suggestions on how to accomplish that?

The output should look like this:

Code: Select all

<li id="first"><a href="#">Home</a></li>
<li><a href="#">Our Solution</a></li>
<li><a href="#">Our Partners</a></li>
<li><a href="#">News</a></li>
<li class="active"><a href="#">About Us</a></li>
<li><a href="#">Contact</a></li>
Thank you!
User avatar
myshko
Forum Members
Forum Members
Posts: 102
Joined: Wed Feb 07, 2007 2:36 pm

Re: Menu Manager - giving an ID to the first item in the list

Post by myshko »

Hi liquid,

I've just managed to run into the same problem and with abit of looking into what the menu manager can do I came up with a way to find the first and last nodes of a menu.

Finding the first node was pretty simple using the $node->index parameter.

This will give you the count of this node in the whole menu. So if we want the first node, we simply test it against '0' (as items in the menu begin at 0 not 1).

For example, I used the condition:

Code: Select all


{if $node->index == 0}
<li class="first"> <a href="{$node->url}"> {$node->menutext} </a>

That first line simply says if the nodes index is equal to '0', output the line beneath (which has a class of 'first').

Finding the last node was a little more tricky. For this I noticed there was a '$count' parameter. Count seems to add up all the nodes in total.

So to find the last one, I used:

Code: Select all


{if $node->index == $count-1}
<li class="last"> <a href="{$node->url}" > {$node->menutext} </a>

Which says if the nodes index is equal to the total count minus 1 (as the first item is a 0), output the line beneath which has a class of last. [NOTE: I haven't tested this for menus more than 1 level deep, count may output something different]

This should be enough to get you there. You can set IDs and classes as you like. Remember that if you are adding current states to your links (class="here") you will have to combine the arguments.

For example, if a link was both the current link AND the last link you would use:

Code: Select all


{if $node->current == true && $node->index == $count-1}
<li class="last here"> <a href="{$node->url}"> {$node->menutext} </a>

Again, you can change ID and class names to suit.

As a tip, I'd avoid using IDs unless they are unique. If at some point you have more than one list using 'first' or 'last' as IDs then the page will be invalid. IDs are suitable if you're making an image menu and you need to specifically target an item.

Hope this helps. Apologies if this seemed patronising, I'm trying to explain everything fully in case it helps someone else less experienced. I'll also try and add the examples to the wiki soon. If more detailed examples are need, just ask.

;)
Lateralus
Forum Members
Forum Members
Posts: 40
Joined: Fri Jun 01, 2007 10:49 am

Re: Menu Manager - giving an ID to the first item in the list

Post by Lateralus »

great post thnx!! radar
SINphul
Forum Members
Forum Members
Posts: 23
Joined: Wed Jan 07, 2009 3:24 am

Re: Menu Manager - giving an ID to the first item in the list

Post by SINphul »

HELP! :)

This is indeed great information, but I have a question that is stumping me.  Your method works great assuming the menu you're presenting is only one level deep.  However, as you mention, it doesn't exactly work if you have any additional levels (in my case, my menu goes up to 5 levels deep).

So that said, how would one apply a class of "last" to the last node of the first level, and not the last node of the entire menu count?

The only solution I could come up with was to do something like the following:

Code: Select all

{if $node->index == ($count - $totalChildren )-1}
    <li class="last"...
{/if}
...where $totalChildren would be the total count of child nodes under that specific parent.  The problem is, I'm a bit of a PHP noob and I have no idea how to get that variable declared and assign the children number to it.

Does anyone out there have an easier method to achieve what I'm attempting to do?  Or is there a simple way to get that child count that I am missing?  Thanks for any help!
JohnnyB
Dev Team Member
Dev Team Member
Posts: 731
Joined: Tue Nov 21, 2006 5:05 pm

Re: Menu Manager - giving an ID to the first item in the list

Post by JohnnyB »

This is the menu I use for all of my projects and I added the logic provided by deadhike in the parent links.  I did not test, but it should work:

Code: Select all

{if $count > 0}
<ul id="menu">
{foreach from=$nodelist item=node}
{if $node->depth > $node->prevdepth}

	{repeat string="<ul>" times=$node->depth-$node->prevdepth}
{elseif $node->depth < $node->prevdepth}

	{repeat string="</li></ul>" times=$node->prevdepth-$node->depth}
	</li>
{elseif $node->index > 0}</li>
{/if}
{if $node->depth == 1}
	<li {if $node->index == 0}class="first"{/if}{if $node->index == $count-1}class="last"{/if}><a class="{$node->alias}"{if $node->type != 'sectionheader' and $node->type != 'separator'} href="{$node->url}" {if $node->accesskey != ''}accesskey="{$node->accesskey}" {/if}{if $node->tabindex != ''}tabindex="{$node->tabindex}" {/if}{if $node->titleattribute != ''}title="{$node->titleattribute}"{/if}{if $node->titleattribute == ''}title="{$node->menutext}"{/if}{if $node->target ne ""} target="{$node->target}"{/if}><dfn>{$node->hierarchy}: </dfn>{$node->menutext}</a>
{/if}
{else}
	<li><a {if $node->type != 'sectionheader' and $node->type != 'separator'}href="{$node->url}" {if $node->accesskey != ''}accesskey="{$node->accesskey}" {/if}{if $node->tabindex != ''}tabindex="{$node->tabindex}" {/if}{if $node->titleattribute != ''}title="{$node->titleattribute}"{/if}{if $node->titleattribute == ''}title="{$node->menutext}"{/if}{if $node->target ne ""} target="{$node->target}"{/if}><dfn>{$node->hierarchy}: </dfn>{$node->menutext}</a>
{/if}
{/if}
{/foreach}

	{repeat string="</li></ul>" times=$node->depth-1}</li>
	</ul>
{/if}
These are the lines that should make it work only for top links:

{if $node->depth == 1}
index == 0}class="first"{/if}{if $node->index == $count-1}class="last"{/if}>
"The art of life lies in a constant readjustment to our surroundings." -Okakura Kakuzo

--
LinkedIn profile
--
I only speak/write in English so I may not translate well on International posts.
--
SINphul
Forum Members
Forum Members
Posts: 23
Joined: Wed Jan 07, 2009 3:24 am

Re: Menu Manager - giving an ID to the first item in the list

Post by SINphul »

Hi MMW; thanks so much for the kind response, but unfortunately your code does not work in this case.  The problem is that the $count variable is going to give a total of every node, regardless if your conditional statement is asking for a check of 1 level deep nodes.  By doing that, it just doesn't put a class of "last" on anything at all.  Hopefully that makes sense.

That said, do you or anyone else have any additional suggestions?  Any further assistance would be most appreciated.  Thanks again!
JohnnyB
Dev Team Member
Dev Team Member
Posts: 731
Joined: Tue Nov 21, 2006 5:05 pm

Re: Menu Manager - giving an ID to the first item in the list

Post by JohnnyB »

SINphul wrote: Hi MMW; thanks so much for the kind response, but unfortunately your code does not work in this case.  The problem is that the $count variable is going to give a total of every node, regardless if your conditional statement is asking for a check of 1 level deep nodes.  By doing that, it just doesn't put a class of "last" on anything at all.  Hopefully that makes sense.

That said, do you or anyone else have any additional suggestions?  Any further assistance would be most appreciated.  Thanks again!
Oh right of course.  :-[

Is your last menu item always going to be the same?  if so, what I've done is test for the alias and then assign a class to it.
alias=='Page-Alias-Name-Here"}class="last"{/if}>
"The art of life lies in a constant readjustment to our surroundings." -Okakura Kakuzo

--
LinkedIn profile
--
I only speak/write in English so I may not translate well on International posts.
--
SINphul
Forum Members
Forum Members
Posts: 23
Joined: Wed Jan 07, 2009 3:24 am

Re: Menu Manager - giving an ID to the first item in the list

Post by SINphul »

Unfortunately, the last level 1 parent node will not always be the same, as the content authors will be making constant site changes.  Any other ideas on how to dynamically target this node and apply a class to it?
Post Reply

Return to “CMSMS Core”