Fallunterscheidungen from hell

Es gibt viele Weg, um mittels TypoScript an Daten zu kommen. Der getText-Datentyp ist dabei eine geniale Werkzeugkiste. Und eine Reihe von Fallunterscheidungen anhand eines einheitlichen Kriteriums/Keys rufen regelrecht nach einem CASE-cObject.

Ein Beispiel, wie man Fallunterscheidungen mit TypoScript NICHT umsetzt, will ich kurz teilen, und erklären, warum man das so nicht machen will.

Weiterlesen

Language-Handling from hell

Die Behandlung von Mehrsprachigkeit in TYPO3 ist sehr flexibel. Manche Möglichkeiten sind „neuer“ (z.B XLIFF), andere sind schon immer mit an Board gewesen. Viele Wege führen ans Ziel – und das sorgt wohl manchmal auch für Verwirrung und Verirrung…

Ein Beispiel, wie man Language-Handling mit TypoScript NICHT umsetzt, will ich kurz teilen, und erklären, warum man das so nicht machen will.

Weiterlesen

Löschen doppelter Datensätze aus MM-Tabellen

Es gibt unterschiedliche Gründe, warum es passieren kann, dass in MM-Tabellen doppelte Datensätze enthalten sind. Oft stammen die Duplikate aus unglücklichen Import- oder Migrationsskripten, oft sind sie entstanden, weil die Tabellenstruktur zu spät strikt genug definiert wurde.
Das Kind ist nun aber schon in den Brunnen gefallen, und wir wollen es retten.
Mit ein wenig Schiebereien klappt das im MySQL recht fix.

Weiterlesen

EXT:DCE – Upgrade to FAL-based files

Die Dynamic Content Elements (DCE) speichern Datei-Felder nun auch per FAL-Relation, also via File Abstraction Layer von TYPO3. Leider gibt es hierfür keinen Upgrade-Wizard. Man kann sich aber mit ein wenig PHP-Code passende SQL-Befehle generieren, um das Upgrade der Extension durchzuführen und die eigenen Content-Elemente entsprechend anzupassen.

Weiterlesen

Kategorien in EXT:solr nutzen

Schnell kommt man an den Punkt, an dem man Solr zusammen mit Kategorien bzw. Hierarchien als Facetten nutzen möchte. Die kurze Zusammenfassung meiner ersten Erfahrungen und Lösungswege:

Datenstruktur

Die zu kategorisierenden Datensätze müssen mittels System Kategorien (sys_category) gruppiert werden. Hierfür braucht gar nicht viel im TCA rumhantiert zu werden, da der TYPO3 Core das passende Hilfsmittel (ExtensionManagementUtility::makeCategorizable()) liefert .

Kategorien indizieren

Wie die Kategorie-Zuordnung mit indiziert wird, erklärt Steffen in seinem Blog-Beitrag „EXT:solr – Use categories as hierarchical facets„.
(Inzwischen ist „category“ als Feld in Solr vorhanden, sodass kein dynamisches Feld mehr nötig ist (category_stringM => category))

plugin.tx_solr.index {
  fieldProcessingInstructions {
    category = categoryUidToHierarchy
  }
  queue.MYTYPE.fields {
    category = SOLR_RELATION
    category {
      localField = categories
      foreignLabelField = uid
      multiValue = 1
    }
  }
}

Durch den Beitrag stößt man auch auf die Details der Implementierung, v.a. die Field Processors und den konkreten categoryUidToHierarchy (Classes/FieldProcessor/CategoryUidToHierarchy.php). Beim Blick in den Code wird klar, dass er nur mit Systemkategorien arbeitet.

Frontend-Ausgabe

Seit die Solr-Extension auf Fluidtemplates aufbaut, ist die Konfiguration der Facette vereinfacht (Früher war ein HMENU nötig):

plugin.tx_solr {
  search {
    faceting {
      facets {
        category {
          label = Category
          field = category
          type = hierarchy
        }
      }
    }
  }
}

Damit nutzt Solr automatisch das Hierarchy-Partial, und man bekommt einem Baum aus Kategorie-UIDs und der Anzahl der enthaltenen Datensätze angezeigt.

Und die Kategorie-Titel? Dafür braucht es einen kleinen Kniff mit TypoScript und eine kleine Änderung am Fluid-Template.

Via TypoScript legen wir uns ein cObject bereit, das uns den Titel einer System-Kategorie ausgibt:

lib.tx_solr.sys_category_title = RECORDS
lib.tx_solr.sys_category_title {
   source.current = 1
   tables = sys_category
   dontCheckPid = 1
   conf.sys_category = TEXT
   conf.sys_category.field = title
   conf.sys_category.htmlSpecialChars = 1
}

Im Hierarchy-Partial ersetzen wir in der Section ‚hierarchyTree‘ das {childNode.label} gegen:

<f:cObject typoscriptObjectPath="lib.tx_solr.sys_category_title">{childNode.label}</f:cObject>

 

Fertig!

 

Links

(Artikel basiert auf TYPO3 8.7.16 und EXT:solr 8.0.3)

Caching Framework: automatisch Cache leeren bei Datensatzänderung

Das Caching Framework lässt sich gut verwenden, um aufwändig generierte/abgefragte Daten zur Wiederverwendung schneller parat zu haben. Die prinzipielle Funktionsweise haben wir in „Caching Framework nutzen“ erklärt und findet sich auch in der Doku sowie in zahlreichen anderen Blogs.
Was aber oftmals fehlt: wie aktualisiert man den Cache bzw. invalidert ihn bei Veränderung der Daten?

Häufig hängt der Inhalt des Caches von Datensätzen ab. D.h. der Cache-Inhalt veraltet, wenn sich ein Datensatz verändert. Und damit ist auch der Ansatzpunkt für die Invalidierung klar: der processDatamap_afterDatabaseOperations-Hook im DataHandler. Er wird immer nach Datenbankoperationen („new“ bzw. „update“) aufgerufen und bekommt auch den Taballennamen mit übergeben. Somit ist es recht einfach, die eigenen Datensätze zu erkennen und auf die Veränderung zu reagieren:

EXT:my_extension/Classes/Hooks/DataHandler.php:

<?php
namespace MyVendorName\MyExtension\Hooks;

use TYPO3\CMS\Core\Cache\CacheManager;
use TYPO3\CMS\Core\Utility\GeneralUtility;

class DataHandler
{
    public function processDatamap_afterDatabaseOperations($status, $tableName, $recordId, array $databaseData, \TYPO3\CMS\Core\DataHandling\DataHandler $dataHandler)
    {
        if ($tableName === 'tx_myextension_domain_model_example') {
            $cache = GeneralUtility::makeInstance(CacheManager::class)->getCache('myCache');
            $cache->flushByTag('tag_123');
        }
    }
}

Dann noch am Hook registrieren, und fertig:

EXT:my_extension/ext_localconf.php

$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['processDatamapClass']['myextension_clearcfcache'] = 'MyVendorName\\MyExtension\\Hooks\\DataHandler';

Links