Create a backend module with Core functionality¶
This page covers the backend template view, using only Core functionality without Extbase.
Tip
If you want to do extensive data modeling, you may want to use Extbase templating. If you are building a simple backend module, it makes sense to work without Extbase.
Basic controller¶
When creating a controller without Extbase an instance of ModuleTemplate
is required to return the rendered template:
use TYPO3\CMS\Backend\Attribute\Controller;
// the module template will be initialized in handleRequest()
use TYPO3\CMS\Backend\Template\ModuleTemplateFactory;
use TYPO3\CMS\Core\Imaging\IconFactory;
#[Controller]
final class AdminModuleController
{
public function __construct(
protected readonly ModuleTemplateFactory $moduleTemplateFactory,
protected readonly IconFactory $iconFactory,
// ...
) {
}
}
New in version 12.1: Since TYPO3 v12.1 a backend controller can be tagged with the
\TYPO3\CMS\Backend\Attribute\Controller
attribute. This way, the
registration of the controller in the Configuration/Services.yaml
file is no longer necessary.
If the controller is not tagged with the \TYPO3\CMS\Backend\Attribute\Controller
attribute, it must be registered in Configuration/Services.yaml
with the backend.controller
tag for dependency injection to work:
services:
_defaults:
autowire: true
autoconfigure: true
public: false
T3docs\Examples\:
resource: '../Classes/*'
exclude: '../Classes/Domain/Model/*'
T3docs\Examples\Controller\AdminModuleController:
tags: ['backend.controller']
Main entry point¶
The handleRequest()
method is the main entry point which triggers only the allowed actions.
This makes it possible to include e.g. Javascript for all actions in the controller.
public function handleRequest(ServerRequestInterface $request): ResponseInterface
{
$languageService = $GLOBALS['LANG'];
$this->menuConfig($request);
$moduleTemplate = $this->moduleTemplateFactory->create($request);
// setUpDocHeader() is documented below
$this->setUpDocHeader($moduleTemplate);
$title = $languageService->sL('LLL:EXT:examples/Resources/Private/Language/AdminModule/locallang_mod.xlf:mlang_tabs_tab');
switch ($this->MOD_SETTINGS['function']) {
case 'debug':
$moduleTemplate->setTitle(
$title,
$languageService->sL(''EXT:examples/Resources/Private/Language/AdminModule/locallang.xlf:module.menu.debug')
);
return $this->debugAction($moduleTemplate);
case 'password':
$moduleTemplate->setTitle(
$title,
$languageService->sL(''EXT:examples/Resources/Private/Language/AdminModule/locallang.xlf:module.menu.password')
);
return $this->passwordAction($moduleTemplate);
default:
$moduleTemplate->setTitle(
$title,
$languageService->sL(''EXT:examples/Resources/Private/Language/AdminModule/locallang.xlf:module.menu.log')
);
return $this->logAction($moduleTemplate);
}
}
Actions¶
Now create an example indexAction()
and assign variables to your view
as you would normally do.
public function debugAction(
ModuleTemplate $view,
string $cmd = 'cookies'
): ResponseInterface
{
$cmd = $_POST['tx_examples_admin_examples']['cmd'];
switch ($cmd) {
case 'cookies':
$this->debugCookies();
break;
}
$view->assignMultiple(
[
'cookies' => $_COOKIE,
'lastcommand' => $cmd,
]
);
return $view->renderResponse('AdminModule/Debug');
}
The DocHeader¶
To add a DocHeader button use $this->moduleTemplate->getDocHeaderComponent()->getButtonBar()
and makeLinkButton()
to create the button. Finally use addButton()
to add it.
private function setDocHeader(string $active) {
$buttonBar = $this->moduleTemplate->getDocHeaderComponent()->getButtonBar();
$list = $buttonBar->makeLinkButton()
->setHref('<uri-builder-path>')
->setTitle('A Title')
->setShowLabelText('Link')
->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-extension-import', Icon::SIZE_SMALL));
$buttonBar->addButton($list, ButtonBar::BUTTON_POSITION_LEFT, 1);
}
See also
Template example¶
<html data-namespace-typo3-fluid="true" xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers">
<f:layout name="Module" />
<f:section name="Content">
<h1><f:translate key="function_debug" extensionName="examples"/></h1>
<p><f:translate key="function_debug_intro" extensionName="examples"/></p>
<p><f:debug inline="1">{cookies}</f:debug></p>
</f:section>
</html>
Note
Some Fluid tags do not work in non-Extbase context such as
<f:form>
.