Configuration module

The configuration module can be found at System > Configuration. It allows integrators to view and validate the global configuration of TYPO3. The module displays all relevant global variables such as TYPO3_CONF_VARS, TCA and many more, in a tree format which is easy to browse through. Over time this module got extended to also display the configuration of newly introduced features like the middleware stack or event listeners.

Extending the configuration module

To make this module more powerful a dedicated API is available which allows extension authors to extend the module so they can expose their own configurations.

By the nature of the API it is even possible to not just add new configuration but to also disable the display of existing configuration, if not needed in the specific installation.

Basic implementation

To extend the configuration module, a custom configuration provider needs to be registered. Each "provider" is responsible for one configuration. The provider is registered as a so-called "configuration module provider" by tagging it in the Services.yaml file. The provider class must implement the EXT:lowlevel/Classes/ConfigurationModuleProvider/ProviderInterface.php (GitHub).

The registration of such a provider looks like the following:

EXT:my_extension/Configuration/Services.yaml
myextension.configuration.module.provider.myconfiguration:
    class: 'Vendor\Extension\ConfigurationModuleProvider\MyProvider'
    tags:
        - name: 'lowlevel.configuration.module.provider'
          identifier: 'myProvider'
          before: 'beUserTsConfig'
          after: 'pagesTypes'
Copied!

A new service with a freely selectable name is defined by specifying the provider class to be used. Further, the new service must be tagged with the lowlevel.configuration.module.provider tag. Arbitrary attributes can be added to this tag. However, some are reserved and required for internal processing. For example, the identifier attribute is mandatory and must be unique. Using the before and after attributes, it is possible to specify the exact position on which the configuration will be displayed in the module menu.

The provider class has to implement the methods as required by the interface. A full implementation would look like this:

EXT:my_extension/Classes/ConfigurationModule/MyProvider.php
<?php

declare(strict_types=1);

namespace MyVendor\MyExtension\Configuration\Processor\ConfigurationModule;

use TYPO3\CMS\Lowlevel\ConfigurationModuleProvider\ProviderInterface;

final class MyProvider implements ProviderInterface
{
    private string $identifier;

    public function __invoke(array $attributes): self
    {
        $this->identifier = $attributes['identifier'];
        return $this;
    }

    public function getIdentifier(): string
    {
        return $this->identifier;
    }

    public function getLabel(): string
    {
        return 'My custom configuration';
    }

    public function getConfiguration(): array
    {
        $myCustomConfiguration = [
            // the custom configuration
        ];

        return $myCustomConfiguration;
    }
}
Copied!

The __invoke() method is called from the provider registry and provides all attributes, defined in the Services.yaml. This can be used to set and initialize class properties like the :php$identifier which can then be returned by the required method getIdentifier(). The getLabel() method is called by the configuration module when creating the module menu. And finally, the getConfiguration() method has to return the configuration as an array to be displayed in the module.

There is also the abstract class EXT:lowlevel/Classes/ConfigurationModuleProvider/AbstractProvider.php (GitHub) in place which already implements the required methods; except getConfiguration(). Please note, when extending this class, the attribute label is expected in the __invoke() method and must therefore be defined in the Services.yaml. Either a static text or a localized label can be used.

Since the registration uses the Symfony service container and provides all attributes using __invoke(), it is even possible to use dependency injection with constructor arguments in the provider classes.

Displaying values from $GLOBALS

If you want to display a custom configuration from the $GLOBALS array, you can also use the already existing TYPO3\CMS\Lowlevel\ConfigurationModuleProvider\GlobalVariableProvider. Define the key to be exposed using the globalVariableKey attribute.

This could look like this:

EXT:my_extension/Configuration/Services.yaml
myextension.configuration.module.provider.myconfiguration:
    class: 'TYPO3\CMS\Lowlevel\ConfigurationModuleProvider\GlobalVariableProvider'
    tags:
        - name: 'lowlevel.configuration.module.provider'
          identifier: 'myConfiguration'
          label: 'My global var'
          globalVariableKey: 'MY_GLOBAL_VAR'
Copied!

Disabling an entry

To disable an already registered configuration add the disabled attribute set to true. For example, if you intend to disable the TBE_STYLES key you can use:

EXT:my_extension/Configuration/Services.yaml
lowlevel.configuration.module.provider.tbestyles:
    class: TYPO3\CMS\Lowlevel\ConfigurationModuleProvider\GlobalVariableProvider
    tags:
        - name: 'lowlevel.configuration.module.provider'
          disabled: true
Copied!

Blinding configuration options

Sensitive data (like passwords or access tokens) should not be displayed in the configuration module. Therefore, a hook is available to blind such configuration options.

First, implement a class, for example:

EXT:my_extension/Classes/Hooks/BlindedConfigurationOptionsHook.php
final class BlindedConfigurationOptionsHook
{
    public function modifyBlindedConfigurationOptions(array $blindedOptions): array
    {
        if (($GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['example']['password'] ?? '') !== '') {
            $blindedOptions['TYPO3_CONF_VARS']['EXTENSIONS']['example']['password'] = '******';
        }

        return $blindedOptions;
    }
}
Copied!

Then register the hook in your extension's ext_localconf.php:

EXT:my_extension/ext_localconf.php
use MyVendor\MyExtension\Hook\BlindedConfigurationOptionsHook;
use TYPO3\CMS\Lowlevel\Controller\ConfigurationController;

$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS'][ConfigurationController::class]['modifyBlindedConfigurationOptions'][]
    = BlindedConfigurationOptionsHook::class;
Copied!