Patrick Fiedorowicz |  27.06.2011 | TYPO3, Extensions

tt_news ist eine der ältesten vorhanden Extensions für TYPO3, sicherlich aber auch die am meisten genutzte. Da sich über die Jahre bei TYPO3 allerdings viel getan und weiterentwickelt hat, sind manche Verhaltensweisen und Funktionen von tt_news veraltet und schlichtweg zu unflexibel geworden. Hierzu zähle ich vorallem das CATMENU, mit welchem man eine für das Auge ansprechende Auswahl aller vorhandenen News-Kategorien anzeigen lassen kann. Doch leider ist die Verwendung des CATMENU zum Teil alles andere als zufrieden stellend.

  • Bislang ist es unmöglich (?!?), ohne Eingriff in den Quellcode der tt_news-Extension, die Anzahl der News, die eine Kategorie beinhaltet, dem Websiten-Besucher anzuzeigen
  • Wraps sind viel zu wenig implementiert, wodurch z. B. eine Listenansicht mit eingebetteten Unterlisten nicht HTML-konform erstellbar ist.

Um in den vollen Genuss der TYPO3-Wraps und Co. zu kommen, kann ich nur empfehlen, sich das Kategorien-Menü selbst zu generieren. Hierzu habe ein Typoscript-Snippet zusammengebastelt, mit welchem man sich selbst das CATMENU generieren lassen kann und als besonderes Feature, zu jeder Kategorie die Anzahl der dort hinterlegten News angezeigt werden.

Übrigens: wer bereits die neue Alternativ-Extension tx_news verwendet, für den habe ich das TypoScript-Snippet in einer angepassten tx_news-Version mit Counter bereitgestellt. 

Ich habe bewusst zu fast jeder Code-Zeile einen Kommentar verfasst, 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 = tt_news_cat
    select {
      # hier muss die pid eures News-Sysordners rein, bzw. wo die News-Kategorien gespeichert sind
      pidInList = 3
      orderBy = title
      where = parent_category=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="news-catmenu-ACT">|</li>
      # ... nur, wenn ...
      wrap.override.if {
        # ... eine News-Kategorie bereits ausgewaehlt wurde und per GET/POST ermittelt werden kann
        value.data = GPvar:tx_ttnews|cat
        # und dieser ermittelte Wert der aktuellen uid gleicht
        equals.field = uid        
      }
      # zeig mir den Kategorie-Titel und mache einen Link daraus zur Kategorie-Detail-Uebersicht
      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_ttnews[cat]={field:uid}
          # cHash mit uebergeben fuers Caching - Danke an ScubaBen fuer den Hinweis!
          useCacheHash = 1
        }
      }
      # zeig mir einen Counter aller News-Eintraege in dieser Kategorie
      20 = CONTENT
      20 {
        table = tt_news_cat
        select {
          # hier wieder der Sysordner aller News-Eintraege und -Kategorien
          pidInList = 3
          join (
            tt_news_cat_mm ON (tt_news_cat.uid = tt_news_cat_mm.uid_foreign) 
              JOIN tt_news ON (tt_news.uid = tt_news_cat_mm.uid_local)
          )
          # dieses Where sorgt dafuer, dass auch die News der Unterkategorien 1 Ebene unterhalb
          # gezaehlt werden - tiefere Ebenen koennen nicht beruecksichtigt werden
          # andWhere.dataWrap = (tt_news_cat.uid={field:uid} OR tt_news_cat.parent_category={field:uid}) AND tt_news.deleted=0 AND tt_news.hidden=0
          # dieses Where zaehlt nur die News in dieser Kategorie
          andWhere.dataWrap (
            (tt_news_cat.uid={field:uid}) 
            AND tt_news.deleted=0 AND tt_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 = tt_news_cat
        select {
          pidInList = 3
          orderBy = title
          andWhere.dataWrap = parent_category={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
          # }
        }
      }
    }
  }
}

Zum Abschluss noch ein wenig CSS, um die aktuell ausgewählte Kategorie auch grafisch ansprechend darzustellen:

li.news-catmenu-ACT > a {
  font-weight: bold;
  color: red; 
}

09.08.2011 - UPDATE 1 (Zeile 41+42)

Der cHash sollte bei einem Link mit übergeben werden, um das Caching von TYPO3 zu "unterstützen". Hierzu gibt es im TypoScript zu typolink eine Option "useCacheHash", diese auf 1 setzen, und schon wird der URL der cHash mit angehängt. Vielen Dank an ScubaBen, der mich "in die richtige Richtung geschubst hat" ;)

09.08.2011 - UPDATE 2 (Zeile 62)

Ein kleiner Fehler hat sich beim Counter der News eingeschlichen. Um lediglich die News zu zählen, die auch in dieser Sprache verfügbar sind, muss die WHERE-Klausel um die sys_language_uid aus dem TSFE-Objekt erweitert werden: "AND sys_language_uid={TSFE:sys_language_uid}"

zurück zu allen News

Kommentare

  1. sushie sushie 13.07.2011
    hallo patrick

    danke für den code, ist an sich genau was ich suche!

    habe aber ein problem: möchte gerne immer alle unterkategorien anzeigen (als verschachtelte ul-listen), habe das aber nicht hingekkriegt... resp. die unterkategorien werden überhaupt nie angezeigt, auch wenn ich deinen code unverändert benütze (abgesehen von der "pidInList" natürlich)... sollten nicht zumindest die unterkategorien der aktuell aktiven kategorie angezeigt werden?

    *danke für deine hilfe und lieber gruss
    1. Patrick FiedorowiczPatrick Fiedorowicz 13.07.2011
      Hallo Sushie,

      ich schreib dir mal per E-Mail, dann kann man das besser besprechen, was bei dir nicht ganz klappt...

      Grüße Patrick
  2. sushie sushie 17.07.2011
    tschau patrick

    danke für deine rückmeldung

    und sorry, war n fehler in meinem typoscript (vergessen den namen der lib anzupassen bei den unterrubriken)... dein code funktioniert einwandfrei!

    werde nun noch versuchen die einstellungen (va. pidInList und pid für catlist) zu dynamisieren, so dass per kategorie auf eine seperate listen-ansicht gelinkt werden kann.

    werde den code hier posten sobald ichs geschafft habe.

    *danke & gruss
    david
    1. Patrick FiedorowiczPatrick Fiedorowicz 13.07.2011
      Hallo Sushi,

      meld dich mal per Email bei mir, dann schauen wir mal dein Problem genauer an.

      Grüße Patrick
  3. Scubaben Scubaben 31.07.2011
    DANKEDANKEDANKEDANKE!
    Ich such schon siet 4 Stunden nach genau Deinem Post. Schade, dass Du noch so schlecht gefunden wirst. Aber vielen Dank & meinen Link hast Du ;)
  4. ScubaBen ScubaBen 09.08.2011
    mmmhhh - also nachdem ich den Cache eingeschaltet habe kam die Ernüchterung. Der chash Wert wird nicht mit übertragen. Ich habe dann die TreeView genommen und an der nen bisschen rumgeschnippelt. Nun gehts.
    1. Patrick FiedorowiczPatrick Fiedorowicz 09.08.2011
      Hallo ScubaBen,

      danke für deinen Hinweis mit dem cHash, das wäre natürlich super, wenn der mit übergeben wird fürs Caching.
      Mit der TS-Anweisung "useCacheHash = 1" im typolink ist das auch schon getan :) Ich werds in meinem Tutorial hinzufügen!

      Grüße Patrick
  5. Christian Christian 10.08.2011
    Hallo Patrick,
    tolles Script, macht beinahe genau das was ich brauche und super, dass Du alles kommentiert hast, dann versteht auch ich einigermaßen was passiert.

    Ich hab aber auch noch zwei Fragen:
    Ist es möglich, nur die Unterkategorien ausgeklappt anzuzeigen von denen gerade die Obergatekorie angeklickt wurde, also ähnlich wie bei einem normalen TYPO3-Menu?

    Im Moment ist es bei mir so:
    Oberkategorie 1
    '- Unterkategorie 1
    '- Unterkategorie 2
    '- Unterkategorie 3
    Oberkategorie 2
    '- Unterkategorie 4
    '- Unterkategorie 5
    Oberkategorie 3
    '- Unterkategorie 6
    '- Unterkategorie 7

    und so hätte ich es gerne, weil ich ziemlich viele Kategorien habe und die Liste sonst ziemlich lang wird:
    Oberkategorie 1
    Oberkategorie 2 (aktiv)
    '- Unterkategorie 4
    '- Unterkategorie 5
    Oberkategorie 3

    Die zweite Frage:
    Ist es möglich eine Klasse für die Oberkategorie zu vergeben, bei der eine Unterkategorie aktiv ist? Dann könnte man den Pfad und nicht nur den aktiven Punkt im Menü hervorheben.

    Grüße Christian
    1. Patrick FiedorowiczPatrick Fiedorowicz 11.08.2011
      Hallo Christian,

      gute Ideen, was du da hast! So könnte man ein relativ langes Kategorien-Menü elegant "verkleinern".
      Mit verschiedenen IF-Abfragen im TS sollte sowas eig. machbar sein... Ich schau mir mal an, was ich da zaubern kann :)

      Grüße Patrick
  6. Georg Georg 02.09.2011
    Vielen Dank für das Script. Funktioniert einwandfrei. Schön wäre noch eine Abfrage, damit nur jene Kategorien angezeigt werden, für welche auch Inhalt vorhanden ist.
  7. Alex T. Alex T. 14.10.2011
    Hallo,
    und danke für das snippet. Tolle Arbeit.

    Siehst du eine Möglichkeit die Anzahl der Artikel kummuliert darzustellen? Also wie bei der original Catmenu tree von tt_news.

    Ich meine, wie macht man aus:
    _
    |__Category1 (3)
    |__SubcategoryA (3)
    |__SubcategoryB (3)
    |__SubcategoryC (3)

    folgendes:

    _
    |__Category1 (12)
    |__SubcategoryA (3)
    |__SubcategoryB (3)
    |__SubcategoryC (3)


    Hintergrund: Bei der Listenansicht von Category1 werden richtigerweise die Artikel aus unterliegende Kategorien ebenfalls angezeigt. Im Fall oben also 12 Artikel. Das Menü zeigt in Klammern aber nur 'seine eigene' Artikel an. Das verwirrt einige Leute.

    Irgend eine Idee/Lösung?
    vg Alex
    1. Patrick FiedorowiczPatrick Fiedorowicz 14.10.2011
      Hallo Alex,

      schau dir im Snippet mal die Zeilen 55 und folgende an, da hast du eine alternative "andWhere"-Bedingung. Einfach diese verwenden und das NICHT auskommentierte andWhere auskommentieren, schon kannst du die Anzahl der News in der aktuellen Ebene + 1 Ebene tiefer.

      Grüße Patrick
  8. Nicki Nicki 07.11.2011
    Hi,

    vielen Dank für den tollen Beitrag!
    Bei mir funktioniert auch alles soweit, allerdings bleibe ich an folgendem Punkt hängen.

    <ul>
    <li>1. Level (1)
    <ul></ul>
    </li>
    </ul>

    Er baut mir keine li in die zweite ul, um die Subkategorien anzeigen zu lassen. Woran könnte das liegen?

    Viele Grüße und vielen Dank!
    Nicki
  9. Harp Harp 06.02.2013
    Hallo, vielen Dank für das Script. Kann mir noch jemand sagen, wie ich dieses Catmenu als Ebene 2 (auf einer Seite der Ebene 1) in einem HMENU einbauen kann.
    1. Patrick FiedorowiczPatrick Fiedorowicz 06.02.2013
      Hi Harp,

      versuch es mal so, dass du das Catmenu in die 2. Ebene deines TMENU einbindest:

      temp.DEINMENU = HMENU
      temp.DEINMENU {
      1 = TMENU
      1 {
      NO {
      wrapItemAndSub = <li>|</li>
      }
      }
      2 < temp.CATMENU
      }

      Musst dabei nur auf die Wraps achten, dass du ein sauberes verschachteltes Menü hinbekommst.

      Grüße Patrick
  10. Thomas HirtThomas Hirt 22.07.2013
    Hallo Patrick!
    Danke für dieses gute Script. Was mir noch fehlt: nur die jeweils aktive Kategorie und Subkategorie soll aufgeklappt werden. Leider kriege ich das nicht hin... Hättest du da eine Idee?

    Das habe ich versucht:
    if {
    value.field = uid
    equals.data = GP:tx_ttnews|cat
    }

    Aber so bald man dann in der zweiten Ebene ist, klappt das Menü wieder zu. UID und GP:tx_ttnews|cat stimmen da ja nicht mehr überein. Man müsste nachsehen ob GP:tx_ttnews|cat innerhalb der parent_cat ist...

    Danke,
    Thomas
  11. Bojo Bojo 23.02.2014
    Hi Patrick, sehr schöne Lösung, funktioniert bei dir auch Mehsprachigkeit? Bei mir werden nur die Titel der default Sprache angezeigt.
    Viele Grüße Bojo
    1. Patrick FiedorowiczPatrick Fiedorowicz 24.02.2014
      Hi Bojo,

      vielen Dank für dein Lob :)

      Zur Mehrsprachigkeit - wenn du nur 1 weitere Sprache hast, kannst du dich mit einer Condition behelfen:

      [globalVar = GP:L = 1]
      # 1. Ebene
      lib.catList.10.select.selectFields = IF(title_lang_ol="", title, title_lang_ol) AS title
      # 2. Ebene
      lib.catList.10.renderObj.30.select.selectFields = IF(title_lang_ol="", title, title_lang_ol) AS title
      [global]

      Diese funktioniert so, dass Sie die Übersetzung des Titels statt dem Default-Titel ausliest und diesen, wenn vorhanden, überschreibt.

      Wenn es mehr Sprachen werden, wird es komplizierter, da in tt_news die Übersetzungen der Kategorie-Titel in der tt_news_cat-Tabelle in einem Feld mit | getrennt aufgelistet werden. Da müsstest du dann noch zusätzlich einen StdWrap mit split oder ähnlich einbauen...

      Schöne Grüße
      Patrick
  12. Johannes Johannes 20.08.2014
    Danke, konnte ich gut gebrauchen
  13. Jan KoutJan Kout 09.10.2015
    Lieber Patrick,

    ich habe noch eine Frage - ich habe dein Script in die tt_news.ts-Datei eingefügt und die IDs der Seiten für die Datensätze und für die Detailseite geändert. In der HTML-Vorlage muss ich aber noch sicherlich den oder die Marker einfügen, oder? Heißt der Marker COA? Ich bin leider ziemlich wenig mit Typo3 vertraut, deswegen frage ich schon so was Grundsätzliches. Oder geht es mit dem Typo3 6.2 doch schon ein Stück leichter?

    Liebe Grüße,
    Jan
    1. Patrick FiedorowiczPatrick Fiedorowicz 09.10.2015
      Hi Jan,

      das kommt ganz darauf an, wie du deine Seite mit Typoscript konfiguriert hast...

      Der Marker heißt in meinem Code "lib.catList".
      Wenn du schon von Markern redest, dann wird bei dir im TS so etwas vorkommen wie "page.10.marks.", oder?
      Dann schreibst du z. B.:
      page.10.marks.CATMENU < lib.catList
      Und in deinem HTML-Template baust du an der gewünschten Stelle deinen Marker "###CATMENU###" ein.

      Wenn es nicht klappt, kannst du mich auch gerne direkt anschreiben.

      Grüße Patrick
  14. StephanStephan 08.12.2015
    Vielen Dank! Funktioniert großartig. Evtl. noch der Hinweis, dass "GPvar" unter TYPO3 Version 6 nicht mehr geht. Dort einfach "GP" verwenden.
  15. MarcusMarcus 23.08.2016
    Hat das jemand mit tx_news probiert? Scheinbar brauch man hier die passende Tabelle. table = sys_category funktioniert leider auch nicht.

    Kann jemand helfen?
    1. Patrick FiedorowiczPatrick Fiedorowicz 23.08.2016
      Hi Marcus,

      das müsste schon funktionieren. Statt der tt_news_cat musst du die sys_category verwenden, um alle Kategorien zu ermitteln. Anschließend musst du über mehrere Tabellen joinen, um den News-Artikel-Counter zu bekommen: sys_category -> sys_category_record_mm -> tx_news_domain_model_news

      Grüße
      Patrick
    2. Patrick FiedorowiczPatrick Fiedorowicz 24.08.2016
      Hi Marcus,

      wie der Zufall will, hab ich gerade einen neuen Artikel veröffentlicht, wie man das flexible Kategorie-Menu auch mit tx_news verwenden kann :)
      Schau mal rein: News Kategorien mit Counter

      Grüße
      Patrick

Neuer Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Bitte gib Sie an, um dein Gravatar-Bild anzuzeigen.