Create a backend module with Extbase

See also the Backend module API.

Backend modules can be written using the Extbase/Fluid combination.

The factory \TYPO3\CMS\Backend\Template\ModuleTemplateFactory can be used to retrieve the \TYPO3\CMS\Backend\Template\ModuleTemplate class which is - more or less - the old backend module template, cleaned up and refreshed. This class performs a number of basic operations for backend modules, like loading base JS libraries, loading stylesheets, managing a flash message queue and - in general - performing all kind of necessary setups.

To access these resources, inject the \TYPO3\CMS\Backend\Template\ModuleTemplateFactory into your backend module controller:

 use TYPO3\CMS\Backend\Attribute\AsController;
 use TYPO3\CMS\Backend\Template\ModuleTemplateFactory;
 use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;

 #[AsController]
 final class MyController extends ActionController
 {
     public function __construct(
         protected readonly ModuleTemplateFactory $moduleTemplateFactory,
     ) {
     }
}
Copied!

Changed in version 14.0

The class alias for \TYPO3\CMS\Backend\Attribute\Controller has been removed. \TYPO3\CMS\Backend\Attribute\AsController is still in place.

After that you can add titles, menus and buttons using ModuleTemplate:

// use Psr\Http\Message\ResponseInterface
public function myAction(): ResponseInterface
{
    $moduleTemplate = $this->moduleTemplateFactory->create($this->request);

    // Example of assignung variables to the view
    $moduleTemplate->assign('someVar', 'someContent');

    // Example of adding a page-shortcut button
    $routeIdentifier = 'web_examples'; // array-key of the module-configuration
    $buttonBar = $moduleTemplate->getDocHeaderComponent()->getButtonBar();
    $shortcutButton = $buttonBar->makeShortcutButton()->setDisplayName('Shortcut to my action')->setRouteIdentifier($routeIdentifier);
    $shortcutButton->setArguments(['controller' => 'MyController', 'action' => 'my']);
    $buttonBar->addButton($shortcutButton, ButtonBar::BUTTON_POSITION_RIGHT);
    // Adding title, menus and more buttons using $moduleTemplate ...

    return $moduleTemplate->renderResponse('MyController/MyAction');
}
Copied!

Using this ModuleTemplate class, the Fluid templates for your module need only take care of the actual content of your module. TYPO3 even comes with a default Fluid layout, that can easily be used:

<f:layout name="Module" />
Copied!

and the actual Template needs to render the title and the content only. For example, here is an extract of the "Index" action template of the "beuser" extension:

typo3/sysext/beuser/Resources/Private/Templates/BackendUser/List.html
<html
   xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers"
   xmlns:core="http://typo3.org/ns/TYPO3/CMS/Core/ViewHelpers"
   xmlns:be="http://typo3.org/ns/TYPO3/CMS/Backend/ViewHelpers"
   data-namespace-typo3-fluid="true">

   <f:layout name="Module" />

   <f:section name="Content">
       <h1><f:translate key="backendUserListing" /></h1>
       ...
   </f:section>

</html>
Copied!

The best resources for learning is to look at existing modules from TYPO3 CMS. With the information given here, you should be able to find your way around the code.