Zum Inhalt springen

Menü in 2 Teile teilen

Erstellt am 24. August 2010 · 3 Antworten · letzte Antwort am 3. März 2011

Tags: Frage

thomax ·

Hallo,

ich suche eine Lösung, um ein Menü abhängig von der aktuellen Seite in zwei Teile zu teilen, sodass sich folgende Möglichkeit ergibt:

Wenn ich auf Seite 1 bin:
(Menüpunkt 1)
Seiteninhalt Seite 1
Menüpunkt 2
Menüpunkt 3
Menüpunkt 4
Menüpunkt 5

Wenn ich auf Seite 2 bin:
Menüpunkt 1
(Menüpunkt 2)
Seiteninhalt Seite 2
Menüpunkt 3
Menüpunkt 4
Menüpunkt 5

Wenn ich auf Seite 3 bin:
Menüpunkt 1
Menüpunkt 2
(Menüpunkt 3)
Seiteninhalt Seite 3
Menüpunkt 4
Menüpunkt 5

Wenn ich auf Seite 4 bin:
Menüpunkt 1
Menüpunkt 2
Menüpunkt 3
(Menüpunkt 4)
Seiteninhalt Seite 4
Menüpunkt 5

Wenn ich auf Seite 5 bin:
Menüpunkt 1
Menüpunkt 2
Menüpunkt 3
Menüpunkt 4
(Menüpunkt 5)
Seiteninhalt Seite 5

Das ganze sollte dynamisch funktionieren, um ein späteres Hinzufügen oder Entfernen von Seiten im Seitenbaum zu ermöglichen. Momentan habe ich es pro Unterseite per Condition gelöst, was zwar funktioniert, jedoch diese dynamik verhindert. Ob der jeweils aktuelle Menüpunkt (in Klammern) gezeigt wird oder nicht, spielt keine große Rolle, da ich diesen ggf. aus dem Seitentitel generieren und per TS von Hand hinzufügen kann.

Basierend auf diesem Beitrag:
#89692

und der Lösung unter:
http://www.typo3wizard.com/de/snippets/menus/menue-dynamisch-in-2-teile-aufteilen.html

habe ich einen TypoScript-Schnipsel, welcher mein Menü in zwei Teile teilt:

lib.naviabove = COA
lib.naviabove {
  10 = HMENU
  10.special = directory
  10.special.value = 1
  10.1 = TMENU
  10.1 {
    wrap = <div>1.teil<br>|</div>
    NO {
      stdWrap.cObject = COA
      stdWrap.cObject {
        10 = TEXT
        10.field = title
        if.value.data = register:count_HMENU_MENUOBJ
        if.negate = 1
        if.isLessThan.prioriCalc = 1
        if.isLessThan.cObject = TEXT
        if.isLessThan.cObject.insertData = 1
        if.isLessThan.cObject.value = ({register:count_menuItems}+1)/2
        wrap = |<br>
      }
    }
  }
}

lib.navibeneath = COA
lib.navibeneath {
  10 = HMENU
  10.special = directory
  10.special.value = 1
  10.1 = TMENU
  10.1 {
    wrap = <div>2.teil<br>|</div>
    NO {
      stdWrap.cObject = COA
      stdWrap.cObject {
        10 = TEXT
        10.field = title
        if.value.data = register:count_HMENU_MENUOBJ
        if.isLessThan.prioriCalc = 1
        if.isLessThan.cObject = TEXT
        if.isLessThan.cObject.insertData = 1
        if.isLessThan.cObject.value = ({register:count_menuItems}+1)/2
        wrap = |<br>
      }
    }
  }
}

Anhand der Zeile:

if.isLessThan.cObject.value = ({register:count_menuItems}+1)/2

wird die Gesamtmenge der Menüeinträge durch zwei geteilt und im ersten Teilmenü die erste und im zweiten Teilmenü die zweite Hälfte der Menüeinträge angezeigt.

Wie kann ich das Skript nun modifizieren, um die Teilung der Menüpunkte nicht in der Mitte, sondern anhand der gerade aktiven Seite vorzunehmen? Sämtliche Versuche die entsprechende Zeile (oder andere Zeilen) anzupassen, sowie mehr als 6 Stunden Recherche in diversen Büchern, Foren und bei Google haben leider bei diesem Problem nicht geholfen.

Hat hier Jemand einen Tipp?

Vielen Dank!
Thomax

igorshmigor ·

ich würde es mit einem billigen Trick lösen

lib.naviabove = COA
lib.naviabove {
  10 = HMENU
  10.special = directory
  10.special.value = 1
  10.1 = TMENU
  10.1 {
    wrap = <div>1.teil<br>|--></div>
    NO.wrap=|<br />
    ACT=1
    ACT.wrap=|<br /><!--
  }
}
lib.navibelow<lib.naviabove
lib.navibelow.10.1.wrap=<div>2.Teil<br><!--|</div>
lib.navibelow.10.1.ACT.wrap=|-->

Ich habe das noch nicht getestet, sollte aber funktionieren.
Die Idee ist, dass im ersten Teil alles ab der aktuellen Seite auskommentiert wird, und im zweiten Teil alles bis zur aktuellen Seite.

thomax ·

Hallo!

Vielen Dank für die Antwort! Deine Idee mithilfe der Schleifendurchläufe einfach alles ab nach dem aktiven Menüpunkt bis zum Ende auszukommentieren, hat mich nochmal zum weiterrecherchieren mit neuen Stichwörtern gebracht. Gutes Um-die-Ecke-Denken 🙂

Ich habe dadurch unter folgendem Thread eine anpassbare Lösung gefunden, die allerdings auch noch etwas "unsauber" ist:
#71117

Angepasst auf meine Situation sieht das ganze dann so aus:

lib.naviabove = HMENU
lib.naviabove {
  special = directory
  special.value = 1
  1 = TMENU
  1 {
    noBlur = 1
    NO {
      allWrap.cObject = CASE
      allWrap.cObject {
        key.data = register:activeIsSetAbove
        default = TEXT
        default.value = |<br>
        1 = TEXT
        1.value = <div style="display:none;">|</div>
      }
#      doNotShowLink.cObject = CASE
#      doNotShowLink.cObject {
#        key.data = register:activeIsSetAbove
#        default = TEXT
#        default.value = 0
#        1 = TEXT
#        1.value = 1
#      }
    }
    ACT = 1
    ACT {
      allWrap = |<br>
      after.cObject = LOAD_REGISTER
      after.cObject {
        activeIsSetAbove = 1
      }
    }
  }
}

lib.navibelow = HMENU
lib.navibelow {
  special = directory
  special.value = 1
  1 = TMENU
  1 {
    noBlur = 1
    NO {
      allWrap.cObject = CASE
      allWrap.cObject {
        key.data = register:activeIsSetBelow
        default = TEXT
        default.value = <div style="display:none;">|</div>
        1 = TEXT
        1.value = |<br>
      }
    }
    ACT = 1
    ACT {
      doNotShowLink = 1
      after.cObject = LOAD_REGISTER
      after.cObject {
        activeIsSetBelow = 1
      }
    }
  }
}

Dort passiert schon ganz schön viel serverseitig, auch wenn im html trotzdem noch überflüssige Einträge stehen. Man kann natürlich "display:none;" durch ein html-Kommentar ersetzen oder umgekehrt.

Die Funktionsweise bei der oberen Navi ist so, dass beim Erreichen des aktiven Menüpunktes ein Register auf 1 gesetzt wird (den Namen des Registers "activeIsSetAbove" kann man dabei selbst festlegen). Bei allen anderen Menüpunkten wird geprüft, ob dieses Register 1 ist, und entsprechend der Wrap gewählt. Bei der unteren Navi halt einfach andersrum in der Bedingung.

Was ich leider in diesem Zusammenhang nicht hinbekommen habe, ist das ganze mit "doNotShowLink" zu verbinden. Damit könnte man sämtliche überflüssigen html-Ausgaben unterbinden, weil alles serverseitig gelöst werden würde. Die auskommetierten Zeilen in dem Skript wirken sich auch wenn sie nicht auskommentiert sind nicht aus.

"doNotShowLink" ist vom Typ boolean (falls man da im Typoscript von "Typen" spricht). Kennt jemand eine Möglichkeit, diesen Wert anhand eines Registers über "CASE" zu setzen?

Viele Grüße
Thomax

resta ·

Hallo,

ist zwar schon eine Weile her, aber danke für den Beitrag.
Folgendermaßen funktioniert es bei mir prächtig, ohne dass unsichtbare Schnipsel im HTML Code auftauchen:

temp.vnav = HMENU
temp.vnav {
  special = directory
  special.value = 1
  
  wrap = <div class="vnav">|</div>
  
  1 = TMENU
  1 {
    
    wrap = <ul>|</ul>
    
    noBlur = 1
    NO {
      
      allWrap.cObject = CASE
      allWrap.cObject {
        key.data = register:activeIsSetAbove
        default = TEXT
        default.value = <li>|</li>
        1 = TEXT
        1.value = 
      }
      doNotShowLink.cObject = CASE
      doNotShowLink.cObject {
        key.data = register:activeIsSetAbove
        default = TEXT
        default.value = 0
        1 = TEXT
        1.value = 1
      }
    }
    ACT = 1
    ACT {
      allWrap = <li class="active">|</li>
      after.cObject = LOAD_REGISTER
      after.cObject {
        activeIsSetAbove = 1
      }
    }
  }
}

temp.vnav2 = HMENU
temp.vnav2 {
  special = directory
  special.value = 1
  
  wrap = <div class="vnav second_vnav">|</div>
  
  1 = TMENU
  1 {
    
    wrap = <ul>|</ul>
    
    noBlur = 1
    NO {
      
      allWrap.cObject = CASE
      allWrap.cObject {
        key.data = register:activeIsSetBelow
        default = TEXT
        default.value =
        1 = TEXT
        1.value = <li>|</li>
      }
      doNotShowLink.cObject = CASE
      doNotShowLink.cObject {
        key.data = register:activeIsSetBelow
        default = TEXT
        default.value = 1
        1 = TEXT
        1.value = 0
      }
    }
    ACT = 1
    ACT {
      doNotShowLink = 1
      after.cObject = LOAD_REGISTER
      after.cObject {
        activeIsSetBelow = 1
      }
    }
  }
}