Commit 1df84058 authored by Christian Kuhn's avatar Christian Kuhn Committed by Anja Leichsenring
Browse files

[TASK] Deprecate old ModuleTemplate API

With the introduction of the simplified ModuleTemplate
API and the transition of all core backend modules
towards it, the old API can and should be deprecated
to faciliate the "Override templates with TsConfig"
feature in extensions as well.

Resolves: #96903
Related: #96730
Related: #96812
Releases: main
Change-Id: I8b15e8f9d999cf61bf9856ceed67beb85921a4e4
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/73517


Tested-by: core-ci's avatarcore-ci <typo3@b13.com>
Tested-by: Stefan Bürk's avatarStefan Bürk <stefan@buerk.tech>
Tested-by: Anja Leichsenring's avatarAnja Leichsenring <aleichsenring@ab-softlab.de>
Reviewed-by: Stefan Bürk's avatarStefan Bürk <stefan@buerk.tech>
Reviewed-by: Anja Leichsenring's avatarAnja Leichsenring <aleichsenring@ab-softlab.de>
parent fcd236e3
...@@ -59,7 +59,7 @@ final class ModuleTemplate implements ViewInterface, ResponsableViewInterface ...@@ -59,7 +59,7 @@ final class ModuleTemplate implements ViewInterface, ResponsableViewInterface
protected DocHeaderComponent $docHeaderComponent; protected DocHeaderComponent $docHeaderComponent;
/** /**
* @todo: mark deprecated together with other legacy handling. * @deprecated: Remove together with legacy view handling below in v13.
*/ */
protected ?StandaloneView $legacyView = null; protected ?StandaloneView $legacyView = null;
...@@ -189,19 +189,32 @@ final class ModuleTemplate implements ViewInterface, ResponsableViewInterface ...@@ -189,19 +189,32 @@ final class ModuleTemplate implements ViewInterface, ResponsableViewInterface
return $this; return $this;
} }
/**
* Optional 'data-module-id="{moduleId}"' on first <div> in body.
* Can be helpful in JavaScript.
*/
public function setModuleId(string $moduleId): self public function setModuleId(string $moduleId): self
{ {
$this->moduleId = $moduleId; $this->moduleId = $moduleId;
// @deprecated: Remove together with registerModuleMenu() in v13.
$this->registerModuleMenu($moduleId); $this->registerModuleMenu($moduleId);
return $this; return $this;
} }
/**
* Optional 'data-module-name="{moduleName}"' on first <div> in body.
* Can be helpful in JavaScript.
*/
public function setModuleName(string $moduleName): self public function setModuleName(string $moduleName): self
{ {
$this->moduleName = $moduleName; $this->moduleName = $moduleName;
return $this; return $this;
} }
/**
* Optional 'class="module {moduleClass}"' on first <div> in body.
* Can be helpful styling modules.
*/
public function setModuleClass(string $moduleClass): self public function setModuleClass(string $moduleClass): self
{ {
$this->moduleClass = $moduleClass; $this->moduleClass = $moduleClass;
...@@ -220,7 +233,10 @@ final class ModuleTemplate implements ViewInterface, ResponsableViewInterface ...@@ -220,7 +233,10 @@ final class ModuleTemplate implements ViewInterface, ResponsableViewInterface
} }
/** /**
* @todo: Document scenarios where this is useful. * ModuleTemplate by default uses queue 'core.template.flashMessages'. Modules
* may want to maintain an own queue. Use this method to render flash messages
* of a non-default queue at the default position in module HTML output. Call
* this method *before* adding single messages with addFlashMessage().
*/ */
public function setFlashMessageQueue(FlashMessageQueue $flashMessageQueue): self public function setFlashMessageQueue(FlashMessageQueue $flashMessageQueue): self
{ {
...@@ -240,17 +256,17 @@ final class ModuleTemplate implements ViewInterface, ResponsableViewInterface ...@@ -240,17 +256,17 @@ final class ModuleTemplate implements ViewInterface, ResponsableViewInterface
} }
/** /**
* @internal Candidate to deprecate when View refactoring finished. * @deprecated since v12, will be removed in v13.
* @todo: deprecate. legacy.
*/ */
public function getView(): StandaloneView public function getView(): StandaloneView
{ {
trigger_error('Method ' . __METHOD__ . ' has been deprecated in v12 and will be removed with v13.', E_USER_DEPRECATED);
$this->initLegacyView(); $this->initLegacyView();
return $this->legacyView; return $this->legacyView;
} }
/** /**
* @todo: deprecate. legacy. * @deprecated since v12, will be removed in v13.
*/ */
public function setContent(string $content): self public function setContent(string $content): self
{ {
...@@ -260,10 +276,16 @@ final class ModuleTemplate implements ViewInterface, ResponsableViewInterface ...@@ -260,10 +276,16 @@ final class ModuleTemplate implements ViewInterface, ResponsableViewInterface
} }
/** /**
* @todo deprecate. legacy. * @deprecated since v12, will be removed in v13. Remove together with $legacyView property and Templates/Module.html.
*/ */
public function renderContent(): string public function renderContent(): string
{ {
trigger_error(
'Method ' . __METHOD__ . ' has been deprecated in v12 and will be removed with v13.'
. ' Use assign(), assignMultiple(), render() or renderResponse() instead and use Module'
. ' as *layout* in templates.',
E_USER_DEPRECATED
);
$this->initLegacyView(); $this->initLegacyView();
$this->legacyView->assignMultiple([ $this->legacyView->assignMultiple([
'docHeader' => $this->docHeaderComponent->docHeaderContent(), 'docHeader' => $this->docHeaderComponent->docHeaderContent(),
...@@ -288,7 +310,7 @@ final class ModuleTemplate implements ViewInterface, ResponsableViewInterface ...@@ -288,7 +310,7 @@ final class ModuleTemplate implements ViewInterface, ResponsableViewInterface
} }
/** /**
* @todo: remove along with legacy view handling. * @deprecated since v12, will be removed in v13.
*/ */
protected function initLegacyView(): void protected function initLegacyView(): void
{ {
...@@ -302,19 +324,21 @@ final class ModuleTemplate implements ViewInterface, ResponsableViewInterface ...@@ -302,19 +324,21 @@ final class ModuleTemplate implements ViewInterface, ResponsableViewInterface
/** /**
* Returns the current body tag. * Returns the current body tag.
* @todo: deprecate. ModuleTemplate should be a data sink only, here. * @deprecated since v12, will be removed in v13.
*/ */
public function getBodyTag(): string public function getBodyTag(): string
{ {
trigger_error('Method ' . __METHOD__ . ' has been deprecated in v12 and will be removed with v13.', E_USER_DEPRECATED);
return $this->bodyTag; return $this->bodyTag;
} }
/** /**
* Generates the Menu for things like Web->Info * Generates the Menu for things like Web->Info
* @todo: deprecate. unused. * @deprecated since v12, will be removed in v13.
*/ */
public function registerModuleMenu(string $moduleMenuIdentifier): self public function registerModuleMenu(string $moduleMenuIdentifier): self
{ {
trigger_error('Method ' . __METHOD__ . ' has been deprecated in v12 and will be removed with v13.', E_USER_DEPRECATED);
if (isset($GLOBALS['TBE_MODULES_EXT'][$moduleMenuIdentifier])) { if (isset($GLOBALS['TBE_MODULES_EXT'][$moduleMenuIdentifier])) {
$menuEntries = $menuEntries =
$GLOBALS['TBE_MODULES_EXT'][$moduleMenuIdentifier]['MOD_MENU']['function']; $GLOBALS['TBE_MODULES_EXT'][$moduleMenuIdentifier]['MOD_MENU']['function'];
...@@ -346,10 +370,15 @@ final class ModuleTemplate implements ViewInterface, ResponsableViewInterface ...@@ -346,10 +370,15 @@ final class ModuleTemplate implements ViewInterface, ResponsableViewInterface
* If you don't need this feature, e.g. for wizards like import/export you can * If you don't need this feature, e.g. for wizards like import/export you can
* disable this behaviour. * disable this behaviour.
* @return string * @return string
* @todo: render unused and deprecate. * @deprecated since v12, will be removed in v13.
*/ */
public function getDynamicTabMenu(array $menuItems, string $domId, int $defaultTabIndex = 1, bool $collapsible = false, bool $wrapContent = true, bool $storeLastActiveTab = true): string public function getDynamicTabMenu(array $menuItems, string $domId, int $defaultTabIndex = 1, bool $collapsible = false, bool $wrapContent = true, bool $storeLastActiveTab = true): string
{ {
trigger_error(
'Method ' . __METHOD__ . ' has been deprecated in v12 and will be removed with v13.'
. ' Inline the HTML into your template.',
E_USER_DEPRECATED
);
$this->pageRenderer->loadJavaScriptModule('@typo3/backend/tabs.js'); $this->pageRenderer->loadJavaScriptModule('@typo3/backend/tabs.js');
$view = GeneralUtility::makeInstance(BackendTemplateView::class); $view = GeneralUtility::makeInstance(BackendTemplateView::class);
$view->setTemplateRootPaths(['EXT:backend/Resources/Private/Templates']); $view->setTemplateRootPaths(['EXT:backend/Resources/Private/Templates']);
...@@ -371,19 +400,24 @@ final class ModuleTemplate implements ViewInterface, ResponsableViewInterface ...@@ -371,19 +400,24 @@ final class ModuleTemplate implements ViewInterface, ResponsableViewInterface
* @param string $text The text string for the header * @param string $text The text string for the header
* @param bool $inlineEdit Whether the header should be editable (e.g. page title) * @param bool $inlineEdit Whether the header should be editable (e.g. page title)
* @return string HTML content * @return string HTML content
* @internal * @deprecated since v12, will be removed in v13.
* @todo: render unused and remove.
*/ */
public function header(string $text, bool $inlineEdit = true): string public function header(string $text, bool $inlineEdit = true): string
{ {
trigger_error(
'Method ' . __METHOD__ . ' has been deprecated in v12 and will be removed with v13.'
. ' Inline the HTML into your template.',
E_USER_DEPRECATED
);
return '<h1 ' . ($inlineEdit ? 'class="t3js-title-inlineedit"' : '') . '>' . htmlspecialchars($text) . '</h1>'; return '<h1 ' . ($inlineEdit ? 'class="t3js-title-inlineedit"' : '') . '>' . htmlspecialchars($text) . '</h1>';
} }
/** /**
* @todo: deprecate. ModuleTemplate should be a data sink only, here. * @deprecated since v12, will be removed in v13.
*/ */
public function isUiBlock(): bool public function isUiBlock(): bool
{ {
trigger_error('Method ' . __METHOD__ . ' has been deprecated in v12 and will be removed with v13.', E_USER_DEPRECATED);
return $this->uiBlock; return $this->uiBlock;
} }
......
.. include:: ../../Includes.txt
======================================================
Deprecation: #96903 - Deprecate old ModuleTemplate API
======================================================
See :issue:`96903`
Description
===========
With introduction of the :doc:`simplified ModuleTemplate API <Feature-96730-SimplifiedExtbackendModuleTemplateAPI>`
a series of PHP methods in backend related :php:`ModuleTemplate` class became obsolete.
These methods are now marked as deprecated in TYPO3 v12 and will be removed in v13 to
encourage backend modules switching to the new API which is easier to use and
allows :doc:`overriding backend templates <Feature-96812-OverrideBackendTemplatesWithTSconfig>`.
The following methods should not be used anymore:
- :php:`ModuleTemplate->setContent()` and :php:`ModuleTemplate->renderContent()`: These methods
were the heart of the old API, using a :php:`StandaloneView` for module *template* rendering. They
are obsolete using :php:`ModuleTemplate->render()` or :php:`ModuleTemplate->renderResponse()` where
the outer ModuleTemplate HTML is referenced in "main body" templates as *layout*.
- :php:`ModuleTemplate->getView()`: This was an additional helper for :php:`ModuleTemplate->setContent()`
and :php:`ModuleTemplate->renderContent()` and is deprecated together with these.
- :php:`ModuleTemplate->getBodyTag()` and :php:`ModuleTemplate->isUiBlock()`: ModuleTemplate should be a
data sink. It should not be abused to carry data around that is later retrieved again. Controllers that
need these methods should be refactored slightly to carry the information around themselves.
- :php:`ModuleTemplate->registerModuleMenu()`: This was a helper method for "third level" menu
registration of (especially) the info module. It is unused in core since at least TYPO3 v7. Extensions
most likely don't use it.
- :php:`ModuleTemplate->getDynamicTabMenu()`: This is a helper to render a "tabbed" view of
item titles and item content. Using the methods leads to strange controller code that relies
on multiple Fluid view instances at the same time. Consuming controllers should instead
add the needed HTML to their templates directly. Example HTML can be found in the EXT:styleguide
backend module, section "Tabs".
- :php:`ModuleTemplate->header()`: This is a tiny helper method to render a :html:`<h1>`. It was used
to make the page title editable in a couple of controllers in the past. Extensions should put this
HTML directly into their templates.
Impact
======
Methods :php:`setContent()`, :php:`header()` and :php:`getView()` are rather common names, the extension
scanner is not configured to scan for them. All other methods names are scanned, the extension scanner
will report possible usages as weak match.
All methods will raise a deprecation level log entry when called. One exception is :php:`setContent()`,
which is always used in combination with :php:`renderContent()` to be useful, so only one deprecation
log entry is created when using both methods.
Affected Installations
======================
In general, instances with extensions that add custom backend modules may be affected.
Migration
=========
See the description section and :doc:`simplified ModuleTemplate API <Feature-96730-SimplifiedExtbackendModuleTemplateAPI>`
for migration information.
.. index:: Backend, PHP-API, PartiallyScanned, ext:backend
...@@ -55,7 +55,7 @@ be added to an extensions :file:`Configuration/page.tsconfig` file ...@@ -55,7 +55,7 @@ be added to an extensions :file:`Configuration/page.tsconfig` file
templates.typo3/cms-linkvalidator.1643293191 = my-vendor/my-extension:Resources/Private/TemplateOverrides templates.typo3/cms-linkvalidator.1643293191 = my-vendor/my-extension:Resources/Private/TemplateOverrides
When the target extension identified by its composer name "my-vendor/my-extension" provides the file When the target extension identified by its composer name "my-vendor/my-extension" provides the file
:file:`Resources/Private/LinkvalidatorOverrides/Templates/Backend/Report.html`, **this** file will :file:`Resources/Private/TemplateOverrides/Templates/Backend/Report.html`, **this** file will
be used instead of the default template file from the linkvalidator extension. be used instead of the default template file from the linkvalidator extension.
All core extensions stick to the general templates, layouts and partial file and directory position structure. All core extensions stick to the general templates, layouts and partial file and directory position structure.
......
...@@ -5169,4 +5169,39 @@ return [ ...@@ -5169,4 +5169,39 @@ return [
'Deprecation-96733-DeprecatedTBE_MODULESRelatedFunctionality.rst', 'Deprecation-96733-DeprecatedTBE_MODULESRelatedFunctionality.rst',
], ],
], ],
'TYPO3\CMS\Backend\Template\ModuleTemplate->renderContent' => [
'numberOfMandatoryArguments' => 0,
'maximumNumberOfArguments' => 0,
'restFiles' => [
'Deprecation-96903-DeprecateOldModuleTemplateAPI.rst',
],
],
'TYPO3\CMS\Backend\Template\ModuleTemplate->getBodyTag' => [
'numberOfMandatoryArguments' => 0,
'maximumNumberOfArguments' => 0,
'restFiles' => [
'Deprecation-96903-DeprecateOldModuleTemplateAPI.rst',
],
],
'TYPO3\CMS\Backend\Template\ModuleTemplate->registerModuleMenu' => [
'numberOfMandatoryArguments' => 1,
'maximumNumberOfArguments' => 1,
'restFiles' => [
'Deprecation-96903-DeprecateOldModuleTemplateAPI.rst',
],
],
'TYPO3\CMS\Backend\Template\ModuleTemplate->getDynamicTabMenu' => [
'numberOfMandatoryArguments' => 2,
'maximumNumberOfArguments' => 6,
'restFiles' => [
'Deprecation-96903-DeprecateOldModuleTemplateAPI.rst',
],
],
'TYPO3\CMS\Backend\Template\ModuleTemplate->isUiBlock' => [
'numberOfMandatoryArguments' => 0,
'maximumNumberOfArguments' => 0,
'restFiles' => [
'Deprecation-96903-DeprecateOldModuleTemplateAPI.rst',
],
],
]; ];
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment