24.06.201020:08

Mehrsprachige TYPO3 Extensions: getRecordOverlay richtig einsetzen

Bei der Entwicklung mehrsprachiger Extensions für TYPO3 kommt man früher oder später in die Verlegenheit die richtigen (also in der benötigten Sprache) Datensätze aus der Datenbank zu holen. Viele Entwickler nutzen dazu eigene WHERE Anweisungen mithilfe derer sie den richtigen Datensatz ermitteln. Das sieht dann oftmals so aus:


$where = 'uid = '.$uid.' AND  sys_language_uid = '.$GLOBALS['TSFE']->sys_language_uid.' AND hidden = 0 AND deleted = 0';

Die benötigte Sprache wird direkt gesetzt was zur Folge hat das man evtl. keinen Datensatz geliefert bekommt. Dies ist logischerweise dann der Fall wenn Der Datensatz noch nicht in die betreffende Sprache übersetzt wurde. Hört sich doch gar nicht so übel an?

 

Nicht ganz. Einerseits  bricht man mit den Coding Guidelines und andererseits macht man ein tolles TYPO3 Feature zunichte: den localization mode. Mit dem localization mode kann das Verhalten von TYPO3 bei Mehrsprachigkeit, oder besser das Verhalten von TYPO3 bei fehlenden Sprachdatensätzen, konfigurieren.

 

TYPO3 und Mehrsprachigkeit

 

TYPO3 bietet ja bekanntlich sehr flexible Möglichkeiten um die Internationalisierung (gerne mit I18Y abgekürzt) umzusetzen.

 

Prinzipiell  kann auf Seitenebene mit der Option config.sys_language_mode gearbeitet werden. Diese gibt an wie mit der Seite umgegangen wird. So kann zum Beispiel per strict eine Fehlermeldung angezeigt werden wenn die Seite nicht verfügbar ist. content_fallback hingegen bietet die Seite dann in der konfigurierten default Sprache an.

 

    Auf Inhaltsebene werden per config.sys_language_overlay = 1 nach Übersetzungen gesucht, aber immer alle Elemente angezeigt -- notfalls eben in der default Sprache. Mit dem Wert  hideNonTranslated wird nicht übersetzter Inhalt hingegen versteckt.

     

    Das sind nur die beiden wichtigsten Einstellungen und selbst deren Funktionen habe ich hier nicht gänzlich abgedeckt. Es existieren noch viele weitere Möglichkeiten (wie etwa config.sys_language_softMergeIfNotBlank), aber der Teil hier langt zum Verständnis.

     

    Schaut euch die untenstehende Linksammlung an, dort erfahrt ihr mehr.

     

     

    SQL Anweisung für Mehrsprachige Extensions

     

    Um das oben beschriebene Verhalten auch in eigenen Extension möglich zu machen sollte man darauf achten mehrsprachige Datensätze korrekt aus der Datenbank holen.

     

    Zuerst holt man sich die Standardsprache aus der Datenbank. Das macht man normalerweise mit mit der WHERE Bedingung sys_language_uid = 0.

    Findige TYPO3 User schaffen es aber auch einen Datensatz anzulegen, ohne vorher die Default-Sprache anzulegen. Um diesem Umstand vorzubeugen ändern wir die SQL Anweisung auf folgende Bedingungen ab: Standard-Sprache ODER den übersetzten Datensatz (der dann aber kein parent Element haben darf).

     

      
      <?php
      // we need at last uid, pid, sys_language_uid
      $select = 'uid, pid, sys_language_uid, text, title'
      $table = 'tx_myext_data';
      // we try to get the default language entry (normal behaviour) or, if not possible, currently the needed language (fallback if no default language entry is available)
      $where = '(sys_language_uid IN (-1,0) OR (sys_language_uid = ' .$GLOBALS['TSFE']->sys_language_uid. ' AND l18n_parent = 0))';
      // always (!) use TYPO3 default function for adding hidden = 0, deleted = 0, group and date statements
      $where  .= $GLOBALS['TSFE']->sys_page->enableFields($table);
      $order = '';
      $group = '';
      $limit = '';
      $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery($select, $table, $where, $group, $order, $limit);
      
      while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
      	// check for language overlay if:
      	// * row is valid
      	// * row language is different from currently needed language
      	// * sys_language_contentOL is set
      	if (is_array($row) && $row['sys_language_uid'] != $GLOBALS['TSFE']->sys_language_content && $GLOBALS['TSFE']->sys_language_contentOL) {
      		$row = $GLOBALS['TSFE']->sys_page->getRecordOverlay($table, $row,$GLOBALS['TSFE']->sys_language_content, $GLOBALS['TSFE']->sys_language_contentOL);
      	}
      	if ($row) {
      		// do stuff with the row entry data	like built HTML or prepare further usage
      	}
      }
      ?>
      

      Es folgt eine normale TYPO3 DB Abfrage. Anschließend testen wir auf eine valides Array, ob wir eine andere Sprache überhaupt benötigen und ob die Konfiguration für den localization mode (wie er oben kurz erläutert wurde) vorhanden ist. Wenn ja, ereledigt TYPO3 den Rest: den Overlay-Datensatz mit der gewünschten Sprache ziehen, um damit den vorhandenen (alten) Datensatz ganz oder teilweise zu ersetzen bzw. die row zu löschen. Letzteres müsste evtl. bei gesetzter  hideNoneTranslated Option gemacht werden.

       

      So erhalten wir genau die Datensätze die wir brauchen und können die Ausgabe / Weiterverarbeitung angehen.

       

      Hinweise

      Gegebenenfalls muss sys_language_uid im select mit $TCA[$table]['ctrl']['languageField'] ersetzt werden (global $TCA; Anweisung nicht vergessen!). Ist aber im Normalfall nicht nötig.

       

      Eine Problematik bleibt bestehen: Wenn der Standard-Datensatz versteckt wurde, kann keine Übersetzung gefunden werden (auch wenn diese nicht versteckt ist und angezeigt werden soll).  Hier wäre generell das "mehrere Seitenbaumäume Prinzip" für vorzuziehen.

      Eine andere Möglichkeit wäre es die enableFields Anweisung wegzulassen und erst die fertige (bereits mit getRecordOverlay bearbeitete) row manuell auf hidden, deleted, Gruppen und Zeit zu prüfen. 

       

       

      Referenzen:

       

       

      Wie immer freue ich mich über Feedback und Hinweise. Wenn ich kann helfe ich auch gerne, eine Antwort ist euch in jedem Fall sicher.

       

       

        Kommentar schreiben

        Felder mit * sind Pflichtfelder

        0 Kommentare