Skip to content

HowTo: Register your plugin, CE or module

The API of TYPO3 is huge and lots of it is sometimes hard to find. In this article I will provide a guide on how to add your FE plugin, your Content Element or your BE module. It covers extensions written "the old way" (pibase / AbstractPlugin) as well as Extbase based implementations.

Extending a TYPO3 CMS installation with a custom module is not very complicated... if you know and understood the API calls required to do so.

We will start heads first into the basic concept on how the Core API is structured and will take a look at the different scenarios for pibase and extbase separately.

Core API structure

The Core has a bunch of API methods related to adding plugins, content elements and modules:

  • \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addPItoST43()
  • \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addModule()
  • \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addPlugin()
  • \TYPO3\CMS\Extbase\Utility\ExtensionUtility::configurePlugin()
  • \TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin()
  • \TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerModule()

The methods in ExtensionManagementUtility are existing for years and build the foundation which should generally be used for pibase based extensions.

Since extbase based extensions need some more abstraction when being registered in the system, the methods of ExtensionUtility are reserved for those. Be aware though that those methods make use of the ExtensionManagementUtility methods internally.

For examples in the following sections, we assume that our extension has the key "rx_extkey" and provides a plugin named "pi1" and a module named "airplane".
The namespace of the extension is therefore "Reelworx\RxExtkey".

If you wonder about the configureModule() methods in the two classes above, let me say one thing about them: Just don't care. They are of Core internal use only, you should not call them.

pibase (aka AbstractPlugin)

Assumption: The code does not use namespaces.

Registering a plugin

Adding a frontend plugin requires two registration steps.

The first step is to make your plugin available for the frontend rendering. This is accomplished in the ext_localconf.php file of your extension with only a single call:

 

\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addPItoST43($_EXTKEY, 'Classes/class.tx_rxextkey_pi1.php', '_pi1', 'list_type', FALSE);

 

The second step is to make the plugin selectable in the backend as well. Since TYPO3 CMS 6.2 this happens in the TCA Override file for tt_content, since we want to select the plugin in the "Insert plugin" content element. The file Configuration/TCA/Overrides/tt_content.php therefore has to contain:

 

\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addPlugin(
array(
'LLL:EXT:rx_extkey/Resources/Private/Language/locallang_db.xml:tt_content.list_type_pi1',
'rx_extkey_pi1',
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extRelPath('rx_extkey') . 'ext_icon.png'
),
'list_type',
'rx_extkey'
);

 

Most likely you will add a third step to provide a your TypoScript configuration as static template for the user to select it. Since this is again manipulating the TCA, the right API call is placed in Configuration/TCA/Overrides/sys_template.php:

 

\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addStaticFile('rx_extkey', 'Configuration/TypoScript/PluginSettings/', 'Plugin Settings');

 

Registering a content element

This is exactly the same process as above, except that you have to replace 'list_type' with 'CType' in both API calls.

Registering a backend module

Adding a backend module is rather simple and happens in the ext_tables.php file:

 

if (TYPO3_MODE === 'BE') {
    \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addModule(
        'web',
        'txrxextkeyAirplane',
        '',
        \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extPath($_EXTKEY) . 'AirplaneModule/'
    );
}

 

Be aware that traditional (non-extbase) backend modules still require a folder per module, which contains at least the index.php file. The conf.php file is still required, unless define the configuration by using the 5th parameter in the call above. If you omit the conf.php file, be aware that there are some important nitpicks you have to take care of. The most prominent being that you've to set the $this->MCONF['name'] property in your module manually.

Special case: Namespaced pibase extensions

Some extensions are still based on pibase but use namespaces for the classes already and maybe even implement a custom MVC handling. (We have a rather big extension doing so, for instance.)

The problem with namespaced plugins though is that the old API methods are not aware of namespaces and fail to properly handle those. This leads to issues when generating the necessary TypoScript code, which will then contain a wrong class name for the plugin.

Luckily it is still possible to register your namespaced plugin if you use one of two tricks:

First possibility is to provide a Migrations/Code/ClassAliasMap.php file with your extension. This will tell the TYPO3 CMS class loader that your namespaced plugin can also be addressed using a different name. Specify the correct mapping here, such that the old name matches your new class. The file content should look like:

 

<?php return array( 'tx_rxextkey_pi1' => Reelworx\RxExtkey\Plugin::class );

 

Second possibility is to override the TypoScript code generated by the addPItoST43() method by calling ExtensionManagementUtility::addTypoScript() with the following code:

 

$overrideSetup = 'plugin.tx_rxextkey_pi1.userFunc = Reelworx\RxExtkey\Plugin->main';
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addTypoScript('rx_extkey', 'setup', $overrideSetup);

 

extbase

Registering your extension's additional functionality is a bit simpler.

Registering a plugin

The first call for the TypoScript generation should go into your ext_localconf.php file:

 

\TYPO3\CMS\Extbase\Utility\ExtensionUtility::configurePlugin(
'Reelworx.RxExtkey',
'Pi1',
array('controller' => 'index,list,...')
);

 

The second call for the TCA additions should again be in the file Configuration/TCA/Overrides/tt_content.php:

 

\TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin(
    'Reelworx.RxExtkey',
    'Pi1',
    'LLL:EXT:rx_extkey/Resources/Private/Language/locallang_db.xml:tt_content.list_type_pi1',
    'EXT:rx_extkey/Resources/Public/Icons/plugin_icon.png'
);

 

Registering a content element

This just requires a tiny modification of the call to configurePlugin(), in particular:

 

\TYPO3\CMS\Extbase\Utility\ExtensionUtility::configurePlugin(
    'Reelworx.RxExtkey',
    'Pi1',
    array('controller' => 'index,list,...'),
    array(),
    \TYPO3\CMS\Extbase\Utility\ExtensionUtility::PLUGIN_TYPE_CONTENT_ELEMENT
);

 

Registering a backend module

Finally your backend module will be registered again in the ext_tables.php file:

 

if (TYPO3_MODE === 'BE') {
    \TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerModule(
        'RxExtkey',
        'web',
        'airplane',
        '',
        array('controller' => 'index'),
        array(
            'access' => 'user,group',
            'icon' => 'EXT:rx_extkey/Resources/Public/Icons/module.png',
            'labels' => 'Resources/Private/Language/locallang_mod.xlf',
        )
    );
}

 

Future

There is more on the horizon. The AC-Team realized that the API in the current state is far from being optimal (consider the historic method name addPItoST43()). The idea is to introduce conventions and to have "strong defaults". The first solutions are documented in this ticket.

Regarding conventions you might also take a look at the autoloader extension by Tim Lochmüller, which embraces this concept for many more areas.

 

Information applies to TYPO3 CMS versions 6.2 to 7.6