Create a backend module with Extbase
Tip
A module that mainly shows and changes a few records does not need Extbase. See Create a backend module with Core functionality.
A backend module can be built with Extbase and Fluid. The module's controller
is an Extbase
Action,
and the domain models, repositories and validators of the extension work in
the module as they do in a frontend plugin. This is the better choice when the
module works with a domain model of its own.
An Extbase controller needs no attribute. Every class implementing
Controller is tagged
and made public automatically. The
As attribute is only for
backend controllers without Extbase.
Changed in version 14.0 Breaking: #105377 - Deprecated functionality removed
The class alias for
\TYPO3\ has been
removed.
\TYPO3\ is still in place.
Building such a module is described in a dedicated chapter:
- Registering an Extbase backend module — the Extbase-specific keys in
Configuration/Backend/Modules.php, and rendering withModuleinstead ofTemplate $this->view. - How an Extbase backend module works — how a request reaches the controller, which TypoScript the module sees, and how storage pages and language are resolved.
- Building an Extbase backend module without a page tree — a list with search, filters and pagination, and filters kept across requests.
- Editing records from an Extbase backend module — creating, editing and deleting records through FormEngine and DataHandler instead of own actions.
- Building an Extbase backend module with a page tree — a module that takes its storage folder, site and language from the selected page.
Fluid templates of an Extbase backend module
A module template uses the Module layout and puts its content into the
Content section. The layout belongs to the backend, not to the extension.
Module looks for templates
and layouts in EXT: first, and in the
extension that registered the module second. That is why
<f: finds the backend's
Layouts/ without any configuration.
Module also supplies the
document header and flash messages the layout renders:
<html
xmlns:be="http://typo3.org/ns/TYPO3/CMS/Backend/ViewHelpers"
xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers"
data-namespace-typo3-fluid="true">
<f:layout name="Module" />
<f:section name="Content">
<f:asset.module identifier="@typo3/backend/modal.js" />
<h1>Conferences</h1>
<f:form action="list" name="demand" object="{demand}">
<f:form.textfield property="searchWord" placeholder="Search" />
<f:form.select
property="status"
options="{published: 'Published', unpublished: 'Unpublished'}"
prependOptionLabel="All"
prependOptionValue=""
/>
<f:form.submit value="Filter" />
<f:link.action action="list" arguments="{operation: 'reset-filters'}">
Reset filters
</f:link.action>
</f:form>
<be:link.newRecord
table="tx_myextension_domain_model_conference"
pid="{newRecordPid}"
>
New conference
</be:link.newRecord>
<table class="table table-striped">
<f:for each="{paginator.paginatedItems}" as="conference">
<tr>
<td>
<be:link.editRecord
table="tx_myextension_domain_model_conference"
uid="{conference.uid}"
fields="title"
contextual="true"
>
{conference.title}
</be:link.editRecord>
</td>
<td>
<div class="btn-group">
<be:link.editRecord
table="tx_myextension_domain_model_conference"
uid="{conference.uid}"
class="btn btn-default"
>
Edit
</be:link.editRecord>
<a
href="{be:moduleLink(
route: 'tce_db',
query: 'cmd[tx_myextension_domain_model_conference][{conference.uid}][delete]=1',
currentUrlParameterName: 'redirect'
)}"
class="btn btn-default t3js-modal-trigger"
data-severity="warning"
data-title="Delete conference"
data-content="This conference will be deleted."
data-button-close-text="Cancel"
data-button-ok-text="Delete"
>
Delete
</a>
</div>
</td>
</tr>
</f:for>
</table>
<nav aria-label="Pagination">
<f:for each="{pagination.allPageNumbers}" as="page">
<f:link.action action="list" arguments="{currentPage: page}">
{page}
</f:link.action>
</f:for>
</nav>
</f:section>
</html>
Warning
Do not add a Layouts/ to your extension unless
you mean to replace the backend's layout. The extension's paths are
searched after the backend's, so its file wins, and a copied layout no
longer follows changes in Core. To change templates of a module
deliberately, use the templates option of
page TSconfig.
The same layout serves modules without Extbase. Buttons, menus and the breadcrumb in the document header are not Extbase-specific either, see Button components and DocHeaderComponent.
The best way to learn more is to read the modules that ship with TYPO3. The backend user module ( typo3/cms-beuser ) and the log module ( typo3/cms-belog ) are built with Extbase.