Patrick Fiedorowicz | 24.08.2016 | TYPO3, Extensions, News
Vertikales Menu

Nachdem ich bisher viel positives Feedback für mein TypoScript-CATMENU für tt_news bekommen habe, ist es nun Zeit geworden, einen Nachfolger für tx_news auf die Beine zu stellen. Natürlich auch wieder mit News-Counter pro Kategorie.

tt_news ist tot, lange lebe tx_news. Ganz so dramatisch ist es nicht, aber tt_news verliert mehr und mehr Bedeutung zugunsten von tx_news. Vor einiger Zeit habe ich hier ein flexibles Kategorie-Menü mit News-Counter für tt_news erstellt und dafür sehr viel Lob bekommen. Nachdem ich aber in meiner eigenen Website und in sämtlichen Kundenprojekten nur noch tx_news einsetze, ist es notwendig geworden, eine neue, angepasste Version zu erstellen, welche die gleichen Features bietet.

Für diejenigen, welche mein CATMENU noch nicht kennen sollten, hier nochmal kurz die Features:

  • maximale Flexibilität durch Verwendung von reinem TypoScript
  • Auflistung aller News-Kategorien, auch über mehrere Ebenen
  • Zählung aller zugewiesenen News pro Kategorie
  • Links zum Filtern nach Kategorien

Ich habe wieder bewusst darauf geachtet, möglichst viele Kommentar zu hinterlegen, so dass auch TYPO3-Anfänger wenig Probleme haben sollten, die Zusammenhänge zu verstehen.

# zu erst der Marker fuer das neue Kat-Menu
lib.catList = COA
lib.catList {
  # hole alle Hauptkategorien
  10 = CONTENT
  10 {
    # wrappe die gesamte Liste als "unsortierte Liste"
    wrap = <ul class="news-catmenu">|</ul>
    table = sys_category
    select {
      # hier muss die pid eures News-Sysordners rein, bzw. wo die News-Kategorien gespeichert sind
      pidInList = 3
      orderBy = title
      where = parent=0 AND deleted=0 AND hidden=0
    }
    renderObj = COA
    renderObj {
      # wrappe jede gefundene Hauptkategorie als Listenelement
      wrap = <li>|</li>
      # ueberschreibe den vorherigen Wrap ...
      wrap.override = <li class="active">|</li>
      # ... nur, wenn ...
      wrap.override.if {
        # ... eine News-Kategorie bereits ausgewaehlt wurde und per GET/POST ermittelt werden kann
        value.data = GP:tx_news_pi1|overwriteDemand|categories
        # und dieser ermittelte Wert der aktuellen uid gleicht
        equals.field = uid        
      }

      # zeig mir den Kategorie-Titel und mache einen Filter-Link daraus
      10 = TEXT
      10 {
        # das title-Feld soll als Text angezeigt werden (koennte man auch description... verwenden)
        field = title
        typolink {
          # verlinke zu der Seite mit der News-Auflistung (Listenansicht)
          parameter = 34
          title.field = title
          # fuege den GET-Parameter fuer die ausgewaehlte Kategorie hinzu
          additionalParams.dataWrap = &tx_news_pi1[overwriteDemand][categories]={field:uid}
          # cHash mit uebergeben fuers Caching
          useCacheHash = 1
        }
      }

      # zeig mir einen Counter aller News-Eintraege in dieser Kategorie
      20 = CONTENT
      20 {
        table = sys_category
        select {
          # hier wieder der Sysordner aller News-Eintraege und -Kategorien
          pidInList = 3
          join = sys_category_record_mm ON (sys_category.uid = sys_category_record_mm.uid_local) 
          JOIN tx_news_domain_model_news ON (tx_news_domain_model_news.uid = sys_category_record_mm.uid_foreign)
          andWhere.dataWrap = (sys_category.uid={field:uid}) 
            AND tx_news_domain_model_news.deleted=0 AND tx_news_domain_model_news.hidden=0
            AND sys_language_uid={TSFE:sys_language_uid}
          # fuehre einen count durch und speichere das Ergebnis in "counter"
          selectFields = count(*) AS counter
        }
        renderObj = TEXT
        renderObj {
          # zeig mir nun das Ergebnis des Counters an und wrappe es
          field = counter
          wrap =  <span>(|)</span>
        }
      }

      # zeige mir alle Unterkategorien der aktuellen Kategorie an
      30 = CONTENT
      30 {
        stdWrap {
          # fuehre den Abschnitt nur aus, wenn in der Select-Abfrage ein Wert gefunden wurde
          required = 1
          wrap = <ul>|</ul>
        }

        table = sys_category
        select {
          pidInList = 3
          orderBy = title
          andWhere.dataWrap = parent={field:uid} AND deleted=0 AND hidden=0
        }
        # vererbe die Einstellungen von lib.CatList.10.renderObj an dieses renderObj
        renderObj < lib.catList.10.renderObj
        renderObj = COA
        renderObj {

          # zeige den Titel mit Verlinkung an, genauso wie bei lib.catList.10.renderObj.10 (vererbt)
          10 < lib.catList.10.renderObj.10

          # zeige den News-Counter an, genauso wie bei lib.catList.10.renderObj.20 (vererbt)
          20 < lib.catList.10.renderObj.20

          # zeige die Unterkategorien an, genauso wie bei lib.catList.10.renderObj.30 (vererbt)
          30 < lib.catList.10.renderObj.30
          # wenn noch eine 4. und 5. Kategorien-Ebene abgebildet werden sollen,
          # dann die folgenden 6 Zeilen verwenden
          # 30.renderObj = COA
          # 30.renderObj {
          #   10 < lib.catList.10.renderObj.10
          #   20 < lib.catList.10.renderObj.20
          #   30 < lib.catList.10.renderObj.30
          # }
        }
      }
    }
  }
}

Wie schaut das nun in Aktion aus? Hier im Kategorie-Menü auf der Seite "News" könnt ihr es euch in der rechten Sidebar ansehen. Ansonsten wünsche ich allen viel Spaß damit und bin wie immer offen für Feedback :)

  1. Georg Theiss Georg Theiss 23.10.2016
    einfach mal ein grosses Dankeschön, vor allem für die sauber Kommentierung!

    Es wird bei mir der Einfachheit halber mit einem DCE-Modul zur Kategorieauswahl zum Einsatz kommen (http://aikantink.de/y4y/blog-aktuelles-snippets/blog-detailansicht/news/fiedomedia-catmenu-fuer-tx-news-mit-counter-in-dce-mit-kategorieauswahl/
  2. Hannes Lang Hannes Lang 17.12.2016
    bei mehrsprachiger Version wird je Sprache eine Zeile ausgegeben. Gibts da einen Trick?
    1. Hannes Lang Hannes Lang 17.12.2016
      .... gefunden: in erster Frage fehlt: languageField = sys_language_uid
  3. Jari-Hermann Ernst Jari-Hermann Ernst 24.02.2017
    Danke für dieses wirklich gut kommentierte TypoScript-Beispiel. Das war genau das, was ich gerade gesucht habe!

    Allerdings wird bei mir der span mit dem Counter für die News nicht im a-Tag generiert, sondern dahinter. Auf Deiner Beispielseite ist das anders.

    Auf was muss ich da achten?
    1. Patrick Fiedorowicz pfiedorowicz 25.02.2017
      Hallo Jari-Hermann,

      danke für das Lob :)

      Du hast recht, ich hab es in der Version auf meiner Website etwas umgebaut. Im Grunde ist das aber nicht viel komplizierter:
      Mach aus dem 10 = TEXT (Kategorie-Titel) ein COA und pack die 20 = Content (Counter) mit rein. Anschließend machst du für das gesamte, neu erstellte COA ein stdWrap.typolink (was vorher beim Kategorie-Titel war). Fertig.

      Schöne Grüße
      Patrick
  4. Alex Möller Alex Möller 23.04.2017
    Hallo, verwende Typo3 V8 habe gerade den script probiert. bekomme aber immer folgende url:

    meineDomain.de/news/?tx_news_pi1%5BoverwriteDemand%5D%5Bcategories%5D=12&cHash=085fffec7addb1c707d87a812eda03bf

    obwohl ich Realurl verwende!
    Sollte ich in der Realurl_config noch was eintragen?

    LG Alex
    1. Patrick Fiedorowicz pfiedorowicz 23.04.2017
      Hi Alex,

      du hast recht, dir fehlt die RealUrl-Konfig für die News-Kategorien.
      Funktionieren denn die News-Detail-Links mit RealUrl?
      Hast du Autoconfig in RealUrl aktiviert oder konfigurierst du das selbst?

      Hier meine Konfig für TYPO3 7, das kannst du gerne verwenden und auf TYPO3 8 umbauen:
      'postVarSets' => array(
      '_DEFAULT' => array(
      'kategorie' => array(
      array(
      'GETvar' => 'tx_news_pi1[overwriteDemand][categories]',
      'lookUpTable' => array(
      'table' => 'sys_category',
      'id_field' => 'uid',
      'alias_field' => 'title',
      'addWhereClause' => ' AND NOT deleted',
      'useUniqueCache' => 1,
      'useUniqueCache_conf' => array(
      'strtolower' => 1,
      'spaceCharacter' => '-',
      ),
      ),
      ),
      ),
      ),
      ),
      (Sorry für die schlechte Formatierung)

      Grüße Patrick
  5. Stefanie Stefanie 26.04.2017
    Hallo,
    danke für das Script - genau das, was ich gesucht habe!
    Allerdings habe ich eine mehrsprachige Website und der Counter funktioniert nicht korrekt. Er zählt alle vorhandenen/übersetzten Artikel unabhängig von der Sprache:

    select {
    # hier wieder der Sysordner aller News-Eintraege und -Kategorien
    pidInList = 14
    join = sys_category_record_mm ON (sys_category.uid = sys_category_record_mm.uid_local)
    JOIN tx_news_domain_model_news ON (tx_news_domain_model_news.uid = sys_category_record_mm.uid_foreign)
    andWhere.dataWrap = (sys_category.uid={field:uid})
    AND tx_news_domain_model_news.deleted=0 AND tx_news_domain_model_news.hidden=0
    AND sys_language_uid={TSFE:sys_language_uid}
    languageField = sys_language_uid
    # fuehre einen count durch und speichere das Ergebnis in "counter"
    selectFields = count(*) AS counter
    }

    Hast du eine Idee, woran das liegen könnte?

    Danke und Grüße,
    Stefanie
    1. Patrick Fiedorowicz pfiedorowicz 26.04.2017
      Hi Stefanie,

      versuch mal das andWhere.dataWrap ohne Umbrüche zu schreiben:
      andWhere.dataWrap = (sys_category.uid={field:uid}) AND tx_news_domain_model_news.deleted=0 AND tx_news_domain_model_news.hidden=0 AND sys_language_uid={TSFE:sys_language_uid}

      Grüße Patrick
    2. Stefanie Stefanie 26.04.2017
      Danke für den Tipp - wenn nur alles so einfach wäre ;-)
      Allerdings war dann die sys_language_uid noch mehrdeutig und musste speziell der news-Tabelle zugewiesen werden:

      andWhere.dataWrap = (sys_category.uid={field:uid}) AND tx_news_domain_model_news.deleted=0 AND tx_news_domain_model_news.hidden=0 AND tx_news_domain_model_news.sys_language_uid={TSFE:sys_language_uid}

      Jetzt stimmen die Zahlen!

      Grüße Stefanie
  6. Kurt Kunig Kurt Kunig 11.05.2017
    Ich habe Deine lib.catList von oben übernommen. Bei mir wird aber nur die Parent-Kategorie angezeigt. Die Unterkategorien bleiben außen vor?
    Bei einem Artikel setze ich immer nur die Subkategorie ohne die Parent-Cat. zusätzlich zu setzen.
    Hast Du eine Idee, woran das liegen kann?
    Ich habe TYPO3 V8.7 und news 5.3.2 im Einsatz.
  7. Markus Dübbert Markus Dübbert 19.06.2017
    Das Menu funktioniert nicht in TYPO3 8.7.1 (news 6.0.0)
    In 7.6.18 mit news 5.3.3 oder auch news 6.0.0 funktioniert es.

    Mir ist noch nicht ganz klar, warum es nicht geht. Die Zuordnung der Unterkategorien funktioniert nicht. Die Unterkategorien (und die Hauptkategorien) werden bei mir bei jeder Hauptkategorie wiederholt.
    1. Markus Dübbert Markus Dübbert 19.06.2017
      Für TYPO3 8.7.1 geht:
      where.dataWrap = parent={field:uid} AND deleted=0 AND hidden=0
      statt
      andWhere.dataWrap = parent={field:uid} AND deleted=0 AND hidden=0
  8. Norbert Norbert 3 Wochen
    Hallo, wirklichein super Skript, vielen Dank dafür.
    Ein Problem hab ich leider dennoch und komme nicht auf die Lösung.
    Ich habe nur den Counter verwendet um Anzahl der Artikel aus einer einzigen Kategorie aus zu geben. Der Counter zählt leider sämtliche Artikel der betreffenden Kategorie (ohne berücksichtigung der Sprache) und ich wollte die Datenbankabfrage noch um "starttime kleiner jetzt" und "endtime größer jetzt" erweitern.
    Eigentlich ganz einfach, aber ich komme einfach nicht auf die Lösung. Könnten Sie mir da kurz weiter helfen? Wär echt super :)

    Vielen Dank
    1. Patrick Fiedorowicz pfiedorowicz 3 Wochen
      Hallo Norbert,

      vielen Dank für dein Lob.

      Achte bitte darauf, dass du join und andWhere in dem Abschnitt für den Counter in eine Zeile schreibst.
      Und dann fügst du am Ende bei andWhere noch hinzu:
      AND tx_news_domain_model_news.starttime < FROM_UNIXTIME() AND tx_news_domain_model_news.endtime > FROM_UNIXTIME()

      Schöne Grüße
      Patrick
    2. Norbert Norbert 3 Wochen
      Guten Tag Patrick,

      leider hatte ich da bereits alles versucht (auch die von Ihnen vorgeschlagenen Änderungen). Sobald ich die mache, liefert mir der Counter jedoch leider gar kein Ergebnis, obwohl jedoch ein Artikel der Abfrage entsprechen würde.
      (der gesamte join steht in einer einzigen langen Zeile)

      Vielen Dank für Ihre Hilfe
    3. Norbert Norbert 2 Wochen
      Hallo Patrick,
      wollte nur bescheid geben dass es jetzt läuft. PERFEKT.
      Mein Fehler war sowohl den join als auch andWhere alles zusammen in eine Zeile. Das darf nicht sein (muss man also in 2 Zeilen schreiben).
      Vielen Dank für deine Hilfe

Neuen Kommentar schreiben

Zurück zu allen News