Page 1 of 1

Menu template with class="first last" for each node

Posted: Mon Dec 05, 2011 5:08 pm
by rooon
Extra classes available in the menu template:
.mN - Number N is the depth of this node. Examples: m3, m12
.first - This node is the first node of this depth.
.last - This node is the last node of this depth.

How to use:

1. Create an UDT with name: menu_classes

Code: Select all

global $smarty;
$nodes=isset($params['nodelist']) ? $params['nodelist'] : false;
// h=hierarchy, d=depth, c=class, t=total
// s=search, i=index, p=position, l=leave
if ($nodes != false){
	$h='';
	$d='';
	foreach ($nodes as $node){
		$h .= $node->hierarchy.' ';
		$d .= $node->depth.' ';
	}
	$ha=explode(' ',trim($h));
	$da=explode(' ',trim($d));
	$c='';
	$t=count($ha);
	for ($i=0; $i<$t; $i++){
		if ($da[$i]==1){
			$s=1+$ha[$i];
		}else{
			$p=strrpos($ha[$i],".");
			$l=1+substr($ha[$i],$p+1);
			$s=substr($ha[$i],0,$p).'.'.$l;
		}
		$c .= 'm'.$da[$i];
		if ($i == 0){$c .= ' first';}elseif ($da[$i] > $da[$i-1]){$c .= ' first';}
		if (array_search($s, $ha) == false){$c .= ' last';}
		if ($i < $t-1){$c .= '|';}
	}
	$ca=explode('|',$c);
	$smarty->assign('firstlast',$ca);
}
2. Menu template:
Put {menu_classes nodelist="$nodelist"} below {if $count > 0}
Note the key=key in {foreach ....}

Code: Select all

{if $count > 0}
{menu_classes nodelist="$nodelist"}
<div id="menuwrapper">
<ul id="primary-nav">
{foreach key=key from=$nodelist item=node}
.....
3. The tag {$firstlast.$key} is now available as class.

Code: Select all

<li class="{$firstlast.$key}">
<a class="{$firstlast.$key}" href="...">
<span class="{$firstlast.$key}">
I am not a good programmer, but it works.
Please let me know if you have a nicer solution.

Re: Menu template with class="first last" for each node

Posted: Mon Dec 05, 2011 10:58 pm
by manuel
Thx for sharing Rooon, nice first post! ;D

To use the {$firstlast.$key} in the <ul class="unli"> generated by the "repeat" in cssmenu.tpl, replace the following:

Code: Select all

{repeat string='<ul class="unli">' times=$node->depth-$node->prevdepth}
by

Code: Select all

{capture assign="firstlastul"}<ul class="unli {$firstlast.$key}">{/capture}
{repeat string="$firstlastul" times=$node->depth-$node->prevdepth}
Note the repeat string now has double quotes to make the string "parsable" by Smarty...

Greetings,
Manuel

Re: Menu template with class="first last" for each node

Posted: Mon Dec 05, 2011 11:11 pm
by manuel
But i'm guessing that's of little use for the intended purpose! Anyway... I guess it's time to stop fiddling around with cmsms for tonight... ::)

Re: Menu template with class="first last" for each node

Posted: Tue Dec 06, 2011 6:24 pm
by rooon
Menu template "cssmenu.tpl.2":

Added:
$node->first / $node->last are included in core of latest version
End Added:

Code: Select all

{*
.unli - Each sub <ul> of the menu (not the top <ul>)
.mN - The depth N of each <ul> or node. Ex. m1, m7  (ul, li, a)
.first - The first node of the corresponding depth  (li, a)
.last - The last node of the corresponding depth  (li, a)
.parent - Node is not active and has no active child (any level)  (li, a)
.menuparent - Node has children  (li, a)
.menuactive - Node is active or parent of active child (any level)  (li, a)
.sectionheader - Node is a sectionheader  (li, a)
.separator - Node is a separator  (li, hr)
*}
{assign var='number_of_levels' value=10000}
{if isset($menuparams.number_of_levels)}
{assign var='number_of_levels' value=$menuparams.number_of_levels}
{/if}
{if $count > 0}
{menu_classes nodelist="$nodelist"}
<ul class="m1">
{foreach key=key from=$nodelist item=node}
{if $node->depth > $node->prevdepth}
{capture assign="firstlastul"}<ul class="m{$node->depth} unli">{/capture}
{repeat string="$firstlastul" 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->parent == true or $node->current == true}
{assign var='classes' value='menuactive'}
{if $node->parent == true}
{assign var='classes' value='menuactive menuparent'}
{/if}
{if $node->children_exist == true and $node->depth < $number_of_levels}
{assign var='classes' value=$classes|cat:' parent'}
{/if}
<li class="{$firstlast.$key} {$classes}">
<a class="{$firstlast.$key} {$classes}" 
{elseif $node->type == 'sectionheader' and $node->haschildren == true}
<li class="{$firstlast.$key} menuparent sectionheader">
<a class="{$firstlast.$key} menuparent sectionheader" ><span>{$node->menutext}</span></a>
{elseif $node->type == 'sectionheader'}
<li class="{$firstlast.$key} sectionheader">
<a class="{$firstlast.$key} sectionheader" ><span>{$node->menutext}</span></a>
{elseif $node->type == 'separator'}
<li class="{$firstlast.$key} separator"><hr class="separator" />
{elseif $node->children_exist == true and $node->depth < $number_of_levels and $node->type != 'sectionheader' and $node->type != 'separator'}
<li class="{$firstlast.$key} menuparent">
<a class="{$firstlast.$key} menuparent" 
{else}
<li class="{$firstlast.$key}">
<a class="{$firstlast.$key}" 
{/if}
{if ($node->type != 'sectionheader' and $node->type != 'separator') or $node->parent == true or $node->current == true }href="{$node->url}"{if $node->titleattribute != ''} title="{$node->titleattribute}"{/if}{if $node->target} target="{$node->target}"{/if}{if $node->accesskey != ''} accesskey="{$node->accesskey}"{/if}{if $node->tabindex != ''} tabindex="{$node->tabindex}"{/if}><span>{$node->menutext}</span></a>{/if}
{/foreach}
{repeat string='</li></ul>' times=$node->depth-1}</li></ul>
{/if}
Any suggestions to improve? Please let me know.