TYPO3: Eigene Extension lokalisieren

16. August 2011 in TYPO3 von Leo

Um die eigene Extension Mehrsprachig zu machen und trotzdem so flexibel wie möglich zu halten, nutzt man die locallang. Früher handelte es sich hier um ein simples PHP-File mit einem Array, heute ist es ein XML-File mit einer besseren struktur und Übersicht, wo es auch keine Zeichensatz Probleme gibt.

Um für die eigene Extension eine locallang nutzen zu können, gehen wir folgendermassen vor:

Als erstes legen wir die locallang.xml an. Meist direkt im Extension Verzeichnis zu finden, sprich typo3conf/ext/meineExtension/locallang.xml. Falls wir jedoch mehrere pi’s in unserer Extension haben, können wir in jedem pi eine eigene locallang Anlegen welche dann jeweils genutzt wird.

In unsere so eben erstelle locallang.xml Datei kopieren wir nun folgenden XML-Code:

<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<T3locallang>
	<meta type="array">
		<type>module</type>
		<description>language Labels</description>
	</meta>
	<data type="array">
		<languageKey index="default" type="array">
			<label index="captchaErrorMessage">Captcha incorrect!</label>
		</languageKey>

		<languageKey index="de" type="array">
			<label index="captchaErrorMessage">Captcha nicht korrekt!</label>
		</languageKey>
	</data>
</T3locallang>

Hier haben wir 2 Sprachen. Die default Sprache (englisch) und “de” für Deutsch. Die Übersetzungen werden als Phrasen gemacht, welche jeweils in labels abgespeichert werden. Die labels erhalten einen namen (index=”") und werden im languageKey Array eingefügt. Oben anhand des Beispiels zu sehen.

In unserer PHP-Class der Extension (falls mehrere muss es in jeder gemacht werden), müssen noch folgende Variabeln angegeben werden, was falls ihr mit dem Extension Kickstarter arbeitet eigentlich erledigt sein sollte. Direkt in der Class gebt ihr folgendes an:

public $scriptRelPath = 'class.ux_tx_tipafriend.php'; // Path to this script relative to the extension dir.
public $extKey = 'x4etipafriendrecap'; // The extension key.

So kann TYPO3 die korrekte localconf holen. Wäre unsere Datei in einem pi Verzeichnis, wäre der $scriptRelPath demnach z.B. pi1/class.ux_tx_tipafriend.php.

Damit die Sprachen nun noch geladen werden, müssen in der Main-Funktion noch folgendes gemacht werden:
Zuerst muss die conf in $this->conf geschrieben werden:

$this->conf = $conf;

Danach (muss danach sein!) muss die locallang selbst noch geladen werden:

$this->pi_loadLL();

Fertig!

Um jetzt auf die Phrasen zuzugreifen, nutzen wir folgende Zeile:

$error = $this->pi_getLL('captchaErrorMessage');

Fluid: Select mit zusätzlicher Option

30. Juni 2011 in TYPO3 von Leo

Lange war ich auf der Suche nach einer einfachen Möglichkeit in einem Fluid Select eine default Option anzufügen, sprich eine Option wie “Produkt auswählen” oder ähnlich. Schlussendlich war die beste lösung einen ViewHelper für das Select zu erstellen.
Dabei bin ich erstmals auf folgenden Artikel gestossen: Fluid: Select in Formularen mit weiteren Optionen. Leider führte dies zu einer Fehlermeldung, und ausserdem waren in meinem Fall noch ein paar Anpassungen nötig.

Hier nun eine kurze Anleitung:
Als erstes erstellen wir einen neuen ViewHelper mit dem Namen SelectViewHelper.php unter typo3conf/ext/meineExt/Classes/ViewHelpers/. In diesen fügen wir nun folgenden Code ein:

class Tx_MeineExt_ViewHelpers_SelectViewHelper extends Tx_Fluid_ViewHelpers_Form_SelectViewHelper {

    public function initializeArguments() {
        parent::initializeArguments();
        $this->registerArgument('additionalOptions', 'array', 'Associative array with values to prepend', FALSE);
    }

    protected function getOptions() {
        $options = parent::getOptions();
        $additionalOptions = array();
        foreach ($this->arguments['additionalOptions'] as $key => $value) {
            $additionalOptions[$key] = $value;
        }
        $return = $additionalOptions + $options;
        return $return;
    }

}

Hierbei noch den Namen der Klasse abändern und “meineExt” durch den eigenen Extension namen ersetzen.

Nun bearbeiten wir unser Fluid Template wo das Custom Select hin soll. Dort fügen wir zuoberst folgende Zeile ein:

{namespace meineExt=Tx_meineExt_ViewHelpers}

Der namespace kann eigentlich beliebig heissen, wie man es halt gerne hätte.

Und fügen dann an einer beliebigen Stelle darunter unser Select ein:

<meineExt:select additionalOptions="{- : '-- Produkt wählen --'}" sortByOptionLabel="name" name="products" property="products" options="{allProducts}" optionValueField="uid" optionLabelField="name" />

Der Parameter additionalOptions ist also für unseres Zusätzliche Feld, dort kann ein beliebiger Wert angegeben werden.

Wichtig: In meinem Fall wurde in der getOptions Methode in unserer ViewHelper Klasse keine array_merge verwendet, wie im Original Code, da die Array-Keys noch gebraucht wurden.

TYPO3: Facebook Like Button per TypoScript

8. November 2010 in TYPO3 von Leo

Mittlerweile findet man den Facebook “Like”-Button ja überall. Dazu gibt es auch passende Extensions im TYPO3 Ext Repository, mit welchen man den Like Button sehr einfach einbauen kann. Jedoch waren diese Extensions nur sehr schwer anpassbar (HTML musste im PHP Code angepasst werden) und man muss sie als Plugin manuell auf jeder Seite platzieren – mühsam!
Deshalb fragte ich mich ob es auch eine bessere Variante gibt – sicher, per TypoScript!
Kurz in Google nach einer Variante gesucht und dabei gleich auf folgendes gestossen, klick. Alles in allem kein schlechtes TypoScript Snippet, jedoch nicht geeignet für mich geeignet, was ich nach einer weile feststellen musste, da ich tt_news im Einsatz habe. Wird nun in der SINGLE-Ansicht ein solcher Button platziert, wird jeweils nur die Seite “geliked”, nicht die News mit der ID. Dies durfte so natürlich nicht sein, da der User so immer auf eine falsche Seite mit einer Warnung kommen würde.

Also habe ich den Code etwas angepasst:

lib.facebook = COA
lib.facebook {
	10 = TEXT
	10.typolink.parameter.data = getIndpEnv:REQUEST_URI
	10.typolink.returnLast = url
	10.dataWrap = http://meinedomain.ch|
	10.rawUrlEncode = 1

	wrap = <iframe src="http://www.facebook.com/plugins/like.php?href=|&layout=button_count&show_faces=true&width=450&action=like&colorscheme=light&height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:450px; height:21px;" allowTransparency="true"></iframe>
}

Es muss noch die baseURL oben angepasst werden. Eigentlich wäre es auch möglich direkt die baseURL zu holen, jedoch habe ich dies im obigen Code nicht gemacht da meine baseURL mit einem Slash (“/”) endet, was schlussendlich einen Doppel-Slash verursachen würde.
Wer die baseURL verwenden möchte ersetzt die Zeile mit folgendem:

10.dataWrap = {TSFE:baseUrl}|

Viel Spass!

Indexed Search installation und konfiguration

5. November 2010 in TYPO3 von Leo

Viele haben anscheinend Probleme mit Indexed Search, der TYPO3 Sucherweiterung. Hier nun ein einfach erklärtes Tutorial für die Installation und Konfiguration von Indexed Search, Schritt für Schritt.
1. Installieren der Extension über den Extension-Manager (da es sich hier um eine System Extension handelt ist sie bereits vorhanden).
2. Kopieren des Templates aus dem Verzeichnis “typo3/sysext/indexed_search/pi/indexed_search.tmpl” nach “fileadmin/templates/ext/indexed_search.tmpl” (Pfad kann aber auch frei gewählt werden, jedoch sollte das Template nicht im typo3/ Verzeichnis sein da es ansonsten bei einem Update überschrieben wird!).
3. Nun auf der obersten Seite ins TypoScript Setup folgenden Code einfügen:

#################################
# Indexed Search aktivieren
#################################
config.index_enable = 1

Dieser Code aktiviert Indexed Search und würde gleich mit dem caching beginnen. Wir benötigen jedoch noch zwei Marker in unserem Template (eigentlich freiwillig, aber empfohlen), welche den zu cachenden Bereich begrenzen, also den Bereich den die Suche dann auch durchsucht und in den Suchergebnissen widerspiegelt.
4. Also fügen wir folgende zwei Marker ein, welche unseren Inhalt umschliessen:

<!--TYPO3SEARCH_begin-->
...
<!--TYPO3SEARCH_end-->

5. Nun sollten die Seiten beim ersten Aufruf für indexed search gecacht werden. Dies kann man im Modul “Info” im Backend überprüfen. Beim Dropdown oben “Indexed Search” auswählen und links im Seitenbaum auf die oberste Seite klicken. Ist nach einem Seitenaufruf über das Frontend nun die Seite gecacht worden sieht man nun eingen kurzen Ausschnitt des gecachten Inhalts.
6. Nun wird im TS Template noch folgender Code im Setup benötigt, welcher noch etwas abgeändert werden muss:

config.language = de
config.locale_all = de_DE
config.sys_language_uid = 0

config.index_externals = 1
# Anzahl der anzuzeigenden Resultate pro Seite
plugin.tx_indexedsearch._DEFAULT_PI_VARS.results = 10
plugin.tx_indexedsearch {
  # ID der obersten Seite
  search.rootPidList = 2
  show.rules = 0
  show.advancedSearchLink = 0
  show.L1sections = 0
  templateFile = fileadmin/templates/ext/indexed_search.tmpl
  _DEFAULT_PI_VARS.lang = 0
  browseBoxWrap = <div class="browsebox">|</div>
  pageWrap = <span>|</span>
}

So weit so gut, Indexed Search wurde nun eingerichtet und läuft hoffentlich!

Pagebrowser (umblättern) funktioniert nicht:

Falls der Pagebrowser (also das Umblättern von Seiten bei Suchergebnissen) nicht funktioniert, rate ich jedem mal die Extension “accessible_is_browse_results” anzusehen, welche das ganze sehr wahrscheinlich wieder funktionstüchtig machen wird. Man kann das ganze jedoch auch ohne zusätzliche Extension gerade biegen, der Fehler wird durch das Umblättern per JavaScript ausgelöst, aber mehr dazu vielleicht mal später.

Eigene Flexform in Extension einbauen

1. Oktober 2010 in TYPO3 von Leo

Eine Flexform kann in einer Extension benutzt werden, um eingaben und weiteres übers Backend an der Extension vorzunehmen.
Um solch eine Flexform in der eigenen Extension hinzuzufügen geht man folgendermassen vor:

1. Man legt in der eigenen Extension eine XML Datei an, am besten flexform.xml oder wie oft üblich flexform_ds.xml.

2. Nun fügt man folgende Zeilen in seine XML Datei ein:

<T3DataStructure>
  <sheets>
    <sDEF>
      <ROOT>
        <TCEforms>
          <sheetTitle>Optionen</sheetTitle>
        </TCEforms>
        <type>array</type>
        <el>
           <eine_option>
              <TCEforms>
              <label>Modus</label>
              <config>
              <items type="array">
                 <numIndex index="0" type="array">
                    <numIndex index="0">Listen Ansicht</numIndex>
                    <numIndex index="1">Detail Ansicht</numIndex>
                 </numIndex>
              </items>
              </config>
            </TCEforms>
           </eine_option>
        </el>
      </ROOT>
    </sDEF>
  </sheets>
</T3DataStructure>

Dies wäre ein Beispiel für eine Einstellung, welche natürlich so alleine nicht funktioniert.

3. Als nächstes müssen wir die Flexform in unserer Extension sozusagen registrieren, bzw. einbinden. Folgender Code kommt in die Datei “ext_tables.php” unserer Extension:

$TCA['tt_content']['types']['list']['subtypes_addlist'][$_EXTKEY.'_pi1'] ='pi_flexform';
t3lib_extMgm::addPiFlexFormValue($_EXTKEY.'_pi1', 'FILE:EXT:'.$_EXTKEY . 'pi1/flexform_ds.xml');

Der Pfad in Zeile 2 muss je nachdem wo eure Flexform liegt und heisst noch angepasst werden.

4. Um nun auf die Einstellungen als Variabeln, welche wir über die Flexform eingegeben haben im Code der Extension zugreifen zu können, benötigen wir folgenden Code am Anfang (Main):

$this->pi_initPIflexForm();

Und um wirklich auf die Variabeln zugreifen zu können folgendes:

$this->code = $this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'eine_option', 'sDEF');

Übrigens, ab TYPO3 4.2.1 soll folgender Code reichen um auf die Einstellungen zuzugreifen:

$this->code = $this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'eine_option');

Eine Ausführliche Beschreibung zu Flexformen gibt es in der TYPO3 Wiki.

TYPO3 und PHPUnit: Code Testen (+ Hello World)

5. August 2010 in TYPO3 von Leo

Das automatisierte Testen von Code wird immer wie beliebter. Deshalb habe ich diese Woche bei 4eyes die Aufgabe erhalten, mir das ganze mal anzusehen und gleich Tests in TYPO3 zu schreiben um eine Extension zu testen.

Anders als mit Selenium, wird hier jedoch direkt der (PHP) Code getestet, also bevor schon die fertigen Resultate da sind, testet man was zwischen Start und ende passiert. So kann man mit PHPUnit z.B. testen ob eine bestimmte Funktion im Code ein bestimmtes Resultat zurück liefert.

Nachdem ich die Funktionsweise dann auch verstanden habe und das Testen möglich war (nach ein paar Startschwierigkeiten), schrieb ich zuerst mal einen kleinen Hello World Test. Doch bevor wir zum Test kommen, zeige ich euch wie ihr alles richtig einrichtet.

Installation

Die Extension PHPUnit (extkey: phpunit) herunterladen und installieren. Hier findet ihr die Extension auf Typo3.org, klick.

Nach der Installation erstellt ihr in einer eurer Extensions einen Ordner namens “Tests”. Der Pfad wäre also:

typo3conf/ext/deineExtension/Tests

Nun erstellt ihr im gerade erstellten Ordner ein neues PHP File mit folgendem Namensschema:

tx-extKey_HelloWorld_testcase.php

Wichtig ist hierbei eigentlich nur das “_testcase” am ende, da dies PHPUnit sagt, dass es sich hier im ein Test File handelt (PHPUnit scannt alle ext Verzeichnise automatisch).

Nun füllen wir das PHP File mit dem standardmässig benötigten Code:

<?php
require_once 'PHPUnit/Framework.php';

class tx_extKey_HelloWorld_testcase extends tx_phpunit_testcase {

}

?>