Mega-Menü mit Cache optimieren

Ein Megamenü zeigt schnell alle Navigationspunkte – aber ist ein Schmerz beim ersten Rendern einer Seite. Dank CachingFramework lässt sich das optimieren.

Für ein solches Menü ist es nötig, dass für alle Teilseitenbäume die Äste ausgelesen werden (TypoScript: expAll) und noch unsichtbar in HTML eingebettet werden. Bei größeren Websites quält man da schnell mal den Datenbankserver, und die Performance lässt nach. Menüs werden pro Seite generiert, und erst dann mittels Seitencache zwischengespeichert. Für große Menüs heißt dies aber, dass auch die „anderen“, inaktiven Äste jedes Mal neu generiert werden :-(

Weiterlesen

„Nächster Montag“ via TypoScript

Im TYPO3.net-Forum ist die Frage aufgetaucht, wie man denn „nächster Montag“ via TypoScript errechnen könne? Mich hat die Fragestellung gereizt…


Die eigentliche Schwierigkeit fand ich eher darin, eine Berechnungsformel zu finden. Nach etwas Nachdenken und Nachlesen, welche Werte die Datumsfunktionen date()/strftime() liefern können, stand die Berechnung fest:

Man nehme den aktuellen UNIX-Zeitstempel und addiere hierzu: acht minus den aktuellen Wochentag als Zahl, multipliziert mit den Sekunden eines Tages.

page.555 = COA
page.555 {
  stdWrap.prioriCalc = 1
  stdWrap.strftime = %A, %d.%m.%Y
  10 = TEXT
  10 {
    data = date: U
  }
  20 = TEXT
  20 {
    data = date: U
    strftime = %u
    wrap3 = +(8-|)*(24*60*60)
  }
}

Quellen

tt_news Icons: Alternative für Datei Ressourcen

Der einfachste Weg für eigene Icons ist via TypoScript den den Icon-Pfad und ggf die Dateiendung zu setzen:

plugin.tt_news.newsFiles.icon.path = fileadmin/templates/images/icons/
plugin.tt_news.newsFiles.icon.ext = png

Zu beachten ist hier lediglich, dass auch eine Datei „default“ mit passender Endung im Ordner liegt.

Alternative

Eine Alternative könnte unter Umständen via replacement-Eigenschaft des stdWrap sein. Dies ist v.a. dann interessanter, wenn die Dateinamen nicht 1:1 von TYPO3 übernommen werden sollen, und bei replacement auch Reguläre Ausdrücke nutzbar wären.

plugin.tt_news.newsFiles {
  stdWrap {
    replacement {
      10 {
        search = typo3/sysext/cms/tslib/media/fileicons/
        replace = fileadmin/images/icons/
      }
      20 {
        search = gif
        replace = png
      }
    }
  }
}

Links

 

Neueste Meldung als Default in tt_news-SingleView

Ruft man die Detailseite des tt_news-Plugins ohne gültige News-ID auf, so erhält man die nur wenig interessante Information, dass eben keine ID übergeben wurde. Oftmals schöner bzw. gewünscht wird hier aber stattdessen eine Default-Inhalt – z.B. die aktuellste Meldung.

Mit ein wenig TypoScript ist das schnell zusammengebaut

plugin.tt_news.noNewsIdMsg_stdWrap.override.if.isFalse.data = GPvar:tx_ttnews|tt_news
plugin.tt_news.noNewsIdMsg_stdWrap.override.cObject = CONTENT
plugin.tt_news.noNewsIdMsg_stdWrap.override.cObject {
  table = tt_news
  select {
    // Seiten-ID der tt_news-Artikel
    pidInList = 8
    orderBy = datetimedesc
    max = 1
  }
}

tt_news: optionSplit vs. noTrimWrap – ungünstige Default-Einstellungen

Die Extension tt_news hat in Version 3.0 eine schöne Neuerung mitgebracht: optionSplit-Unterstützung für viele Marker. Über genau diese Neuerung kann man jedoch auch stolpern. Im aktuellen Fall wunderte ich mich über das Resultat des Markers ###NEWS_AUTHOR### in der LIST-Ansicht.

Von:Julian

So zusammengeklebt sieht das nicht schön aus. Da gibt’s doch bestimmt einen stdWrap, mit dem man da ein Leerzeichen dazwischen bekommt. Und in der Tat, es gibt den preAuthor_stdWrap, der auf das „Von:“ angewendet wird. Zu meiner Überraschung hatte dieser schon einen passenden Default-Wert im TypoScript:

plugin.tt_news.displayList.preAuthor_stdWrap.noTrimWrap = || |

Dann hilft wohl nur eine genauere Analyse…
Weiterlesen

Menü der Unterseiten – ggf. der Elternseite, falls Shortcut

Ein Menü aus Unterseiten lässt sich ganz leicht in TypoScript bauen. Hierzu einfach ein HMENU hernehmen, und via special = directory die passenden Einstellungen vornehmen:

20 = HMENU
20 {
    // Menü der Unterseiten der aktuellen Seite
    special = directory
    special.value.data = TSFE : id
    1 = TMENU
    1 {
        NO {
            // ...
        }
    }
}

Problem

Nun trifft man gelegentlich aber auf Seitenstrukturen, bei denen Shortcuts in Verwendung sind, d.h. die aktuelle Seite eigentlich eine Menü der Unterseiten der Elternseite anzeigen sollte.

Bildschirmfoto 2014-03-11 um 10.07.21Hier wäre „Seite 2“ der Shortcut auf die erste Unterseite, und wir würden uns wünschen, dass folglich auf „Seite 2.1“ ein Menü der Unterseiten von „Seite 2“ angezeigt wird.

Lösung

Die Lösung ist hier mittels override auch recht fix erreicht:

20 = HMENU
20 {
    // Menü der Unterseiten der aktuellen Seite (unabhaengig vom Treelevel)
    special = directory
    special.value.data = TSFE : id
    // Falls aktuelle Seite aus einem Shortcut der Parent-Site hervorging, dann Unterseiten dieser anzeigen
    special.value.override {
        cObject = CONTENT
        cObject {
            table = pages
            select {
                pidInList >
                pidInList.data = leveluid : -3
                // @todo: siehe "Update"
                //where = doktype = 4 AND ((shortcut_mode=0 AND shortcut = ###currentPage###) OR shortcut_mode=1)                 
                where = doktype = 4 AND (shortcut_mode=0 AND shortcut = ###currentPage###)                 
                markers {
                    currentPage.data = TSFE : id
                }
            }
            renderObj = COA
            renderObj {
                10 = TEXT
                10.field = uid
            }
        }
    }
    1 = TMENU
    1 {
        NO = 1
        NO {
           // ...
        }
    }
}

Über eine Datenbankabfrage suchen wir Seiten, die einerseits Elternseite unserer aktuellen Seite sind, zugleich aber auch von Typ „Shortcut“ (doktype=4) sind und als Ziel unsere aktuelle Seiten haben bzw. den Modus „First subpage of current page“ haben.

TYPO3 4.5-Spezialität:

Da uidInList erst aber 4.6 stdWrap-Eigenschaften hat, kann der Wert nicht dynamisch gesetzt werden, und kommt bei 4.5 der Defaultwert von pidInList = this in die Quere. Es muss also statt uidInList die Seiten-ID der Eltern-Eltern-Seite in die pidInList-Bedingung geschrieben werden. Diese ID erhält man am einfachsten aus der Rootline.

Update

Die Logik passt noch nicht für Modus „First subpage of current page“, falls wir uns nicht auf dieser ersten Unterseite befinden, sondern auf anderer Unterseite.
Hat jemand eine Idee, wie das mit berücksichtigt werden kann?

Zufälliges Bild aus Resourcen

Im TYPO3-Forum kam letzten die Frage nach einem zufälligem Bild aus dem Resourcen-Feld (media) einer bestimmten, festen Seite auf. Die Frage interessierte mich, gerade weils ich hier durch die Einführung von FAL Änderungen ergaben und viele Snippets aus dem Netz nicht (mehr) funktionieren.

Aus dem Ansatz des Threadautors entwickelt, ergab sich schließlich folgende Lösung:

temp.backImg = FILES
temp.backImg {
    files.cObject = CONTENT
    files.cObject {
        table = sys_file_reference
        select {
            // Page-ID der Seite, aus der Bilder entnommen werden sollen
            pidInList = 3
            where = tablenames='pages' AND fieldname='media'
            selectFields = uid_local
            orderBy = rand()
            max = 1
        }
        renderObj = TEXT
        renderObj.field = uid_local
    }
    renderObj = IMAGE
    renderObj {
        file.import.data = file:current:publicUrl
    }
}

Zunächst sieht das ganze etwas kompliziert aus. Es hat aber den Vorteil, dass mit diesem Ansatz wirklich sehr variable Lösungen möglich werden. So könnte statt auf die pages-Tabelle auch auf News-Datensätze, Produktdaten, Inhaltselemente odgl. zugegriffen werden, da die volle Breite der SQL-Abfrage bereitsteht.

Der einfachere Weg

Wenn man sich nicht zu sehr in Code schon reingedacht hat, und den Wald vor lauter Bäumen nicht mehr sieht, dann fällt einem sogar die einfachere Lösung ein (die letztens im Forum auch gesucht wurde):

temp.backImg = IMAGE
temp.backImg.file {
    import.data = levelmedia: 0
    import.listNum = rand
    treatIdAsReference = 1
}

Zu beachten ist hierbei aber, dass das TypoScript-Objekt gecacht wird, d.h. der „Zufall“ auch gecacht wird. Wenn dies unerwünscht ist, dann müsste ein *_INT-Objekt außenherum.
Alternative wäre, mehrere Bilder in HTML einzubetten und via JS (und damit am Cache vorbei) den Zufall zu handhaben (d.h. Bilder ein-/auszublenden).

Links

Externe URLs in Menüs

Seiten vom Typ „External URL“ werden von TYPO3 in Menüs standardmäßig nur als interne Links generiert, die dann via Redirect auf die externe Seite verweisen.

Manchmal möchte man aber die Seiten gleich direkt verlinkt haben. Christopher hat dazu ein Snippet online gestellt. Dort wird aber nicht das zwischenzeitlich eingeführte Feld „Protocol“ bzw. „urltype“ berücksichtigt. Daher habe ich das Snippet etwas gepimpt :-)

lib.extUrlMenu = HMENU
lib.extUrlMenu {
    1 = TMENU
    1 {
        wrap = <ul id="externalLinks"> | </ul>

        NO = 1
        NO {
            wrapItemAndSub = <li> | </li>

            doNotLinkIt = 1
            stdWrap.cObject = CASE
            stdWrap.cObject {
                key.field = doktype
                default = TEXT
                default {
                    field = title
                    typolink {
                        parameter.data = field:uid
                    }
                }

                3 < .default
                3 {
                    stdWrap.htmlSpecialChars = 1
                    typolink {
                        parameter {
                            data >
                            cObject = CASE
                            cObject.key.field = urltype
                            cObject.default = TEXT
                            cObject.default.value = http://
                            cObject.1 = TEXT
                            cObject.1.value = http://
                            cObject.4 = TEXT
                            cObject.4.value = https://
                            cObject.2 = TEXT
                            cObject.2.value = ftp://
                            cObject.3 = TEXT
                            cObject.3.value = mailto:
                            cObject.stdWrap.dataWrap = |{field:url}
                        }
                    }
                }
            }
        }
    }
}

Quellen

  1. TMENU with external links