Tobse
Tobse

Reputation: 747

Typo3 custom extension route enhancers

I have created a custom Typo3 v9.5.26 extension using the Extension Builder extension.

My extension resides in typo3conf/ext/xyz_sortitems and sorts items.

An item has the attributes itemid, name, date and amount.

My ext_localconf.php looks like this:

<?php  
if (!defined('TYPO3_MODE')) {  
    die ('Access denied.');  
}  
  
call_user_func(  
    function() {  
  
        \TYPO3\CMS\Extbase\Utility\ExtensionUtility::configurePlugin(  
            'XYZ.XyzSortitems',  
            'Sortitems',  
  
            // cacheable actions  
            ['Sortitems' => 'sortbyname,sortbydate,sortbyamount,showsingleitem'],  
  
            // non-cacheable actions  
            ['Sortitems' => 'sortbyname,sortbydate,sortbyamount,showsingleitem']  
        );  
  
    }  
);

My view controller resides in typo3conf/ext/xyz_sortitems/classes/Controller/SortitemsController.php and looks about like this:

<?php  
  
namespace XYZ\XyzSortitems\Controller;  
  
class SortitemsController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionController {  
  
    protected $sortitemsRepository = null;  
  
    public function injectSortitemsRepository(\XYZ\XyzSortitems\Domain\Repository\SortimtesRepository $sortitemsRepository) {  
        $this->sortitemsRepository = $sortitemsRepository;  
    }  
  
    public function sortbynameAction() {  
        // sorts items by name here...  
    }  
  
    public function sortbydateAction() {  
        // sorts items by date here...  
    }  
  
    public function sortbyamountAction() {  
        // sorts items by amount here...  
    }  
  
    public function showsingleitemAction() {  
        // displays a single item here...  
    }  
  
}

...and my view template (e.g. for the sortbydateAction) resides in ext/xyz_sortitems/Resources/Private/Templates/Sortbydate.html and generates links to the respective items like this:

<html xmlns:f="http://typo3.org/ns/fluid/ViewHelpers">  
    <f:layout name="defaultLayout" />  
    <f:section name="sectionname">  
        <f:for each="{items}" as="item">  
  
            <!-- here the link to the single item page is generated -->  
            <f:link.action action="showsingleitem" pageUid="4321" arguments="{itemid: item.itemid}">  
  
        </f:for>  
    </f:section>  
</html>

My extension is working as expected.

Now when I look at the front-end at a page displaying a sorted list of items (e.g. sorted by date), the Fluid template engine generates the links of the items in this list to the respective target pages (each displaying a single item) about like this:

http://example.com/item  
?tx_xzysortitems_sortitems%5Baction%5D=showsingleitem 
&tx_xzysortitems_sortitems%5Bcontroller%5D=Sortitems  
&tx_xzysortitems_sortitems%5Bitemid%5D=12345  
&cHash=38a2dd43d7b0c4997c3b0ff6d4430e55

Instead I need to have the links to the respective pages showing a single item looking like this:

http://example.com/item/{itemid}/{name}  
(e.g. http://example.com/item/12345/ice-cream-on-toast)

Since RealURL is gone in Typo2 v9, I obviously need a Route Enhancer in typo3conf/ext/xyz_sortitems/config.yaml, reading itemid and name from the extension's table in the Typo3 database and putting these values into the URLs pointing to the single item pages.

Unfortunately about 90% of all code examples I could find reference Georg Ringer's pi-based "News" extension as example. This extension is a quite special one (because it's pi-based and for many other reasons) and the pure repetition of examples about this extension doesn't make the subject any more understandable for me. The remaining 10% of instuctions I could find, including the official Typo3 documentation (currently here) provide great examples, but don't mention which value comes from where.

I'm mainly interested in the top part of the config.yaml:

  routeEnhancers:  
    {SecondLine}:  
      type: {typedefinition}  
      extension: {extensionname}  
      plugin: {pluginname}  
      namespace: {namespace}  
      limitToPages:  
        - {a_page_id}  
        - {another_page_id}  
      routes:  
      # routes here...

Which of these values do I need and where exactly do I take them from?

The instructions I've found so far usually either don't explain these values at all or refer to them with "take these values from your ext_localconf.php". This doesn't help me much, as this doesn't explain which value in config.yaml corresponds with which value in ext_localconf.php and if the syntax of the respective value needs to be lowercase, first letter uppercase and rest lowercase or camelcase, if it needs to be in single or double quotes, escaped, can contain spaces, needs underscores or whatever else the syntax requires in order to be valid. Terms like "extension name" can be misleading, as in my example this could be "sortitems", "xyz_sortitems", "XYZ.Sortitems", "XyzSortitems" or "Sortitems", just to name some.

I would appreciate an answer with a config.yaml code example explaining these values in detail, in a generic way, so that everyone who reads this question and has the same issue understanding the manuals like me can apply this valuable knowledge to their own custom Typo3 extension easily.

Upvotes: 1

Views: 1004

Answers (1)

Heinz Schilling
Heinz Schilling

Reputation: 2272

Based on your question this are the explanations of the values.

routeEnhancers:  
    {SecondLine}:  
      type: {typedefinition}  
      extension: {extensionname}  
      plugin: {pluginname}  
      namespace: {namespace}  
      limitToPages:  
        - {a_page_id}  
        - {another_page_id}  
      routes:  
      # routes here...

Value of {SecondLine}

Example: XzySortitemsShow

Unique name for the enhancers, used internally for referencing. Found in core doc.

Value of {typedefinition}

Example: Extbase

TYPO3 comes with the following route enhancers out of the box:

  • Simple Enhancer (enhancer type “Simple”)
  • Plugin Enhancer (enhancer type “Plugin”)
  • Extbase Plugin Enhancer (enhancer type “Extbase”)

More types are described in core docs.

Value of {extensionname}

Example: XyzSortitems

UpperCamelCase of the extension name (the name of the folder of your extension)

Source: typo3_src-10.4.14/sysext/extbase/Classes/Utility/ExtensionUtility.php

Function parameters of configurePlugin() are

public static function configurePlugin(
    $extensionName, 
    $pluginName, 
    array $controllerActions, 
    array $nonCacheableControllerActions = [], 
    $pluginType = self::PLUGIN_TYPE_PLUGIN)

Comment from code of configurePlugin() * @param string $extensionName The extension name (in UpperCamelCase) or the extension key (in lower_underscore)

Value of {pluginname}

Example: Sortitems

Source: typo3_src-10.4.14/sysext/extbase/Classes/Utility/ExtensionUtility.php

Function parameters of configurePlugin() are

public static function configurePlugin(
    $extensionName, 
    $pluginName, 
    array $controllerActions, 
    array $nonCacheableControllerActions = [], 
    $pluginType = self::PLUGIN_TYPE_PLUGIN)

Comment from code of configurePlugin()

* @param string $pluginName must be a unique id 
      for your plugin in UpperCamelCase 
      (the string length of the extension key 
      added to the length of the plugin name 
      should be less than 32!)

{namespace}

Is a alternate to type extbase.

Example can be found here in core doc and the plugin enhancer is described here in core doc.

For the Extbase Plugin Enhancer, it is also possible to configure the namespace directly by skipping extension and plugin properties and just using the namespace property as in the regular Plugin Enhancer.

Offtopic: Georg Ringer's EXT:news is not pi-based!

Upvotes: 2

Related Questions