Questions & Answers

rbitdd
Returning Responder

Frage zur Navigation / Anzahl der Elemente eines Ordners

Hallo zusammen.

Ich habe folgendes Problem:

Unser Designer war so "kreativ", dass er in Abhรคngigkeit der Anzahl der Unterordner unterschiedliche Designs des Navigationshintergrundes mรถchte :smileyangry:

Ich muss nun auf erster Ebene wissen, wie viele Menรผpunkte Ebene zwei hat.

Mit Hilfe des Helpdesks (ich dachte ich hรคtte einen Fehler gefunden, hab's aber nur falsch verstanden) bin ich schon mal soweit:

$CMS_SET(counter,0)$


$CMS_FOR(folder,#nav.ref.parent.parent.parent.parent.getChildren(#nav.ref.parent.class))$

$CMS_IF(folder.getFolderLangSpec(#global.language).isVisible())$

$CMS_SET(counter,counter+1)$

$CMS_VALUE(folder.id)$

$CMS_END_IF$

$CMS_END_FOR$



Ich lasse mir die ID ausgeben, um zu รผberprรผfen, welchen Menรผpunkt er denn jetzt gerade zรคhlt.

Mir ist ja noch klar, das in Abhรคngigkeit der Anzahl der "parent"s, die ich angebe, auch die entsprechende Menรผebene durchgezรคhlt wird, jedoch nicht, warum er nicht immer die gleiche Menรผebene zรคhlt. OK, habe das nochmal รผberprรผft, habe auch das jetzt verstanden. D.h. das ganze wรผrde sich vereinfachen lassen, wenn fรผr jeden Ordner eine eigene Startseite besteht und nicht nur ein Startordner. Hier weiรŸ ich jedoch nicht, ob das gewรผnscht, geschweige denn auf Dauer so sein wird. Ich kenn doch die Redakteure. Smiley Wink

Hat jemand eine Idee, wie ich herausfinde, wie viele Menรผpunkte Ebene X hat?

Danke schon mal! Smiley Happy

0 Kudos
8 Replies
rbitdd
Returning Responder

Ich habe mich durch diesen Artikel inspirieren lassen! Smiley Happy

Dabei ist dann folgendes rausgekommen:

$CMS_TRIM(level:3, char:"\r\n")$
$CMS_SET(menu_count,0)$
$CMS_SET(menu_list, [])$

$-- alle ordner in tmpfolder und einzeln durchlaufen--$
$CMS_FOR(tmpfolder,#global.node.store.children(#global.node.parent.class))$
    $-- ueberpruefen, ob ordner sichtbar ist --$
    $CMS_IF(tmpfolder.getFolderLangSpec(#global.language).isVisible())$
       $-- wenn ja, dann dessen unterordner durchsuchen ... --$
        $CMS_FOR(otherfolder,tmpfolder.children(#global.node.parent.class))$
            $-- und ueberpruefen, ob diese sichtbar sind --$
            $CMS_IF(otherfolder.getFolderLangSpec(#global.language).isVisible())$
                $-- wenn ja, dann wird dieser Ordner gezaehlt --$
                $CMS_SET(menu_count,menu_count+1)$
            $CMS_END_IF$
        $CMS_END_FOR$
        $-- alle gezaehlten Ordner der Liste hinzufuegen --$
        $CMS_SET(menu_list,menu_list.add(menu_count))$
        $-- und Wert wieder zurueck setzen --$
        $CMS_SET(menu_count,0)$
    $CMS_END_IF$
$CMS_END_FOR$
$CMS_END_TRIM$

Fรผr die Navigationsfunktion habe ich noch einen weiteren Counter angelegt:

$CMS_SET(navi_counter,0)$

Innerhalb der Navigationsfunktion frage ich dann ab, wie viele Eintrรคge jetzt in der entsprechenden Ebene enhalten sind:

$CMS_IF(menu_list.get(navi_counter) == 5)$###hier Style-Klassen-ร„nderung###$CMS_END_IF$

Und im innerEndHTML wird der Counter dann eins hoch gezรคhlt.

$CMS_SET(navi_counter,navi_counter+1)$]

Etwas "tricky", geht auch vielleicht einfacher (bin offen fรผr Vorschlรคge Smiley Wink), aber es geht jetzt erst mal!Smiley Happy

0 Kudos
rbitdd
Returning Responder

Ich habe einen Fehler gefunden:

Das oben genannte funktioniert nur, wenn "#global.node.parent.class" vom Typen "de.espirit.firstspirit.store.access.sitestore.PageRefFolderImpl" ist.

Aber sobald die generierte Seite direkt im Sitestore (z.B. die Startseite) liegt, funktioniert das nicht, weil da "#global.node.parent.class" vom Typen "de.espirit.firstspirit.store.access.sitestore.SiteStoreRootImpl" ist.

"Kleiner" aber feiner Unterschied.

Jemand ne Idee?

0 Kudos
hoebbel
Crownpeak employee

Erstmal zwei Anmerkungen [da ich keine Zeit habe, das in Ruhe durchzulesen]

Wenn man wissen will, ob der _aktuelle_ Navigationspunkt sichtbare Kinder hat, hilft #nav.hasSubFolders() [gibt einen Boolean Wert zurรผck]

Will man den aktuellen Ordner in der Navigation haben, bekommt man den mittels #nav.folder

Mit den beiden Informationen soltle der Code bedeutend kรผrzer werden - und das Problem mit der Sitestore Wurzel auch nicht mehr auftreten Smiley Wink

Tut mir leid, dass ich diese Infos in de helpdesk Antwort nicht mirgeschickt hatte - leider war mir wohl doch nicht ganz bewusst, was Sie wollten Smiley Sad

0 Kudos
rbitdd
Returning Responder

Hallo Herr Hรถbbel,

ja, gut zu wissen, hilft aber leider nicht weiter. Smiley Sad

Ich muss wissen, wie viele sichtbare Kinder der Menรผpunkt hat, nicht ob. Daher hilft #nav.hasSubFolders() nicht weiter.

รœber #nav.folder denke ich nochmal nach, ob das weiterhelfen kรถnnte! Smiley Wink

Ein Kollege hat sich meiner kurz erbarmt und sich mit mir dran gesetzt.

Wir lassen uns jetzt per

$CMS_FOR(items,#global.node.store.children)$
     $CMS_SET(folder_reference,items)$
$CMS_END_FOR$

ein Objekt vom Typen "PageRefFolderImpl" geben! (Eklig, oder? :smileygrin: Ich bezweifle auch, dass das IMMER funktioniert. Bisherige Tests sind aber immer positiv ausgefallen, da FS bei #global.node.store.children

wohl immer erst die einzelnen Seitenreferenzen und danach erst die Ordner auflistet.)

Die "forder_reference" dann an Stelle von "#global.node.parent.class" eingetragen und es lรคuft! Smiley Happy

(Merkwรผrdigerweise muss ich das aber an beiden Stellen ersetzen. Warum ist mir nicht ganz klar, aber auch im Moment relativ! Smiley Wink)

Sieht also jetzt so aus:

$CMS_TRIM(level:3, char:"\r\n")$
$CMS_SET(navi_counter,0)$
$CMS_SET(menu_count,0)$
$CMS_SET(menu_list, [])$

$CMS_FOR(items,#global.node.store.children)$
    $CMS_SET(folder_reference,items)$
$CMS_END_FOR$

$-- alle ordner in tmpfolder und einzeln durchlaufen--$
$CMS_FOR(tmpfolder,#global.node.store.children(folder_reference.class))$
    $-- ueberpruefen, ob ordner sichtbar ist --$
    $CMS_IF(tmpfolder.getFolderLangSpec(#global.language).isVisible())$
       $-- wenn ja, dann dessen unterordner durchsuchen ... --$
        $CMS_FOR(otherfolder,tmpfolder.children(folder_reference.class))$
            $-- und ueberpruefen, ob diese sichtbar sind --$
            $CMS_IF(otherfolder.getFolderLangSpec(#global.language).isVisible())$
                $-- wenn ja, dann wird dieser Ordner gezaehlt --$
                $CMS_SET(menu_count,menu_count+1)$
            $CMS_END_IF$
        $CMS_END_FOR$
        $-- alle gezaehlten Ordner der Liste hinzufuegen --$
        $CMS_SET(menu_list,menu_list.add(menu_count))$

        $-- und Wert wieder zurueck setzen --$

        $CMS_SET(menu_count,0)$
    $CMS_END_IF$
$CMS_END_FOR$
$CMS_END_TRIM$

Mal schau'n ob sich das nicht doch noch optimieren lรคsst! Smiley Wink

Ach ja, meine tolles Konstrukt befindet sich nicht in der Navigationsfunktion. Daher werde ich, solange wir keinen Weg finden die Funktion komplett darin abzubilden, auch nicht auf #nav zu greifen kรถnnen.

Viele GrรผรŸe

0 Kudos
rbitdd
Returning Responder

Ok, ich muss das hier nochmal ausgraben:

Wir lassen uns jetzt per

$CMS_FOR(items,#global.node.store.children)$
     $CMS_SET(folder_reference,items)$
$CMS_END_FOR$

ein Objekt vom Typen "PageRefFolderImpl" geben! (Eklig, oder? :smileygrin: Ich bezweifle auch, dass das IMMER funktioniert. Bisherige Tests sind aber immer positiv ausgefallen, da FS bei #global.node.store.children

wohl immer erst die einzelnen Seitenreferenzen und danach erst die Ordner auflistet.)

Also, eklig ist hier echt untertrieben. Ich habe jetzt herausgefunden, warum das funktionierte (und heute zwischenzeitlich nicht mehr! Smiley Wink :smileygrin:)


#global.node.store.children

zeigt nรคmlich nicht immer erst auf die Seiten und dann auf Ordner. Von Sortierung nach Typen kann hier keine Rede sein. Die ist dem FS ziemlich schnuppe. Es erfolgt viel mehr eine Sortierung nach ID. Diese ist, logischerweise, aufsteigend sortiert und bekanntermaรŸen von der Reihenfolge der Anlage des Objektes abhรคngig.

Wenn ich also zuletzt im Strukturbaum an oberster Stelle eine Seite angelegt habe, erhalte ich unter "folder_reference" eine Seite und mein tolles Skript war fรผr'n "Hintern".

Derzeit habe ich jedoch das Glรผck, das ich eine Strukturvariable setzen musste, die auf einen Ordner verweist und das wird auch immer so bleiben. Daher ist es zuverlรคssiger als die bisherige Variante, wenn ich mir von dieser Variable die Referenz bzw. die Klasse der Referenz geben lasse.

Ich wรผnschte eine bessere Lรถsung prรคsentieren zu kรถnnen. Vielleicht findet sich diese ja noch! Smiley Wink

In diesem Sinne: t.b.c.

0 Kudos

Hallo rbitdd,

falls ich den Sachverhalt richtig verstanden habe kรถnnte es auch so gelรถste werden:

<CMS_HEADER>
 
<CMS_FUNCTION name="Navigation" resultname="fr_pt_mainnavigation">
  <CMS_PARAM name="expansionVisibility" value="all"/>
  <CMS_PARAM name="wholePathSelected" value="1"/>
  <CMS_PARAM name="suppressEmptyFolders" value="1" />
  <CMS_ARRAY_PARAM name="beginHTML" size="5">
    <CMS_ARRAY_ELEMENT index="0">
    <![CDATA[
    $CMS_SET(level_0_count,0)$
    $CMS_SET(level_0_content,"")$
    ]]></CMS_ARRAY_ELEMENT>
    <CMS_ARRAY_ELEMENT index="1">
    <![CDATA[
    $CMS_SET(level_1_count,0)$
    $CMS_SET(level_0_count,level_0_count + 1)$
    $CMS_SET(level_1_content,"")$
    ]]></CMS_ARRAY_ELEMENT>
    <CMS_ARRAY_ELEMENT index="2">
    <![CDATA[
    $CMS_SET(level_2_count,0)$
    $CMS_SET(level_1_count,level_1_count + 1)$
    $CMS_SET(level_2_content,"")$
    ]]></CMS_ARRAY_ELEMENT>
    <CMS_ARRAY_ELEMENT index="3">
    <![CDATA[
    $CMS_SET(level_3_count,0)$
    $CMS_SET(level_2_count,level_2_count + 1)$
    $CMS_SET(level_3_content,"")$
    ]]></CMS_ARRAY_ELEMENT>
    <CMS_ARRAY_ELEMENT index="4">
    <![CDATA[
    $CMS_SET(level_4_count,0)$
    $CMS_SET(level_3_count,level_3_count + 1)$
    $CMS_SET(level_4_content,"")$
    ]]></CMS_ARRAY_ELEMENT>
    </CMS_ARRAY_PARAM>
 
  <CMS_ARRAY_PARAM name="endHTML" size="5">
    <CMS_ARRAY_ELEMENT index="0">
    <![CDATA[<div>$CMS_VALUE(#nav.label)$ ($CMS_VALUE(level_0_count)$)</div>
    $CMS_VALUE(level_0_content)$
    ]]></CMS_ARRAY_ELEMENT>
    <CMS_ARRAY_ELEMENT index="1">
    <![CDATA[
    $CMS_SET(level_0_content_new)$<div>$CMS_VALUE(#nav.label)$ ($CMS_VALUE(level_1_count)$)</div>$CMS_END_SET$
    $CMS_SET(level_0_content,level_0_content.toString()+level_0_content_new.toString()+level_1_content.toString())$
    ]]></CMS_ARRAY_ELEMENT>
    <CMS_ARRAY_ELEMENT index="2">
    <![CDATA[
    $CMS_SET(level_1_content_new)$<div>$CMS_VALUE(#nav.label)$ ($CMS_VALUE(level_2_count)$)</div>$CMS_END_SET$
    $CMS_SET(level_1_content,level_1_content.toString()+level_1_content_new.toString()+level_2_content.toString())$
    ]]></CMS_ARRAY_ELEMENT>
    <CMS_ARRAY_ELEMENT index="3">
    <![CDATA[
    $CMS_SET(level_2_content_new)$<div>$CMS_VALUE(#nav.label)$ ($CMS_VALUE(level_3_count)$)</div>$CMS_END_SET$
    $CMS_SET(level_2_content,level_2_content.toString()+level_2_content_new.toString()+level_3_content.toString())$
    ]]></CMS_ARRAY_ELEMENT>
    <CMS_ARRAY_ELEMENT index="4">
    <![CDATA[
    $CMS_SET(level_3_content_new)$<div>$CMS_VALUE(#nav.label)$ ($CMS_VALUE(level_4_count)$)</div>$CMS_END_SET$
    $CMS_SET(level_3_content,level_3_content.toString()+level_3_content_new.toString()+level_4_content.toString())$
    ]]></CMS_ARRAY_ELEMENT>
    </CMS_ARRAY_PARAM>
</CMS_FUNCTION>
</CMS_HEADER>
<style type="text/css">
.level0{padding-left:0px;}
.level1{padding-left:20px;}
.level2{padding-left:40px;}
.level3{padding-left:60px;}
.level4{padding-left:80px;}
.level5{padding-left:100px;}
</style>
$CMS_VALUE(fr_pt_mainnavigation)$

Ich hoffe es hilft das Problem zu lรถsen.

Beste GrรผรŸe aus Ulm

0 Kudos

Hallo rbitdd,

ist das Thema noch aktuell? Ich habe รคhnliche Probleme รผber ein Script gelรถst. Es wir innerhalb der Funktion navigation aufgerufen und bekommt den aktuellen Navigationspunkt und die Sprache รผbergeben (beides kenne ich an diesem Punkt und erspare mir so das umstรคndliche holen รผber den Rendercontext). Das sieht dann so aus:

     $CMS_RENDER(script:"shownavarrow",nav:#nav,lang:#global.language)$

Der Rรผckgabewert kann entweder ein String fรผr die CSS Classe sein oder eine Zahl fรผr die Verarbeitung im Template. Je nach dem, wie oft man dieses Script in anderem Context benรถtigt, muss man sich fรผr eine Variante entscheiden.

Im Scritp hole ich mir รผber

     PageRefFolder parentFolder = nav.getFolder();

den รผbergeordneten Ordner, รผber den ich dann iterieren kann:

    int folderCount = 0;  

    folderIter = parentFolder.getChildren(PageRefFolder.class, false).iterator();
    while(folderIter.hasNext()){
        if(folderIter.next().getFolderLangSpec(lang).isVisible()){
            folderCount++;           
        }
    }

Danach kann man die Zahl nach Belieben weiter verarbeiten und am Ende des Scripts รผber den Return das gewรผnschte Resultat zurรผckgeben oder in eine globale Variable speichern (einen Hinweis, wie das geht, findet man in einem Blog von Gerrit Bรถsebeck). Schreibt man das CMS_RENDER in ein CMS_SET, kann man diese Variable ebenfalls weiter verwenden.

AbschlieรŸend ist noch zu sagen, dass man im Script die try and catch Anweisungen nicht vergessen sollte und ein paar wenige Logs fรผr das Debugging einbauen, dann geht die Entwicklung einfacher ๐Ÿ˜‰

Ich hoffe, der Ansatz hilft.

Viele GrรผรŸe.

PS: Die o.g. Methode hasSubFolders() liefert alle Unterordner unabhรคngig von ihrer Sichtbarkeit in der Navigation bzw. Sitemap.

0 Kudos

Sorry fรผr den Necro, aber das Thema ist noch immer nicht im Produkt gelรถst.

Vielleicht mag der eine oder die andere meinen FR unterstรผtzen?

https://community.crownpeak.com/t5/Feature-Discussions/New-nav-hasVisibleSubFolders-Function/idi-p/5...

0 Kudos

Type a product name