{menu} mit first- und last-Klassen?

Hilfe zu Modulen und Tags
Post Reply
mike-r

{menu} mit first- und last-Klassen?

Post by mike-r »

Ich bin mir sicher, dass ich hier schon einmal eine Diskussion incl. Lösung dazu gesehen hatte, ich finde sie nur leider nicht mehr.

Ich möchte in den Menüs das erste und letzte Kind mit einer Klasse versehen, also:

Code: Select all

<ul id="menu">
<li  id="first">Menüpunkt 1</li>
<li>Menüpunkt 2</li>
...
<li  id="last">letzter Menüpunkt</li>
...
Wie bewerkstellige ich das?
NaN

Re: {menu} mit first- und last-Klassen?

Post by NaN »

Ich weiß nicht, ob das das ist was Du suchst, aber hier gings letztens um fast genau das gleiche:

http://forum.cmsmadesimple.org/index.ph ... 317.0.html

Dort wurde der letzte Menüpunkt mit Hilfe des Extra-Feldes mit einer zusätzlichen CSS-Klasse versehen.
Im Menu-Template wurde dann mit Smarty der Inhalt des Extra-Feldes geprüft und dieser dann als Klasse verwendet.
Das ließe sich auch für den ersten Menüpunkt anwenden.
Muss man allerdings immer manuell eingeben.
Eine Möglichkeit, das komplett zu automatisieren (anhand einer Abfrage nach Hierarchie oder mit Smarty-Modifikatoren etc.) habe ich noch nicht herausgefunden.
mike-r

Re: {menu} mit first- und last-Klassen?

Post by mike-r »

Ah super, danke, den Thread meinte ich.
Sonya

Re: {menu} mit first- und last-Klassen?

Post by Sonya »

NaN wrote: Eine Möglichkeit, das komplett zu automatisieren (anhand einer Abfrage nach Hierarchie oder mit Smarty-Modifikatoren etc.) habe ich noch nicht herausgefunden.
Mit smarty geht es, wenn name in foreach hinzugefügt wird. Hier ist die Doku http://www.smarty.net/manual/en/languag ... oreach.php. Und hier ist ein kleines Beispiel:

Code: Select all

{foreach from=$nodelist item=node name=menu}
{if $smarty.foreach.menu.first}<!-- Formatierung für first -->{/if}
<a href="{$node->url}" {if $node->target ne ""} target="{$node->target}"{/if}> {$node->menutext} </a>
{if $smarty.foreach.menu.last}<!-- Formatierung für last -->{/if}
{/foreach}
lume

Re: {menu} mit first- und last-Klassen?

Post by lume »

Danke für das Beispiel mit Smarty, aber leider produziert der Menumanager ja nur ein lineares Array, in dem alle Menüeinträge untergebracht sind. Als Folge funktioniert $smarty.foreach.menu.first bzw. last nur auf der obersten Ebene des Menüs. Ich möchte aber auf den unteren Ebenen ebenfalls eine "last"-Klasse setzen. Also quasi dann, wenn der nächste Eintrag im Loop eine kleinere $node->depth hat, als der aktuelle.
Habt Ihr dazu auch einen genialen smary Tip?
NaN

Re: {menu} mit first- und last-Klassen?

Post by NaN »

Ein verschachteltes Array hätte in diesem Falle mit Smarty auch keinen Sinn, da mit Smarty - soweit ich weiß - keine Rekursion möglich ist.
($nodelist ist übrigens ein Objekt, kein Array)
Für die Klasse "first" hast Du die Lösung ja schon gefunden.
Einfach prüfen, ob $node->depth größer ist als $node->prevdepth.

Für "last" ist es nicht ganz so einfach, da es leider keine Möglichkeit gibt schon im Vorfeld das nachfolgende Element zu prüfen.
Dazu fehlen einfach die nötigen Variablen im $nodelist-Objekt.
Daher hab ich mich der Smarty Funktion {counter} bedient.
{counter} zählt innerhalb einer {foreach}-Schleife einfach von Eins bis Ende.
Da der Index im Array mit Null beginnt, hat man mit {counter } schon den Index des nachfolgenden Elements.
Somit kann man mit

Code: Select all

{$nodelist[NÄCHSTER INDEX]->depth}
auf die Eigenschaften des nachfolgenden Elements zugreifen.

Hab das ganze mal am Simple_Navigation Template probiert:

Code: Select all

{if $count > 0}
<ul>
{foreach from=$nodelist item=node name=item}

{counter assign=nextindex}

{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->current == true}
<li class="currentpage{if ($node->depth > $node->prevdepth) || $smarty.foreach.item.first} first{elseif $smarty.foreach.item.last || $nodelist[$nextindex]->depth < $node->depth} last{/if}">
<h3><dfn>Current page is {$node->hierarchy}: </dfn>{$node->menutext}</h3>

{elseif $node->parent == true}
<li class="activeparent{if ($node->depth > $node->prevdepth) || $smarty.foreach.item.first} first{elseif $smarty.foreach.item.last || $nodelist[$nextindex]->depth < $node->depth} last{/if}"><a class="activeparent" href="{$node->url}"{if $node->accesskey != ''} accesskey="{$node->accesskey}"{/if}{if $node->tabindex != ''} tabindex="{$node->tabindex}"{/if}{if $node->titleattribute != ''} title="{$node->titleattribute}"{/if}><dfn>{$node->hierarchy}: </dfn>{$node->menutext}</a>

{elseif $node->type == 'sectionheader'}
<li class="sectionheader{if ($node->depth > $node->prevdepth) || $smarty.foreach.item.first} first{elseif $smarty.foreach.item.last || $nodelist[$nextindex]->depth < $node->depth} last{/if}">{$node->menutext}

{elseif $node->type == 'separator'}
<li class="separator{if ($node->depth > $node->prevdepth) || $smarty.foreach.item.first} first{elseif $smarty.foreach.item.last || $nodelist[$nextindex]->depth > $node->depth} last{/if}" style="list-style-type: none;"> <hr />

{else}
<li{if ($node->depth > $node->prevdepth) || $smarty.foreach.item.first} class="first"{elseif $smarty.foreach.item.last || $nodelist[$nextindex]->depth < $node->depth} class="last"{/if}>
<a 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->target != ''} target="{$node->target}"{/if}><dfn>{$node->hierarchy}: </dfn>{$node->menutext}</a>

{/if}

{/foreach}
{repeat string="</li></ul>" times=$node->depth-1}</li>
</ul>
{/if}
Last edited by NaN on Wed May 27, 2009 3:48 pm, edited 1 time in total.
lume

Re: {menu} mit first- und last-Klassen?

Post by lume »

Der Trick mit counter ist wirklich nett! Ich habe mir etwas umständlicher mit

Code: Select all

{math equation="x + 1" x=$smarty.foreach.menu.index assign="next" }
geholfen. Dennoch Danke für die Hilfe!
konsument
Forum Members
Forum Members
Posts: 137
Joined: Thu Oct 26, 2006 9:20 am
Location: Dresden - Saxony - Germany

Re: {menu} mit first- und last-Klassen?

Post by konsument »

Hi Zusammen,

habe genau das gleiche Problem und nach stundenlangem Suchen glücklicherweise diesen Thread gefunden  :D

Das Template von NaN funktioniert fast einwandfrei. Nur leider wird in der ersten Liste der letzte Punkt nicht mit "last" geschmückt. Woran liegt das?

@ Lume

Kannst du vielleicht mal dein Template posten?
lume

Re: {menu} mit first- und last-Klassen?

Post by lume »

Hi konsument,
auf die Gefahr hin, dass das hier jetzt nicht mehr gebraucht wird, werde ich deiner Bitte mal nachkommen:

Code: Select all

{* CSS classes used in this template:
.activeparent - The top level parent when a child is the active/current page
li.active0n h3 - n is the depth/level of the node. To style the active page for each level separately. The active page is not clickable.
.clearfix - Used for the unclickable h3 to use the entire width of the li, just like the anchors. See the Tools stylesheet in the default CMSMS installation.
li.sectionheader h3 - To style section header
li.separator - To style the ruler for the separator *} 


{if $count > 0}
<ul>
{foreach from=$nodelist item=node name=menu}
{assign var='class' value=""}
{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}


{math equation="x + 1" x=$smarty.foreach.menu.index assign="next" }
{if $node->depth > $node->prevdepth}
  {assign var='class' value="first"}
{elseif $smarty.foreach.menu.last}
  {assign var='class' value="last"}
{elseif $nodelist[$smarty.foreach.menu.index]->depth > $nodelist[$next]->depth}
  {assign var='class' value="last"}
{/if}

{if $node->current == true}
  {assign var='class' value="currentpage $class"}
  {if $node->haschildren == true}
       {assign var='class' value="haschildren $class"}
  {/if}
  <li class="{$class}"><h3><dfn>Current page is {$node->depth}: </dfn>  {$node->menutext}</h3>

{elseif $node->parent == true}
  {assign var='class' value="activeparent $class"}
<li class="{$class}"><a class="activeparent" href="{$node->url}"{if $node->accesskey != ''} accesskey="{$node->accesskey}"{/if}{if $node->tabindex != ''} tabindex="{$node->tabindex}"{/if}{if $node->titleattribute != ''} title="{$node->titleattribute}"{/if}><dfn>{$node->depth}: </dfn>{$node->menutext}</a>

{elseif $node->type == 'sectionheader'}
<li class="sectionheader">{$node->menutext}

{elseif $node->type == 'separator'}
<li class="separator" style="list-style-type: none;"> <hr />

{else}
<li class="{$class}"><a 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->target != ''} target="{$node->target}"{/if}><dfn>[{$node->depth}] </dfn>{$node->menutext}</a>

{/if}

{/foreach}
{repeat string="</li></ul>" times=$node->depth-1}</li>
</ul>
{/if}
ich hoffe das hilft.

Gruß
Ludger (lume)
sp
New Member
New Member
Posts: 5
Joined: Sun Aug 08, 2010 4:17 pm

Re: {menu} mit first- und last-Klassen?

Post by sp »

ich hab mal ne frage zu nan's vorschlag. dieser funktioniert super.

wenn man dieses menutemplate aber 2x in die seite einbaut (zb. footermenu) sind im zweiten menu alle klassen nach "first", "last"-klassen. und nicht mehr nur die letzte.

ich hab jetzt ein bisschen rumprobiert, hab aber die ursache nicht gefunden.
NaN

Re: {menu} mit first- und last-Klassen?

Post by NaN »

Könnte an der Variablen liegen, die durch {counter} erzeugt wird.
Bin mir da nicht ganz sicher.
Probier aber lieber mal lieder die Idee von lume.
Die sieht mir etwas eleganter aus.
Ohne irgendwelche zusätzlichen Variablen, sondern nur mit dem, was die Smarty-Engine so bietet.
Post Reply

Return to “Module und Tags”