userFunc Tutorial

Mit userFunc kann man PHP Inhalte in Typoscript und Templates rendern, beispielsweise für einen Login. In diesem Tutorial wird die Einbindung von userFunc für TYPO3 Versionen 10 und 11 erklärt.

Kategorien: Develop

In diesem Beispiel programmieren wir einen Login. Das ist ein häufiger Use Case, weil oft erweiterte Login Codes ausgeführt werden müssen. 

Und grundsätzlich ist userFunc immer die Antwort auf die Frage: wie führe ich ein Stück PHP Code in einem TypoScript oder Fluid Template aus. 

 

1) Erstellung einer Controller Action

Der beste Ansatz ist es immer, den PHP Code in eine Extbase Controller Action zu legen. Von dort aus hat man Zugriff auf eine Vielzahl an TYPO3 internen Funktionen. 

Es gibt aber auch andere (einfachere) Lösungen für userFunc, die weiter unten gezeigt werden.  

Die Ausgabe erfolgt entweder direkt, indem man einen String zurückgibt. Oder wie in diesem Beispiel, der einen normalen View "List.html" unter Resources/Private/Templates verwendet. 

 

 

namespace MyVendor\MyExtension\Controller;
class LoginController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionController
{
  public function listAction()
  {
    $userData = makeLoginCheck();
    $this->view->assign('userData', $userData);
  }
}

2) Plugin definieren

Der Controller benötigt noch eine Plugin Konfiguration, damit er aufrufbar ist. Diese in ext_localconf.php hinzufügen: 

 

ExtensionUtility::configurePlugin(
   'MyVendor.my_extension',
   'pi1',
   [
       LoginController::class => 'list',
   ],
   [
       LoginController::class => 'list',
   ]
);

3) Typoscript mit userFunc

Und jetzt kann man die userFunc im Typoscript verwenden.

Die Einbindung erfolgt über die Standard Extension Konfiguration, d.h. die Controller Klasse ist bereits bekannt, ein zusätzliches Include ist nicht notwendig. 

Man beachte die Detail-Unterschiede in den Schreibweisen: MyExtension und my_extension! Das ist häufigste Fehler wenn irgendwas nicht funktioniert: die Schreibweisen sind je nach Funktion CamelCase oder underscore_case.

 

#Einbindung ins PageTemplate
page = PAGE
page {
    (...)
    10 = FLUIDTEMPLATE
    10 {
        variables {
            mylogin = USER_INT
            mylogin {
                userFunc       = TYPO3\CMS\Extbase\Core\Bootstrap->run
                vendorName     = MyVendor
                extensionName  = MyExtension
                pluginName     = pi1
                controllerName = Login
            }
        }
    }
}
#Einbindung als USER_INT
10 = USER_INT
10 {
      userFunc       = TYPO3\CMS\Extbase\Core\Bootstrap->run
      vendorName     = MyVendor
      extensionName  = MyExtension
      pluginName     = pi1
      controllerName = Login
}

Achtung: in vielen Tutorials findet man noch "switchableControllerActions" in der Konfiguration. Diese sind in Version 11 deprecated und werden in Version 12 entfernt.

Die Lösung besteht jetzt darin, mehrere Plugins zu konfigurieren, es wird immer die erste Action in der Liste ausgeführt. 

4) Einbindung ins Fluid Template

Obwohl man die userFunc als "USER_INT" definiert hat, kann es bei manchen Fluid Renderings unerwartete Cache Probleme geben. Statt der erwarteten Ausgabe bekommt man nur sowas hier:

 

<!--INT_SCRIPT.759ce9c8a82973a244dd93bae0375cc8-->

Damit bekommt man die Ausgabe der gerenderten userFunc Ergebnisse:

 

<f:format.raw>{mylogin}</f:format.raw>

Andere Möglichkeiten für userFunc Einbindung

Man kann auch eine ganz normale PHP Klasse per userFunc einbinden.

Das erste Beispiel ist eine einfache Funktion "getUserFunc", die Übergabe von einem Parameter wird mit "var1" gezeigt. 

Das zweite Beispiel ist ein HMENU mit "getUserFuncMenu", wie man es von früher kennt (hauptsächlich für Backward Compatibility). Hier noch der Link zur Doku.

Achtung: der Parameter "includeLibs" wurde mit Version 8 entfernt, früher konnte man damit noch beliebige Pfade für die Klasse setzen. In diesem Beispiel liegt die Klasse unter "Classes/Userfunc" und wird damit automatisch geladen. Über den Namespace Eintrag wird der genaue Pfad angegeben, d.h. sie kann auch unter "Classes/FooBaz" liegen. 

Historisches: vor Version 7 mussten die Klassen- und Funktionsnamen mit "user" beginnen, das ist nicht mehr notwendig. Die Namen können beliebig vergeben werden.

namespace MyVendor\MyExtension\Userfunc;
class Someclass
{
    public function getUserFunc(string $content, array $conf): string
    {
        $var1 = $conf['userFunc.']['var1'];
        return 'Hello from Userfunc';
    }
    public function getUserFuncMenu(string $content, array $conf): array
    {
        $var1 = $conf['userFunc.']['var1'];
        return [
            [
                'title' => 'Menu1',
                '_OVERRIDE_HREF' => '/some/link.html',
            ],
            [
                'title' => 'Menu2',
                '_OVERRIDE_HREF' => '/some/other/link.html',
            ]
        ];
    }
}

Typoscript für einfache Funktion

 

10 = USER_INT
10 {
  userFunc = MyVendor\MyExtension\Userfunc\Someclass->getUserFunc
  userFunc.var1 = 222
}

 

Typoscript für HMENU

 

lib.mymenu = HMENU
lib.mymenu {
    special = userfunction
    special.userFunc = MyVendor\MyExtension\Userfunc\Someclass->getUserFuncMenu
    special.userFunc.var1 = 111
    1 = TMENU
    1.wrap = <ul class="level-1">|</ul>
    1.NO = 1
    1.NO {
        wrapItemAndSub = <li>|</li>
    }
}

 

Fluid Einbindung über:

 

<f:cObject typoscriptObjectPath="lib.mymenu" />

Es ist Zeit durchzustarten

Egal, welche Herausforderung Sie bei Ihrer Website oder in Ihrer IT haben, wir liefern kompetente und zuverlässige Lösungen.