Typo3: Link zu einer Seite im Frontend aus Scheduler-Task / dem Backend-Kontext oder CLI-Job erzeugen

Jeder kommt früher oder später an diesen Punkt: Er ist in Typo3 in einem Context wie einem Scheduler Task oder CLI Job und möchte einen Link zu einer Seite im Frontend generieren, z.B. um zyklisch eine E-Mail zu generieren, die einen Link zum Frontend enthält.

Jeder Typo3-Entwickler geht hier zunächst den gewohnten Weg: Der UriBuilder. Den Code kopiert man sich aus einem Controller oder der Typo3 Doku – und er sieht ungefähr so aus:

$objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Extbase\Object\ObjectManager::class);
$uriBuilder = $objectManager->get(\TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder::class);
$uri = $uriBuilder
  ->reset()
  ->setTargetPageUid(199)
  ->setArguments(['test'=>99])
  ->build();

Funktioniert wunderbar im Frontend-Context des Controllers – aber was passiert im Scheduler / Backend-Kontext?
Aus dem Link wird etwas in dieser Art:
/typo3/index.php?route=%2Fmodule%2Fsystem%2FtxschedulerM1&token=xxx&test=99
Für das Problem leider unbrauchbar. Und wieder eines der Themen, bei der man denkt: „Ist ganz einfach zu lösen“ – und sich dann wundert, wenn man nach einigen Stunden immer noch nicht die richtige Lösung finden konnte.

Leider ist das Web zu der Frage „Wie erzeugt man einen Link zum Frontend aus dem Backend-Kontext / aus dem Scheduler“ voll von Antworten, wie dieser hier bei StackOverflow: Allein beim Runterscrollen durch das Script denkt man eigentlich nur: Ist das Euer ernst? Ich will doch nur einen Link. Irgendwann baut man aus Ungeduld den Link dann vielleicht per Hand ($link = 'https://www.domain.de/?id=' . $pid) – aber richtig „gut“ fühlt sich das nicht an. Die URL ist hardgecoded, Parameter sind offen gelegt, der Slug / RealUrl fehlt. Nicht schön. Und erschwerend kommt hinzu: Der Code scheint sich von Typo3-Version zu Version zu ändern.

Wie es einfacher geht? Mit unserer Extension nnhelpers, die genau dort hilft, wo man denkt „Das muss doch irgendwie einfacher gehen“. nnhelpers ist eine Sammlung von Tools und Funktionen, die die Arbeit mit Typo3 und der Extension-Entwicklung erheblich vereinfacht. Alle Scripte sind als einzeilige „No-Brainer“ konzipiert. Und alle Methoden sind direkt im Backend in einem übersichtlichen „Spickzettel“ zusammengefasst.

So sieht die Lösung dann mit `nnhelpers` aus:

\nn\t3::Page()->getLink(199, ['test'=>99]);

Der gleiche Befehlt funktioniert in jedem Kontext – ob Frontend, Backend, CLI. Und er funktioniert versionsübergreifend für Typo3 6 aufwärts.
Er erzeugt einen Link zum Frontend aus dem Backend-Kontext oder Scheduler-Kontext oder CLI-Kontext mit absoluter URL zur Seite, bei der aber auch der Slug bzw. RealUrl-Pfad inkl. Parameter korrekt aufgelöst wird.

Richtig gesehen: `nnhelpers` braucht keine Instanz des `UriBuilder, der über den `ObjectManager` instanziiert werden muss, der über die `GeneralUtility` generiert werden muss. Der Einzeiler kann einfach – so wie er ist – an der Stelle eingefügt werden, wo er benötigt wird. Er hält damit den Code sauber und übersichtlich.

Hier geht es zur Extension im Repository von Typo3:
https://extensions.typo3.org/extension/nnhelpers

Die Dokumentation dazu gibt es hier:
Auf Deutsch: https://labor.99grad.de/typo3-docs/nnhelpers/de/
Und English: https://labor.99grad.de/typo3-docs/nnhelpers/en/

nnhelpers im Typo3 Repository (TER) veröffentlicht

Seit heute ist einer unser wichtigster „Mitarbeiter“ im TER und unterstützt Euch ab sofort bei Euren eigenen Projekten! Selbstverständlich vollkommen ehrenamtlich und ohne Berechnung 😉

Die Extension „nnhelpers“, eine Sammlung extrem hilfreicher Methoden und ViewHelper, die wir ausnahmslos jeden Tag bei der Extension-Entwicklung in Typo3 brauchen.

Hier geht es zur Extension im Repository von Typo3:
https://extensions.typo3.org/extension/nnhelpers

Die Dokumentation dazu gibt es hier:
https://labor.99grad.de/typo3-docs/nnhelpers/de/
https://labor.99grad.de/typo3-docs/nnhelpers/en/

typeNum in Link funktioniert nicht. Typo3 type removed from URL (Typo3 9, Typo3 10)

Problem nach dem Update auf Typo3 9 oder 10:

Beim Erstellen eines Links über den ViewHelper f:link.page, f:uri.page, f:link.typolink, f:uri.typolink etc. wird der typeNum-Parameter ignoriert.
Auch beim Versuch, type manuell über additionalParams zu übergeben, erscheint kein &type=123456 in der generierten URL:

<f:link.page pageType="123456" additionalParams="{s:1,p:2,type:123456}" pageUid="3"<

wird zu:
https://www.domain.de/?s=1&p=2

Der type=123456-Parameter wird einfach entfernt.

Lösung:
Die site-yaml Konfiguration prüfen und darauf achten, dass ein routeEnhancer für den Page-Type definiert wurde!


routeEnhancers:
  PageTypeSuffix:
    type: PageType
    default: '/'
    index: ''
    map:
      beispiel: 123456

Hier – als kleiner Spickzettel – noch mal die TypoScript-Setup zum simplen Aufruf einer Methode über typeNum.

Mit entsprechender Einstellung im TypoScript und der Site-Konfiguration (yaml) wird die angegebene Methode beim Aufruf der URL https://www.beispiel.de/?type=123456 ausgeführt.


beispiel = PAGE
beispiel {
  typeNum = 123456
  config {
    disableAllHeaderCode = 1
    xhtml_cleaning = 0
    admPanel = 0
    additionalHeaders = Content-type: text/plain
    no_cache = 1
    contentObjectExceptionHandler = 0
  }
  10 = USER
  10.userFunc = Pfad\Zu\Deinem\Script->methodenName
}

Für Suchmaschinen: Typo3 Typolink ignores type-Parameter, typeNum not working Typo3, typeNum funktioniert nicht, type wird aus URL entfernt beim ViewHelper. Typoscript mit page-type wird nicht ausgeführt. Problem typeNum in Link-URL.

typo3 templavoila – Sie haben nicht die nötigen Rechte, um diese Änderung durchzuführen.

Sie haben nicht die nötigen Rechte, um diese Änderung durchzuführen

Bei einer Typo3 6.2 Installation mit TemplaVoila 1.9.2 standen wir vor einem fast unlösbaren Rätsel: Aus unerfindlichem Grund funktionierte das Anlegen von neuen Inhaltselementen nicht mehr – weder in der Listenansicht noch in der TV-Seitenansicht. Nach Auswahl eines Contentelementes aus dem Wizard brach Typo3 mit der Fehlermeldung „Sie haben nicht die nötigen Rechte, um diese Änderung durchzuführen.“ ab. Und das, obwohl wir als Admin eingeloggt waren.

Vor wenigen Tagen noch lief alles problemlos und wir hatten kein Update eingespielt.
Im Netz findet mal viele Lösungen dazu, am häufigsten den Hinweis, dass ein Feld in der Datenbank-Tabelle pages fehlen würde.

t3ver_swapmode ist es nicht!

Die allgemein anerkannte Lösung, folgenden MySQL-Befehl zum Einfügen der fehlenden Spalte auszuführen, funktionierte aber leider nicht:

ALTER table pages add(`t3ver_swapmode` tinyint(4) NOT NULL DEFAULT '0');

MariaDB hat Probleme mit unmaskiertem „recursive“ von Typo3

Nach langem Suchen: Der Host hatte die Datenbank auf MariaDB umgestellt. MariaDB hat ein reserviertes Keyword recursive – das blöderweise auch ein Spaltenname in der Tabelle tt_content ist. Beim Generieren der INSERT-Query in /typo3/sysext/core/Classes/Database/DatabaseConnection.php maskiert Typo3 allerdings die Feldnamen nicht durch backticks – es steht als INSERT INTO tt_content (recursive, ...) statt INSERT INTO tt_content(`recursive`, ...).

Die Query bricht mit der Fehlermeldung „SQL Error: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ‚recursive,menu_type,list_type,table_bgColor,table_border,table_cellspacing,ta…‘ at line 1“ ab.

Patch und Lösung

Das Problem wurde in einer späteren Version von Typo3 gefixed. Für Typo3 < 6 kann es mithilfe dieser Patches zum Laufen gebracht werden: https://forge.typo3.org/attachments/35472?utf8=%E2%9C%93&type=sbs

Schritt für Schritt Anleitung

  1. Die Datei /typo3/sysext/core/Classes/Database/DatabaseConnection.php bearbeiten
  2. Folgende Zeilen suchen und ersetzen:

Suche nach:
$query = 'INSERT INTO ' . $table . ' (' . implode(',', array_keys($fields_values)) . ') VALUES ' . '(' . implode(',', $fields_values) . ')';
Ersetzen mit:
$query = 'INSERT INTO ' . $table . ' (`' . implode('`,`', array_keys($fields_values)) . '`) VALUES ' . '(' . implode(',', $fields_values) . ')';


Suche nach:
$query = 'INSERT INTO ' . $table . ' (' . implode(', ', $fields) . ') VALUES ';
Ersetzen mit:
$query = 'INSERT INTO ' . $table . ' (`' . implode('`,`', $fields) . '`) VALUES ';


Suche nach:
$fields[] = $k . '=' . $v;
Ersetzen mit:
$fields[] = '`' . $k . '`=' . $v;


Suche nach:
$queryParts[] = $table . '.' . implode(($like . ' OR ' . $table . '.'), $fields) . $like;
Ersetzen mit:
$queryParts[] = $table . '.`' . implode(('`' . $like . ' OR ' . $table . '.`'), $fields) . '`' .$like;


Für Suchmaschinen: In TYPO3 erscheint beim Anlegen eines Inhaltselements folgende Fehlermeldung von TemplaVoila: „Sie haben nicht die nötigen Rechte, um diese Änderung durchzuführen.“ Probleme Typo3 Zugriffsrechte Backend Templavoila trotz Admin-Rechten. TemplaVoila funktioniert unter MariaDB nicht mehr. Typo3 Problem MariaDB INSERT Query. TemplaVoila forbidden new content element, SQL Error: You have an error in your SQL syntax. MariaDB.

Typo3 Extension „mask“: Mehrere templateRootPaths angeben

Kleines, sehr hilfreiches TypoScript für die wunderbare Extension „mask“ (Typo3).

Nicht selten kommt man an das Problem, mehr als nur einen Pfad zu seinen Mask-Templates definieren zu wollen. Die Extension-Konfiguration im Backend lässt leider nur jeweils einen einzigen Pfad für Folder for Content Fluid Templates (with trailing slash) frontend.content (folder), Folder for Content Fluid Layouts (with trailing slash) frontend.layouts (folder) und Folder for Content Fluid Partials (with trailing slash) frontend.partials (folder) zu.

Das Problem lässt sich aber im TypoScript-Setup lösen.

Ab Typo3 9 LTS


lib.maskContentElement {
  templateRootPaths {
    // 10 wird von mask gesetzt, abhängig von der EXT-Konfiguration im Backend
    20 = EXT:deine/ext/Resources/Private/Templates/
  }
  partialRootPaths {
    // 10 wird von mask gesetzt, abhängig von der EXT-Konfiguration im Backend
    20 = EXT:deine/ext/Resources/Private/Partials/
  }
  layoutRootPaths {
    // 10 wird von mask gesetzt, abhängig von der EXT-Konfiguration im Backend
    20 = EXT:deine/ext/Resources/Private/Layouts/
  }
}

Bis einschließlich Typo3 8 LTS


lib.tx_mask {
  templateRootPaths {
    // 10 wird von mask gesetzt, abhängig von der EXT-Konfiguration im Backend
    20 = EXT:deine/ext/Resources/Private/Templates/
  }
  partialRootPaths {
    // 10 wird von mask gesetzt, abhängig von der EXT-Konfiguration im Backend
    20 = EXT:deine/ext/Resources/Private/Partials/
  }
  layoutRootPaths {
    // 10 wird von mask gesetzt, abhängig von der EXT-Konfiguration im Backend
    20 = EXT:deine/ext/Resources/Private/Layouts/
  }
}

Wenn mir jetzt noch jemand sagen könnte, wie man die mask.json in mehrere Dateien bekommt… dann würde ich den Entwicklern von mask eine Bierkasten-Abo schenken 🙂

Für Suchmaschinen: Typo3 Extension Mask. Mehrere Pfade zu Templates und templateRootPaths für mask typo3. mask typo3 multiple templateRootPaths. Zusätzliche Pfade für Mask-Templates per TypoScript angeben.

Typo3 autoload-Cache leeren bei Klick auf Typo3-Blitz und „alle Caches leeren“

Während der Entwicklung von Typo3-Extensions ändert, erstellt und erweitert man häufig Klassen in seinem eigenen Namespace. Durch das (sinnvolle) Typo3-Caching werden diese Klassennamen und Pfade in einer PHP-Datei gecached (typo3conf/autoload/autoload_classmap.php).

Leider greift der Klick auf den „Typo3 Blitz“ mit der Option „Alle Caches leeren“ nicht, um auch diese Dateien neu aufzubauen. Typo3 zwingt den Entwickler ins Install-Tool und dort zu der Option „Create autoload information for extensions“. Dieser Wechsel ist relativ nervig – und eine klassische Frustrations-Quelle, wenn im Frontend mal wieder das „striped Zebra of death“ mit einem Fatal Error erscheint.

Weiterlesen

Typo3 tx_form: Eigenes Formularelement erstellen / custom form element

Versuch einer Anleitung für Dummies

(oder Normalsterbliche, die einfach nur einen Job zu erledigen haben)

Vor einigen Tagen haben wir einen Beitrag veröffentlicht, wie man ein die Typo3 Core Extension tx_form um ein eigenes Formularelement erweitern kann.

Die Typo3 Extension tx_form ist zwei Dingen vorbildlich: Der modularen und konsequent objektorientierten Architektur. Und im bisher unerreichten Verwirrungsfaktor für Normalsterbliche. Ich weiß nicht, wie viele Stunden wir im Ordner sysext/form verbracht haben, um zu verstehen, welches mixin von welchem übergeordneten mixin per __inheritances welche Konfigurations-Häppchen erbt.

Genauso unverständlich und eine echte Motivationsbremse ist es für viele Typo3-Entwicklern, dass tx_form auf eine weitere Konfigurationssprache setzt. TypoScript, TCA und FlexForm-XML? Alles alte Hasen, da geht noch einer. Also jetzt noch YAML dazu. Zwei spaces statt tab. Unlesbare Dateien und kaum brauchbare Editoren. Und was die Erweiterbarkeit angeht noch ziemlich buggy. Na dann, lasst uns mal einsteigen.

Weiterlesen

Eigenes Custom Form Element für tx_form-Extension – Typo3 v8

How-To für das Erstellen eines Custom Form Elements für die tx_form-Extension unter Typo3 v8.

Falls man ein Custom Form Element erstellen möchte, haltet euch an das How-To. Für detaillierte Informationen und die Dokumentation zur ext:form besucht: https://docs.typo3.org/typo3cms/extensions/form/Index.html

Außerdem haben wir eine „Anleitung für Dummies und Normalsterbliche, die einfach einen Job zu erledigen haben“ erstellt – eine Kurzfassung mit farblicher Kennzeichnung und einem simplen Online-Generator.

Weiterlesen