userFunc Tutorial

->Ab TYPO3 Version 6.2 gab es einige Änderungen, daher hier ein Update

Dieses Tutorial ist für Version 4.5:
Eine „user_func“ kann an jeder Stelle im TypoScript verwendet werden, um PHP Code einzubinden. Los geht es mit diesem Tutorial, da werden schon mal die einfachsten Prinzipien erklärt: http://www.typo3wizard.com/de/snippets/allgemeine-probleme-und-loesungen/einfache-userfunc.html

Jetzt habe ich das ganze etwas ausgebaut:

1. Code includieren

includeLibs.user_mylinks = EXT:veranstaltungen/user_teaserlink.php

Zuerst muss ich den Pfad zu meiner Datei definieren. Nach dem includeLibs steht der Name der Klasse.

2. Funktion oder Klasse programmieren

class user_mylinks {
    var $cObj;// The backReference to the mother cObj object set at call time

    function main($content, $conf) {
        $value = $conf['value'];
        return $content;
    }

	function makeTeaserLink()
	{
		$link = trim($this->cObj->data["image_link"]);
		$outputlink = "";

	        if (strpos($link,"www.") === 0)
		{
			$outputlink = "http://".$link;
		}
		else
		{
			$outputlink = $link;
		}

		return '$outputlink';
	}
}

Hier verwende ich eine einfache Funktion, um Links zu parsen, da mir die String-Funktionen im TypoScript fehlen. Die Funktion macht in echt natürlich einiges mehr, aber dann wird es unübersichtlich.

Wichtig ist hier: Die Klasse muss mit „user_“ beginnen, sonst passiert gar nichts!

3. Einbindung in TypoScript

Die Einbindung in TypoScript geht sehr einfach über:

10 = USER
10.userFunc = user_mylinks->makeTeaserLink
oder
10 = USER
10.userFunc = user_myfunction

Variante 1 ist eine Klasse, da muss der Name der Klasse mit „user_“ beginnen. Variante 2 ist eine Funktion, da muss der Funktionsname mit „user_“ beginnen.

Oder man bindet es mit einer lib ein, wie im ersten Tutorial gezeigt:

temp.info = USER
temp.info
{
  userFunc =user_mylinks->main
  value=atest
  color=#11FAAA
}
page.XX<temp.info

Daten übergeben

In der Funktion hat man Zugriff auf „data“ aus TypoScript, was sehr praktisch in einer Datenbankabfrage ist:

20 = CONTENT
20 {
     table = tt_content
     select {
        pidInList = this
        orderBy = sorting
        where= colPos=1
        languageField = sys_language_uid
      }
      renderObj = COA
      renderObj {
          10 = USER
          10.userFunc = user_mylinks->makeTeaserLink
      }
}

Wenn ich jetzt in der userFunc $this->cObj->data["image_link"] aufrufe, bekomme ich den Wert aus dem jeweiligen Datenbankeintrag. In diesem Beispiel manipuliere ich den eingetragenen Link aufs Bild.

Das erste Tutorial zeigt außerdem, wie man Daten aus value über $conf[„value“] verwendet. In den Kommentaren findet sich außerdem ein Hinweis wie man GET-Parameter abfragen kann.

Man kann die userFunc auch in Conditions verwenden, dazu gibt es hier ein Beispiel. Allerdings würde ich das nicht in die localconf, sondern eine eigene Datei schreiben. Dazu muss ich nur das include aus Schritt 1 hinzufügen.
Achtung: bei Conditions sind nur Funktionen, keine Klassen erlaubt: http://dmitry-dulepov.com/article/interesting-issue-with-conditions.html

Links:

7 Gedanken zu “userFunc Tutorial

  1. Hi Arne,

    ich glaube da läufst du in ein TypoScript Grundsatzproblem. Vermutlich wird deine UserFunc aufgerufen, bevor der Teil den du gepostet hast ausgeführt wurde.

    TypoScript ist ja vom Prinzip her ein Array, und kein Programmiercode. Und wie die Reihenfolge beim Abarbeiten der Array-Einträge ist weiß ich nicht.
    Schau mal ob es hilft, ihn in ein temp Objekt zu packen. Außerdem gibt es die Reihenfolge: 10. kommt vor 20., und auf welcher Ebene dein Objekt ist: 10.10 oder 10.10.10.
    Evtl. hilft es auch das USER Objekt durch USER_INT oder PHP_SCRIPT zu ersetzen: http://www.typo3.net/tsref/cobject/user/
    Wie genau das abgearbeitet wird und ob man die Reihenfolge beeinflussen kann müsstest aber jemanden fragen der sich mit Typo3 Core auskennt.

    Wenn es irgendwie geht würde ich ansonsten das parsen vom String in PHP machen:

    $input = $conf["value"]; //ABC#DEF#EEE-111-222-333-444#GHI
    $data = explode("#",$input);
    echo ($data[2]); //EEE-111-222-333-444
    

    http://at.php.net/manual/de/function.explode.php

    LG Andrea

  2. Hallo Andrea,

    danke für die flinke Antwort. Das Beispiel funktioniert, allerdings nur, wenn das feste Werte sind. Da war mein Pseudocode wohl auch doof für… es kommt schlicht nichts geparstes in der userFunc an.

    Bei mir zum Beispiel geht es konkret um ein Textfeld, das ich splitte und von dem ich mir dann den x. Eintrag nehme.

    So sieht das konkret aus (hoffe, es kommt richtig an):

        [file] => TEXT
        [file.] => Array
            (
                [data] => field:field_data
                [split.] => Array
                    (
                        [token] => #
                        [cObjNum] => 1
                        [1.] => Array
                            (
                                [current] => 1
                            )
     
                        [returnKey] => 1
                    )
     
            )
     

    Das ist der Dump des Arrays und bildet 1:1 auch das ab, was ich per TS vorgebe. Nur eben leider vor und nicht nach dem Parsen. Ich kriege meine Vorgaben überliefert, aber nicht das Ergebnis. Scheint mir irgendwie unlösbar zu sein :-/ Herauskommen sollte eigentlich etwas wie

    EEE-111-222-333-444
    aus einem String wie
    ABC#DEF#EEE-111-222-333-444#GHI

    (oder so ähnlich)

  3. Hi Arne,

    damit kann ich die myVar übergeben:

    includeLibs.user_randomquote = fileadmin/user_myClass.php
    
    myVar = TEXT
    myVar.value = test
    
    page.10.marks {
     
     CONTENT = COA
     CONTENT {
    	 10 = USER
    	 10.userFunc = user_myClass->main
    	 10.value < myVar
    	}
    
    }

    In der Funktion gibt var_dump($conf) folgendes:

    array(3) {
      ["userFunc"]=>
      string(22) "user_randomquote->main"
      ["value"]=>
      string(4) "TEXT"
      ["value."]=>
      array(1) {
        ["value"]=>
        string(4) "test"
      }
    }

    Damit steht der Wert Test in $conf["value."]["value"]:

    echo "Conf: ".$conf["value."]["value"];
  4. Mist, da hat der wohl was beim Kommentieren geschluckt. Vielleicht so besser:

    myVar = TEXT
    myVar.value = test
    10 = USER
    10.userFunc = user_myClass->main
    10.myVar < myVar
    

    In 10.myVar steht dann "TEXT" statt "test", egal wie ich es übergebe (auch myVar.value etc. klappt nicht).

  5. Hi,

    in Deinem Beispiel werden Werte direkt dem assoziativen Array $conf zugewiesen. Siehe:

    […]
    userFunc =user_mylinks->main
    value=atest
    color=#11FAAA
    […]

    Weißt Du zufällig einen Weg, auch Werte aus Variablen als Variable an die userFunc zu übergeben? In folgendem Beispiel

    myVar = TEXT
    myVar.value = test
    10 = USER
    10.userFunc = user_myClass->main
    10.myVar cObj funktioniert in meinem Fall nicht als Workaround, da ich in einer bestimmten Zeile in einem FCE von TemplaVoila hänge und nur das gesamte TV-Objekt bekomme, nicht aber gezielt diese Zeile.

Die Kommentarfunktion ist geschlossen.