Schnellnavigation:

Kategorien

« Mai 2017»
S M T W T F S
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31      

Kopieren Sie diesen Link in Ihren RSS-Reader

RSS 0.91Nachrichten
RSS 2.0Nachrichten

In eigener Sache

Peter Linzenkirchner, Lisardo EDV Beratung in Augsburg. Freelance und Partner für Design- und Webagenturen in Augsburg und München. Pixelgenaue Templates, valides HTML, barrierearm. TYPO3-Projekte, Extension-Programmierung und mehr ... 

Zur Zeit wird gefiltert nach: sprachen
Filter zurücksetzen

02September2010

Sprachumschaltung

Die Sprachumschaltung per TypoScript hängt die GET-Variable L zweimal an die Sprachumschalter. Bisher kein Problem, da die Reihenfolge richtig war, ab Typo3 sind die beiden aber in der falschen falschen Reihenfolge.


[mehr]

Ziel ist die Erstellung einer Extension, die alle Features zur Mehrsprachigkeit bietet, die zur Ausstattung von TYPO3 gehören.

Die Datenbank-Struktur

Diese drei Felder müssen zusätzlich in der Extension in der »ext_tables.sql« angelegt werden:

  1. sys_language_uid int(11) DEFAULT'0'NOT NULL,
  2. l18n_parent int(11) DEFAULT'0'NOT NULL,
  3. l18n_diffsource mediumblob NOT NULL,

Die »ext_tables.php« muss so erweitert werden:

  1. "ctrl"=> Array (
  2.   [--snip--]
  3.   "delete"=>"deleted",   
  4.   'transOrigPointerField'  =>'l18n_parent',
  5.   'transOrigDiffSourceField'=>'l18n_diffsource',
  6.   'languageField'      =>'sys_language_uid',
  7.   [--snip--]

Und das »columns«-Array in der »tca.php« ebenfalls:

  1. "columns"=> Array (
  2.   [--snip--]
  3.   'sys_language_uid'=> array(
  4.     'exclude'=>1,
  5.     'label' =>'LLL:EXT:lang/locallang_general.xml:LGL.language',
  6.     'config'  => array(
  7.         'type'                =>'select',
  8.         'foreign_table'   =>'sys_language',
  9.         'foreign_table_where'=>'ORDER BY sys_language.title',
  10.         'items'       => array(
  11.             array('LLL:EXT:lang/locallang_general.php:LGL.allLanguages', -1),
  12.             array('LLL:EXT:lang/locallang_general.php:LGL.default_value',0)
  13.         )
  14.     )
  15.   ),
  16.   'l18n_parent'=> array(
  17.     'displayCond'=>'FIELD:sys_language_uid:>:0',
  18.     'exclude'  =>1,
  19.     'label'   =>'LLL:EXT:lang/locallang_general.xml:LGL.l18n_parent',
  20.     'config'      => array(
  21.         'type'  =>'select',
  22.         'items'=> array(
  23.             array('',0),
  24.         ),
  25.         'foreign_table'   =>'tx_meineExtension',
  26.         'foreign_table_where'=>'AND tx_meineExtension.uid=###CURRENT_PID### AND tx_meineExtension.sys_language_uid IN (-1,0)',
  27.     )
  28.   ),
  29.   'l18n_diffsource'=> array(
  30.     'config'=> array(
  31.         'type'=>'passthrough'
  32.     )
  33.   ),
  34.   [--snip--]
  35. ),

Wichtig: Damit die Zuordnung der Sprach-Overlays funktioniert, muss oben bei »foreign_table« die korrekte Tabellenbezeichnung der Extension eingegeben werden, ebenso bei »foreign_table_where« – insgesamt also dreimal.

Damit die Redakteure später nicht nur Language-Overlay-Datensätze anlegen, sondern einen Datensatz direkt einer Sprache zuordnen können (um z. B. Datensätze in einer Fremsprache anlegen zu können, ohne dass es zuvor einen Datensatz in der Standardsprache gibt), muss auch noch das »types«-Array in der »tca.php« erweitert werden:

  1. "types"=> Array (
  2.   "0"=> Array("showitem"=>"hidden;;1;;1-1-1, sys_language_uid;;1;;3-3-3,
  3.   [-- snip --]
  4. ),

Damit erscheint im Backend ein DropDown-Menü mit einer Auswahl von allen definierten Alternativ-Sprachen sowie der Auswahl »Alle«.

Im Backend müsste jetzt alles richtig ausgegeben werden: Die Redakteure können neue Datensätze anlegen, diese einer oder allen Sprachen zuordnen, oder nachträglich Datensätze in der Standardsprache übersetzen. Also genauso wie bei den normalen Inhaltselementen.

Natürlich muss die Ausgabe im Frontend das entsprechend berücksichtigen

Ausgabe von sprachabhängigen Texten ins Template

Damit sind nicht die Inhalte aus den Datentabellen gemeint sondern zum Beispiel Überschriften oder Labels für Formularfelder, die ebenfalls den Sprachen angepasst werden müssen. Diese Texte werden zunächst in die »locallang.xml« im pi1-Ordner der Extension eingetragen:

  1. <?xml version="1.0"encoding="utf-8"standalone="yes"?>
  2. <T3locallang>
  3.     <meta type="array">
  4.         <type>module</type>
  5.         <description>Language labelsforplugin tx_meineExtension_pi1</description>
  6.     </meta>
  7.     <data type="array">
  8.         <languageKey index="default"type="array">
  9.             <label index="eindeutigerName">Headline in Defaultsprache</label>
  10.         </languageKey>
  11.         <languageKey index="en"type="array">
  12.             <label index="eindeutigerName">Headline in English</label>
  13.         </languageKey>
  14.         <languageKey index="de"type="array">
  15.             <label index="eindeutigerName">Überschrift in Deutsch</label>
  16.         </languageKey>
  17.     </data>
  18. </T3locallang>

Diese Datei muss in UTF-8 abgespeichert werden, sonst gibt es entweder eine leere Frontend-Seite oder eine Fehlermeldung, je nach TYPO3-Version. Sie darf weder HTML noch Entities enthalten. In der Regel wirds das nicht brauchen (da die Datei ja UTF-8 ist), aber falls doch, gibt es folgende Möglichkeiten:

Entitiy definieren:

  1. <?xml version="1.0"encoding="utf-8"standalone="yes"?>
  2. <!DOCTYPE T3locallang [
  3.     <!ENTITY euro"&amp;euro;">
  4. ]>
  5. <T3locallang>
  6.     <meta type="array">
  7.         <type>module</type>
  8.         <description>Language labelsforplugin tx_tmeineExtension_pi1</description>
  9.     </meta>
  10.     <data type="array">
  11.         <languageKey index="default"type="array">
  12.                 <label index="eindeutigerName">Preis is&amp;euro;</label>
  13.         </languageKey>
  14.     </data>
  15. </T3locallang>

Sieht komisch aus, funktioniert aber. Die nächste Möglichkeit ist wahrscheinlich einfacher:

HTML in »locallang.xml«

  1. <?xml version="1.0"encoding="utf-8"standalone="yes"?>
  2. <T3locallang>
  3.     <meta type="array">
  4.         <type>module</type>
  5.         <description>Language labelsforplugin tx_meineExtension_pi1</description>
  6.     </meta>
  7.     <data type="array">
  8.         <languageKey index="default"type="array">
  9.             <label index="eindeutigerName"><![CDATA[<strong style='color:#00005a;'>und so weiter</strong>]]></label>
  10.         </languageKey>
  11.     </data>
  12. </T3locallang>

Jeder HTML-eintrag muss also mit

  1. <![CDATA[   ]]>

maskiert werden.

Ausgabe ins Frontend

Damit eine Ausgabe möglich wird, muss die »class.tx_meineExtension_pi1.php« erweitert werden:

  1. classtx_meineExtension_pi1extendstslib_pibase {
  2.   // snip
  3.   functionmain($content,$conf){
  4.   // snip
  5.   $this->pi_loadLL();
  6.   // snip
  7.  

 

Die Zeile $this->pi_loadLL(); lädt die notwendige Klasse.

Die eigentliche Ausgabe des Textes erfolgt so:

  1. $txt=$this->pi_getLL('eindeutigerName','default',FALSE);

Die Optionen bedeuten:

  • Name/Bezeichnung des Eintrags in der »locallang.xml«
  • Defaultwert – in der Regel ein englischer Begriff, als Platzhalter, falls der Eintrag in der locallang.xml fehlt
  • TRUE wenn der Wert durch htmlspecialchars() laufen soll

Daten aus den Datentabellen auslesen

Das erweist sich als das eigentliche Problem. Ich habe noch keine endgültige Lösung, aber die folgende funktioniert fürs erste.

1. Schritt: Daten aus der Tabelle holen. Dabei interessiert erstmal nur der WHERE-Teil des sql-Statements, der Rest dürfte klar sein:

  1. if ($GLOBALS['TSFE']->sys_language_content==0){
  2.   $whereClause="pid=xyz".
  3.   ' AND (sys_language_uid IN (-1,0) OR (sys_language_uid='.
  4.   $GLOBALS['TSFE']->sys_language_uid.
  5.   ' AND l18n_parent=0)) '.
  6.   $this->cObj->enableFields($tableName);
  7. }else{
  8.   $whereClause="pid=xyz".
  9.   ' AND (sys_language_uid IN (-1,0) OR (sys_language_uid='.
  10.   $GLOBALS['TSFE']->sys_language_uid.
  11.   ' AND l18n_parent=0)) ';
  12. }

Erläuterung: In der Defaultsprache wird »$this->cObj->enableFields()« aufgerufen, damit die versteckten Datensätze (und die gelöschten etc) nicht sichtbar werden. Bei den Alternativ-Sprachen entfällt das in diesem Schritt sondern folgt erst in einem weiteren. Die Zeile »’ AND (sys_language_uid ….« wählt alle Datensätze aus, die in »sys_language_uid« 0 (= Standardsprache) oder -1 (= alle Sprachen) stehen haben. Sie wählt aber auch alle Datensätze in der Alternativsprache aus, die keinen Eintrag in der Standardsprache haben.

Im nächsten Schritt werden die Sprach-Overlays geholt: die Felder des Datensatzes werden mit den Einträgen in der Alternativ-Sprache überschrieben:

  1. while ($row=$GLOBALS ['TYPO3_DB']->sql_fetch_assoc($newsResult) ){
  2.   if ($GLOBALS['TSFE']->sys_language_content){
  3.       $row=$GLOBALS['TSFE']->sys_page->getRecordOverlay($tableName,$row,$GLOBALS['TSFE']->sys_language_content,$GLOBALS['TSFE']->sys_language_mode=='strict'?'hideNonTranslated':'');
  4.   }
  5. }

Je nach Spracheinstellung werden dabei auch Einträge entfernt – also z. B. wenn sys_language_mode=strict eingestellt ist, werden alle nicht übesetzten Einträge entfernt.

trans2rm ist eine Extension, um den Eintrag »[Translate to xx]« beim Anlegen einer neuen Sprachversion zu unterdrücken. Sie muss nur installiert werden.

Um zu verhindern, dass in leere Titel-Felder (Copy) eingefügt wird, muss ausserdem im Page TSconfig dieser Eintrag hinein:

  1. TCEMAIN.default.disablePrependAtCopy=1</span>
  2.  

Weiterführende Links

Manual auf Typo3.org

Page TSconfig auf Typo3

 

Kategorien: Backend  Kommentare 0
Tags: sprachen, trans2rm
01September2010

Sprachmenü

Als Sprachumschalter wird sinnvollerweise das Sprachmenü von Typoscript benutzt. Hier ein Beispiel, das einen Sprachumschalter einbaut, der zwischen zwei Sprachen wechselt und dazu keine Fahnen benutzt, sondern Text.

  1. temp.nav_top_intern {
  2.     20=HMENU
  3.     20 {
  4.         special=language
  5.         special.value=1,0
  6.         1=TMENU
  7.         1 {
  8.             NO=1
  9.             NO.linkWrap= |&nbsp;&#124;&nbsp;
  10.             NO.stdWrap.cObject=TEXT
  11.             NO.stdWrap.cObject {
  12.                 value=Englisch||German
  13.             }
  14.             USERDEF1< .NO
  15.             USERDEF1 {
  16.                 doNotLinkIt=1
  17.                 stdWrap.typolink.parameter=399
  18.                 stdWrap.typolink.additionalParams= &L=1
  19.             }
  20.         }
  21.     }
  22. }

Dieses Menü hat den Vorteil, dass bei einer fehlenden Übersetzung einer Seite auf eine selbst zu definierende Startseite gesprungen werden kann.

Man kann es auch so aufbauen, dass ein Wechsel zwischen den Textausgabe erfolgt, also in den deutschen Seiten wird nur Englisch als Link ausgegeben und umgekehrt.

  1. temp.nav_top_intern {
  2.     20=HMENU
  3.     20 {
  4.         special=language
  5.         special.value=1
  6.         1=TMENU
  7.         1 {
  8.             NO=1
  9.             NO.linkWrap= |&nbsp;&#124;&nbsp;
  10.             NO.stdWrap.cObject=TEXT
  11.             NO.stdWrap.cObject {
  12.                 value=English
  13.             }
  14.             USERDEF1< .NO
  15.             USERDEF1 {
  16.                 doNotLinkIt=1
  17.                 stdWrap.typolink.parameter=399
  18.                 stdWrap.typolink.additionalParams= &L=0
  19.             }
  20.         }
  21.     }
  22. }
  23.  
  24. [globalVar=GP:L=1]
  25.  
  26. # Kopfmenü mit Sprachumschaltung.
  27. temp.nav_top_intern {
  28.     20.special.value=0
  29.     20.1.NO.stdWrap.cObject.value=Deutsch
  30.     20.1.USERDEF1.stdWrap.typolink.additionalParams= &L=0
  31. }
  32.  

Weiterführende Links

 

 

 

 

Kategorien: Typoscript  Kommentare 0
Tags: menü, sprachen
Besuchen Sie mich auf Google+