TYPO3 v15 dev-main snapshot ()
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _deprecation-102762-1710402828:
|
||||
|
||||
=======================================================
|
||||
Deprecation: #102762 - Deprecate GeneralUtility::hmac()
|
||||
=======================================================
|
||||
|
||||
See :issue:`102762`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
The method :php:`\TYPO3\CMS\Core\Utility\GeneralUtility::hmac()`
|
||||
has been deprecated in TYPO3 v13 and will be removed with v14 in
|
||||
favor of :ref:`feature-102761-1704532036`.
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
Usage of the method will raise a deprecation level log entry in
|
||||
TYPO3 v13 and a fatal error in TYPO3 v14.
|
||||
|
||||
|
||||
Affected installations
|
||||
======================
|
||||
|
||||
All third-party extensions using :php:`\TYPO3\CMS\Core\Utility\GeneralUtility::hmac()`.
|
||||
|
||||
|
||||
Migration
|
||||
=========
|
||||
|
||||
All usages of :php:`\TYPO3\CMS\Core\Utility\GeneralUtility::hmac()`
|
||||
must be migrated to use the :php:`hmac()` method in the class
|
||||
:php:`\TYPO3\CMS\Core\Crypto\HashService`.
|
||||
|
||||
Before
|
||||
------
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
//use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
$hmac = GeneralUtility::hmac('some-input', 'some-secret');
|
||||
|
||||
After
|
||||
-----
|
||||
|
||||
.. code-block:: php
|
||||
:caption: Using :php:`GeneralUtility::makeInstance()`
|
||||
|
||||
//use TYPO3\CMS\Core\Crypto\HashService;
|
||||
//use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
$hashService = GeneralUtility::makeInstance(HashService::class);
|
||||
$hmac = $hashService->hmac('some-input', 'some-secret');
|
||||
|
||||
.. code-block:: php
|
||||
:caption: Using dependency injection
|
||||
|
||||
namespace MyVendor\MyExt\Services;
|
||||
|
||||
use TYPO3\CMS\Core\Crypto\HashService;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
final readonly class MyService
|
||||
{
|
||||
public function __construct(
|
||||
private HashService $hashService,
|
||||
) {}
|
||||
|
||||
public function someMethod(): void
|
||||
{
|
||||
$hmac = $this->hashService->hmac('some-input', 'some-secret');
|
||||
}
|
||||
}
|
||||
|
||||
If possible, use dependency injection to inject :php:`HashService` into your class.
|
||||
|
||||
.. index:: Backend, FullyScanned, ext:core
|
||||
@@ -0,0 +1,56 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _deprecation-103211-1709038752:
|
||||
|
||||
=========================================================
|
||||
Deprecation: #103211 - Deprecate pageTree.backgroundColor
|
||||
=========================================================
|
||||
|
||||
See :issue:`103211`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
The user TSconfig option :typoscript:`options.pageTree.backgroundColor`
|
||||
has been deprecated and will be removed in TYPO3 v14 due to its
|
||||
lack of accessibility. It is being replaced with a
|
||||
:ref:`new label system <feature-103211-1709036591>` for tree nodes.
|
||||
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
During v13, :typoscript:`options.pageTree.backgroundColor` will be
|
||||
migrated to the new label system. Since the use case is unknown,
|
||||
the generated label will be "Color: <value>". This information
|
||||
will be displayed on all affected nodes.
|
||||
|
||||
|
||||
Affected installations
|
||||
======================
|
||||
|
||||
All installations that use the user TSconfig option
|
||||
:typoscript:`options.pageTree.backgroundColor` are affected.
|
||||
|
||||
|
||||
Migration
|
||||
=========
|
||||
|
||||
Before:
|
||||
|
||||
.. code-block:: typoscript
|
||||
:caption: EXT:my_extension/Configuration/user.tsconfig
|
||||
|
||||
options.pageTree.backgroundColor.<pageid> = #ff8700
|
||||
|
||||
After:
|
||||
|
||||
.. code-block:: typoscript
|
||||
:caption: EXT:my_extension/Configuration/user.tsconfig
|
||||
|
||||
options.pageTree.label.<pageid> {
|
||||
label = Campaign A
|
||||
color = #ff8700
|
||||
}
|
||||
|
||||
.. index:: Backend, JavaScript, TSConfig, NotScanned, ext:backend
|
||||
@@ -0,0 +1,62 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _deprecation-103230-1709202638:
|
||||
|
||||
===========================================================
|
||||
Deprecation: #103230 - Deprecate `@typo3/backend/wizard.js`
|
||||
===========================================================
|
||||
|
||||
See :issue:`103230`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
The TYPO3 backend module :js:`@typo3/backend/wizard.js` that offers simple
|
||||
wizards has been marked as deprecated in favor of the richer
|
||||
:js:`@typo3/backend/multi-step-wizard.js` module.
|
||||
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
Using the deprecated module will trigger a browser console warning.
|
||||
|
||||
|
||||
Affected installations
|
||||
======================
|
||||
|
||||
All installations using :js:`@typo3/backend/wizard.js` are affected.
|
||||
|
||||
|
||||
Migration
|
||||
=========
|
||||
|
||||
Migrate to the module :js:`@typo3/backend/multi-step-wizard.js`. There are two
|
||||
major differences:
|
||||
|
||||
* The class name changes to :js:`MultiStepWizard`.
|
||||
* The method :js:`addSlide()` receives an additional argument for the step title
|
||||
in the progress bar.
|
||||
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
.. code-block:: diff
|
||||
|
||||
-import Wizard from '@typo3/backend/wizard.js';
|
||||
+import MultiStepWizard from '@typo3/backend/multi-step-wizard.js';
|
||||
|
||||
-Wizard.addSlide(
|
||||
+MultiStepWizard.addSlide(
|
||||
'my-slide-identifier',
|
||||
'Slide title',
|
||||
'Content of my slide',
|
||||
SeverityEnum.notice,
|
||||
+ 'My step',
|
||||
function () {
|
||||
// callback executed after displaying the slide
|
||||
}
|
||||
);
|
||||
|
||||
.. index:: Backend, JavaScript, NotScanned, ext:backend
|
||||
@@ -0,0 +1,41 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _deprecation-103244-1709376790:
|
||||
|
||||
=========================================
|
||||
Deprecation: #103244 - Class SlugEnricher
|
||||
=========================================
|
||||
|
||||
See :issue:`103244`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
Class :php:`\TYPO3\CMS\Core\DataHandling\SlugEnricher` has been marked as
|
||||
deprecated in TYPO3 v13 and will be removed with v14.
|
||||
|
||||
The class was used as a helper for :php:`\TYPO3\CMS\Core\DataHandling\DataHandler`,
|
||||
which now inlines the code in a simplified variant.
|
||||
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
Using the class will raise a deprecation level log entry and a fatal error in TYPO3 v14.
|
||||
|
||||
|
||||
Affected installations
|
||||
======================
|
||||
|
||||
There is little to no reason to use this class in custom extensions, very few
|
||||
instances should be affected by this. The extension scanner will find usages
|
||||
with a strong match.
|
||||
|
||||
|
||||
Migration
|
||||
=========
|
||||
|
||||
No migration available.
|
||||
|
||||
|
||||
.. index:: PHP-API, FullyScanned, ext:core
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _deprecation-103528-1712153304:
|
||||
|
||||
==============================================================
|
||||
Deprecation: #103528 - Deprecated `DocumentSaveActions` module
|
||||
==============================================================
|
||||
|
||||
See :issue:`103528`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
The JavaScript module :js:`@typo3/backend/document-save-actions.js` was
|
||||
introduced in TYPO3 v7 to add some interactivity in FormEngine context.
|
||||
At first it was only used to disable the submit button and render a
|
||||
spinner icon instead. Over the course of some years, the module got more
|
||||
functionality, for example to prevent saving when validation fails.
|
||||
|
||||
Since some refactorings within FormEngine, the module rather became a
|
||||
burden. This became visible with the introduction of the
|
||||
:ref:`Hotkeys API <feature-101507-1690808401>`, as
|
||||
the :js:`@typo3/backend/document-save-actions.js` reacts on explicit :js:`click`
|
||||
events on the save icon, that is not triggered when FormEngine invokes a
|
||||
:ref:`save action via keyboard shortcuts <feature-103529-1712154338>`.
|
||||
Adjusting :js:`document-save-actions.js`'s
|
||||
behavior is necessary, but would become a breaking change, which is
|
||||
unacceptable after the 13.0 release. For this reason, said module has
|
||||
been marked as deprecated and its usages are replaced by its successor
|
||||
:js:`@typo3/backend/form/submit-interceptor.js`.
|
||||
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
Using the JavaScript module :js:`@typo3/backend/document-save-actions.js` will
|
||||
render a deprecation warning in the browser's console.
|
||||
|
||||
|
||||
Affected installations
|
||||
======================
|
||||
|
||||
All installations relying on :js:`@typo3/backend/document-save-actions.js` are
|
||||
affected.
|
||||
|
||||
|
||||
Migration
|
||||
=========
|
||||
|
||||
To migrate the interception of submit events, the successor module
|
||||
:js:`@typo3/backend/form/submit-interceptor.js` shall be used instead.
|
||||
|
||||
The usage is similar to :js:`@typo3/backend/document-save-actions.js`, but
|
||||
requires the form HTML element in its constructor.
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
.. code-block:: js
|
||||
|
||||
import '@typo3/backend/form/submit-interceptor.js';
|
||||
|
||||
// ...
|
||||
|
||||
const formElement = document.querySelector('form');
|
||||
const submitInterceptor = new SubmitInterceptor(formElement);
|
||||
submitInterceptor.addPreSubmitCallback(function() {
|
||||
// the same handling as in @typo3/backend/document-save-actions.js
|
||||
});
|
||||
|
||||
.. index:: Backend, JavaScript, NotScanned, ext:backend
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _deprecation-103850-1715873982:
|
||||
|
||||
================================================================
|
||||
Deprecation: #103850 - Renamed Page Tree Navigation Component ID
|
||||
================================================================
|
||||
|
||||
See :issue:`103850`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
When registering a module in the TYPO3 Backend, using the page tree as navigation component,
|
||||
the name of the page tree navigation component has been renamed in TYPO3 v13.
|
||||
|
||||
Previously, the navigation component was called
|
||||
:php:`@typo3/backend/page-tree/page-tree-element`, now it is named :php:`@typo3/backend/tree/page-tree-element`.
|
||||
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
Using the old navigation ID will trigger a PHP deprecation warning.
|
||||
|
||||
|
||||
Affected installations
|
||||
======================
|
||||
|
||||
TYPO3 installations with custom backend modules utilizing the page tree navigation component.
|
||||
|
||||
|
||||
Migration
|
||||
=========
|
||||
|
||||
Instead of writing this snippet in your :file:`Configuration/Backend/Modules.php`:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
'mymodule' => [
|
||||
'parent' => 'web',
|
||||
...
|
||||
'navigationComponent' => '@typo3/backend/page-tree/page-tree-element',
|
||||
],
|
||||
|
||||
It is now called:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
'mymodule' => [
|
||||
'parent' => 'web',
|
||||
...
|
||||
'navigationComponent' => '@typo3/backend/tree/page-tree-element',
|
||||
],
|
||||
|
||||
.. index:: Backend, PHP-API, NotScanned, ext:backend
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _feature-102836-1705994823:
|
||||
|
||||
===================================================================
|
||||
Feature: #102836 - Allow deleting IRRE elements via `postMessage()`
|
||||
===================================================================
|
||||
|
||||
See :issue:`102836`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
To invoke a deletion on items in FormEngine's Inline Relation container
|
||||
API-wise, a new message identifier :js:`typo3:foreignRelation:delete` has been
|
||||
introduced.
|
||||
|
||||
Example usage:
|
||||
|
||||
.. code-block:: js
|
||||
|
||||
import { MessageUtility } from '@typo3/backend/utility/message-utility.js';
|
||||
|
||||
MessageUtility.send({
|
||||
actionName: 'typo3:foreignRelation:delete',
|
||||
objectGroup: 'data-<page_id>-<parent_table>-<parent_uid>-<reference_table>',
|
||||
uid: '<reference_uid>'
|
||||
});
|
||||
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
Extension developers are now able to trigger the deletion of IRRE elements via
|
||||
API.
|
||||
|
||||
.. index:: Backend, JavaScript, ext:backend
|
||||
+110
@@ -0,0 +1,110 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _feature-103043-1707113495:
|
||||
|
||||
===========================================================================
|
||||
Feature: #103043 - Modernize tree rendering and implement RTL and dark mode
|
||||
===========================================================================
|
||||
|
||||
See :issue:`103043`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
The Tree feature in TYPO3 stands as one of its most iconic and widely used
|
||||
components, offering a visual representation of site structures to editors
|
||||
globally. Serving various purposes, such as file management, category/record
|
||||
selection, navigation, and more, the Tree has been a cornerstone for content
|
||||
handling.
|
||||
|
||||
Originally introduced in Version 8 with a performance-oriented approach, the
|
||||
SVG tree, powered by d3js, has faithfully served the community for the past
|
||||
seven years. While it excelled in providing a fast and efficient experience,
|
||||
it had its share of challenges, particularly due to its reliance on SVG and
|
||||
d3js.
|
||||
|
||||
Challenges with the SVG tree:
|
||||
|
||||
- Limited functionality due to SVG constraints
|
||||
- Maintenance complexities with code-built SVG
|
||||
- Accessibility challenges
|
||||
- Difficulty in extension and innovation
|
||||
- Lack of native drag and drop
|
||||
- Complexity hindering understanding for many
|
||||
|
||||
Recognizing these challenges, we embarked on a journey to reimagine the Tree
|
||||
component, paving the way for a more adaptable and user-friendly experience.
|
||||
|
||||
Introducing the Modern Reactive Tree:
|
||||
|
||||
The new Tree, built on contemporary web standards, bids farewell to the
|
||||
SVG tree's limitations. Embracing native drag and drop APIs, standard HTML
|
||||
markup, and CSS for styling, the Modern Reactive Tree promises improved
|
||||
maintainability and accessibility.
|
||||
|
||||
Key enhancements:
|
||||
|
||||
- Unified experience: All features are now consolidated into the base tree,
|
||||
ensuring a seamless and consistent user experience. This encompasses data
|
||||
loading and processing, selection, keyboard navigation, drag and drop, and
|
||||
basic node editing.
|
||||
|
||||
- User preferences: The tree now dynamically adjusts to user preferences,
|
||||
supporting both light/dark mode and left-to-right (LTR) or right-to-left
|
||||
(RTL) writing modes.
|
||||
|
||||
- Reactive rendering: Adopting a modern reactive rendering approach, the tree
|
||||
and its nodes now autonomously redraw themselves based on property changes,
|
||||
ensuring a smoother and more responsive interface.
|
||||
|
||||
- Native drag and drop: Leveraging native drag and drop functionality opens
|
||||
up avenues for future enhancements, such as dragging content directly onto
|
||||
a page or seamlessly moving elements between browser windows.
|
||||
|
||||
- Improved API endpoints: All endpoints delivering data for the tree now adhere
|
||||
to a defined API definition, enhancing consistency and compatibility with
|
||||
existing integrations.
|
||||
|
||||
- Unified dragging tooltip handling: The dragging tooltip handling has been
|
||||
adjusted to a unified component that can be utilized across all components,
|
||||
ensuring synchronization across browser windows.
|
||||
|
||||
- Dynamic tree status storage: The Pagetree status is no longer stored in the
|
||||
database. Instead, it is now stored in the local storage of the user's
|
||||
browser. This change empowers the browser to control the tree status, making
|
||||
it more convenient for users to transition between multiple browsers or
|
||||
machines.
|
||||
|
||||
- Enhanced virtual scroll: The virtual scroll of the tree has been improved,
|
||||
ensuring that only nodes currently visible to the user are rendered to the
|
||||
DOM. Additionally, the focus on selected nodes is maintained even when
|
||||
scrolled out of view, providing a smoother and more user-friendly experience.
|
||||
|
||||
As we transition to this Modern Reactive Tree, we anticipate a renewed era of
|
||||
flexibility, ease of use, and potential for exciting future features.
|
||||
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
The TYPO3 CMS Tree modernization brings:
|
||||
|
||||
- Personalization:
|
||||
Adapts to user preferences for a tailored interface.
|
||||
|
||||
- Reactive design:
|
||||
Ensures smoother interactions.
|
||||
|
||||
- Efficient integration:
|
||||
Improved API endpoints for seamless data exchange.
|
||||
|
||||
- Consistency across devices:
|
||||
Unified dragging and dynamic storage for a consistent experience.
|
||||
|
||||
- Enhanced performance:
|
||||
Optimal rendering during navigation.
|
||||
|
||||
These changes collectively enhance usability, adaptability, and performance,
|
||||
elevating the TYPO3 CMS Tree experience.
|
||||
|
||||
.. index:: Backend, ext:backend
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _feature-100268-1708278982:
|
||||
|
||||
==================================================================================
|
||||
Feature: #103147 - Provide full userdata in password recovery email in ext:backend
|
||||
==================================================================================
|
||||
|
||||
See :issue:`103147`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
A new array variable :html:`{userData}` has been added to the password
|
||||
recovery FluidEmail object. It contains the values of all fields from
|
||||
the :sql:`be_users` table belonging to the affected backend user.
|
||||
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
It is now possible to use the :html:`{userData}` variable in the password
|
||||
recovery FluidEmail to access data from the affected backend user.
|
||||
|
||||
.. index:: Backend, ext:backend
|
||||
@@ -0,0 +1,73 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _feature-103186-1708686767:
|
||||
|
||||
=========================================================
|
||||
Feature: #103186 - Introduce tree node status information
|
||||
=========================================================
|
||||
|
||||
See :issue:`103186`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
We've enhanced the backend tree component by extending tree nodes to
|
||||
incorporate status information. These details serve to indicate the
|
||||
status of nodes and provide supplementary information.
|
||||
|
||||
For instance, if a page undergoes changes within a workspace, it will
|
||||
now display an indicator on the respective tree node. Additionally,
|
||||
the status is appended to the node's title. This enhancement not only
|
||||
improves visual clarity but also enhances information accessibility.
|
||||
|
||||
Each node can accommodate multiple status information, prioritized by
|
||||
severity and urgency. Critical messages take precedence over other
|
||||
status notifications.
|
||||
|
||||
For example, status information can be added by using the event
|
||||
:php:`\TYPO3\CMS\Backend\Controller\Event\AfterPageTreeItemsPreparedEvent`:
|
||||
|
||||
.. code-block:: php
|
||||
:caption: EXT:my_extension/Classes/Backend/EventListener/ModifyPageTreeItems.php
|
||||
:emphasize-lines: 21-27
|
||||
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace MyVendor\MyExtension\Backend\EventListener;
|
||||
|
||||
use TYPO3\CMS\Backend\Controller\Event\AfterPageTreeItemsPreparedEvent;
|
||||
use TYPO3\CMS\Backend\Dto\Tree\Label\Label;
|
||||
use TYPO3\CMS\Core\Attribute\AsEventListener;
|
||||
|
||||
#[AsEventListener(
|
||||
identifier: 'my-extension/backend/modify-page-tree-items',
|
||||
)]
|
||||
final readonly class ModifyPageTreeItems
|
||||
{
|
||||
public function __invoke(AfterPageTreeItemsPreparedEvent $event): void
|
||||
{
|
||||
$items = $event->getItems();
|
||||
foreach ($items as &$item) {
|
||||
if ($item['_page']['uid'] === 123) {
|
||||
$item['statusInformation'][] = new StatusInformation(
|
||||
label: 'A warning message',
|
||||
severity: ContextualFeedbackSeverity::WARNING,
|
||||
priority: 0,
|
||||
icon: 'actions-dot',
|
||||
overlayIcon: '',
|
||||
);
|
||||
}
|
||||
}
|
||||
$event->setItems($items);
|
||||
}
|
||||
}
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
Tree nodes can now have status information. Workspace changes are
|
||||
now reflected in the title of the node in addition to the indicator.
|
||||
|
||||
.. index:: Backend, JavaScript, ext:backend
|
||||
@@ -0,0 +1,63 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _feature-103187-1708943723:
|
||||
|
||||
======================================================================
|
||||
Feature: #103187 - Introduce CLI command to create backend user groups
|
||||
======================================================================
|
||||
|
||||
See :issue:`103187`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
A new CLI command :bash:`./bin/typo3 setup:begroups:default` has been
|
||||
introduced as an alternative to the existing backend module. This command
|
||||
automates the creation of backend user groups, enabling the creation of
|
||||
two pre-configured backend user groups with permission presets applied.
|
||||
|
||||
.. note::
|
||||
|
||||
The pre-configured backend user group permissions are subject to be
|
||||
further changed and adjusted and defines a first set. It is also possible
|
||||
that additional groups may be added or made configurable. That means,
|
||||
that the :bash:`./bin/typo3 setup:begroups:default` command and the
|
||||
pre-defined permissions are considerable `experimental` during the
|
||||
TYPO3 v13 development cycle.
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
You can now use :bash:`./bin/typo3 setup:begroups:default` to create
|
||||
pre-configured backend user groups without touching the GUI.
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
Interactive / guided setup (questions/answers):
|
||||
|
||||
.. code-block:: bash
|
||||
:caption: Basic command
|
||||
|
||||
./bin/typo3 setup:begroups:default
|
||||
|
||||
The backend user group can be set via the :bash:`--groups|-g` option. Allowed
|
||||
values for groups are :bash:`Both`, :bash:`Editor` and :bash:`Advanced Editor`:
|
||||
|
||||
.. code-block:: bash
|
||||
:caption: Command examples
|
||||
|
||||
./bin/typo3 setup:begroups:default --groups Both
|
||||
./bin/typo3 setup:begroups:default --groups Editor
|
||||
./bin/typo3 setup:begroups:default --groups "Advanced Editor"
|
||||
|
||||
When using the :bash:`--no-interaction` option, this defaults to :bash:`Both`.
|
||||
|
||||
.. note::
|
||||
|
||||
At the moment, the command does not support the creation of backend user
|
||||
groups with custom names or permissions (they can be modified later through
|
||||
the backend module). It is limited to creating two pre-configured backend
|
||||
user groups with permission presets applied.
|
||||
|
||||
.. index:: Backend, CLI, ext:backend
|
||||
@@ -0,0 +1,101 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _feature-103211-1709036591:
|
||||
|
||||
=============================================
|
||||
Feature: #103211 - Introduce tree node labels
|
||||
=============================================
|
||||
|
||||
See :issue:`103211`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
We've upgraded the backend tree component by extending tree nodes to
|
||||
incorporate labels, offering enhanced functionality and additional
|
||||
information.
|
||||
|
||||
Before the implementation of labels, developers and integrators
|
||||
relied on :typoscript:`pageTree.backgroundColor.<pageid>` for visual cues,
|
||||
which has been :ref:`deprecated <deprecation-103211-1709038752>` with TYPO3 v13.
|
||||
However, these background colors lacked accessibility and meaningful context,
|
||||
catering only to users with perfect eyesight and excluding those
|
||||
dependent on screen readers or contrast modes.
|
||||
|
||||
With labels, we now cater to all editors. These labels not only offer
|
||||
customizable color markings for tree nodes but also require an
|
||||
associated label for improved accessibility.
|
||||
|
||||
Each node can support multiple labels, sorted by priority, with the
|
||||
highest priority label taking precedence over others. Users can
|
||||
assign a label to a node via user TSconfig, noting that only one label
|
||||
can be set through this method.
|
||||
|
||||
.. code-block:: typoscript
|
||||
:caption: EXT:my_extension/Configuration/user.tsconfig
|
||||
|
||||
options.pageTree.label.<pageid> {
|
||||
label = Campaign A
|
||||
color = #ff8700
|
||||
}
|
||||
|
||||
Labels also support locallang keys:
|
||||
|
||||
.. code-block:: typoscript
|
||||
:caption: EXT:my_extension/Configuration/user.tsconfig
|
||||
|
||||
options.pageTree.label.<pageid> {
|
||||
label = LLL:EXT:my_extension/Resources/Private/Language/locallang.xlf:labels.pageTree.campaign
|
||||
color = #ff8700
|
||||
}
|
||||
|
||||
The labels can also be added by using the event
|
||||
:php:`\TYPO3\CMS\Backend\Controller\Event\AfterPageTreeItemsPreparedEvent`.
|
||||
|
||||
.. code-block:: php
|
||||
:caption: EXT:my_extension/Classes/Backend/EventListener/ModifyPageTreeItems.php
|
||||
:emphasize-lines: 22-26
|
||||
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace MyVendor\MyExtension\Backend\EventListener;
|
||||
|
||||
use TYPO3\CMS\Backend\Controller\Event\AfterPageTreeItemsPreparedEvent;
|
||||
use TYPO3\CMS\Backend\Dto\Tree\Label\Label;
|
||||
use TYPO3\CMS\Core\Attribute\AsEventListener;
|
||||
|
||||
#[AsEventListener(
|
||||
identifier: 'my-extension/backend/modify-page-tree-items',
|
||||
)]
|
||||
final readonly class ModifyPageTreeItems
|
||||
{
|
||||
public function __invoke(AfterPageTreeItemsPreparedEvent $event): void
|
||||
{
|
||||
$items = $event->getItems();
|
||||
foreach ($items as &$item) {
|
||||
// Add special label for all pages with parent page ID 123
|
||||
if (($item['_page']['pid'] ?? null) === 123) {
|
||||
$item['labels'][] = new Label(
|
||||
label: 'Campaign B',
|
||||
color: '#00658f',
|
||||
priority: 1,
|
||||
);
|
||||
}
|
||||
}
|
||||
$event->setItems($items);
|
||||
}
|
||||
}
|
||||
|
||||
Please note that only the marker for the label with the highest priority is
|
||||
rendered. All additional labels will only be added to the title of the node.
|
||||
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
Labels are now added to the node and their children, significantly
|
||||
improving the clarity and accessibility of the tree component.
|
||||
|
||||
.. index:: Backend, JavaScript, TSConfig, ext:backend
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _feature-103220-1709106910:
|
||||
|
||||
====================================================================
|
||||
Feature: #103220 - Support comma-separated lists in page tree filter
|
||||
====================================================================
|
||||
|
||||
See :issue:`103220`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
The page tree has been enhanced to enable the user to not only search for
|
||||
strings and single page IDs, but for comma-separated lists of page IDs as well.
|
||||
|
||||
.. index:: Backend, ext:backend
|
||||
@@ -0,0 +1,34 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _feature-103255:
|
||||
|
||||
====================================================================
|
||||
Feature: #103255 - Native support for language Scottish Gaelic added
|
||||
====================================================================
|
||||
|
||||
See :issue:`103255`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
TYPO3 now supports Scottish Gaelic. Scottish Gaelic language is spoken in Scotland.
|
||||
|
||||
The ISO 639-1 code for Scottish Gaelic is "gd", which is how TYPO3
|
||||
accesses the language internally.
|
||||
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
It is now possible to
|
||||
|
||||
* Fetch translated labels from translations.typo3.org / CrowdIn automatically
|
||||
within the TYPO3 backend.
|
||||
* Switch the backend interface to Scottish Gaelic language.
|
||||
* Create a new language in a site configuration using Scottish Gaelic.
|
||||
* Create translation files with the "gd" prefix (such as `gd.locallang.xlf`)
|
||||
to create your own labels.
|
||||
|
||||
TYPO3 will pick Scottish Gaelic as a language just like any other supported language.
|
||||
|
||||
.. index:: Backend, Frontend, ext:core
|
||||
+732
@@ -0,0 +1,732 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _feature-103309-1709741435:
|
||||
|
||||
===================================================================
|
||||
Feature: #103309 - Add more expression methods to ExpressionBuilder
|
||||
===================================================================
|
||||
|
||||
See :issue:`103309`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
The TYPO3 :php:`\TYPO3\CMS\Core\Database\Query\Expression\ExpressionBuilder`
|
||||
provides a relatively conservative set of database query expressions since a
|
||||
couple of TYPO3 and Doctrine DBAL versions now.
|
||||
|
||||
Additional expression methods are now available to build more advanced database
|
||||
queries that ensure compatibility across supported database vendors.
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
|
||||
|
||||
:php:`ExpressionBuilder::as()`
|
||||
------------------------------
|
||||
|
||||
Creates a statement to append a field alias to a value, identifier or sub-expression.
|
||||
|
||||
.. note::
|
||||
|
||||
Some :php:`ExpressionBuilder` methods provides a argument to directly add
|
||||
the expression alias to reduce some nesting. This method can be used for
|
||||
custom expressions and avoids recurring conditional quoting and alias appending.
|
||||
|
||||
.. code-block:: php
|
||||
:caption: Method signature
|
||||
|
||||
/**
|
||||
* @param string $expression Value, identifier or expression which
|
||||
* should be aliased.
|
||||
* @param string $asIdentifier Used to add a field identifier alias
|
||||
* (`AS`) if non-empty string (optional).
|
||||
*
|
||||
* @return string Returns aliased expression.
|
||||
*/
|
||||
public function as(
|
||||
string $expression,
|
||||
string $asIdentifier = '',
|
||||
): string {}
|
||||
|
||||
// use TYPO3\CMS\Core\Database\Connection;
|
||||
// use TYPO3\CMS\Core\Database\ConnectionPool;
|
||||
// use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
|
||||
->getQueryBuilderForTable('some_table');
|
||||
$expressionBuilder = $queryBuilder->expr();
|
||||
|
||||
$queryBuilder->selectLiteral(
|
||||
$queryBuilder->quoteIdentifier('uid'),
|
||||
$expressionBuilder->as('(1 + 1 + 1)', 'calculated_field'),
|
||||
);
|
||||
|
||||
$queryBuilder->selectLiteral(
|
||||
$queryBuilder->quoteIdentifier('uid'),
|
||||
$expressionBuilder->as(
|
||||
$expressionBuilder->concat(
|
||||
$expressionBuilder->literal('1'),
|
||||
$expressionBuilder->literal(' '),
|
||||
$expressionBuilder->literal('1'),
|
||||
),
|
||||
'concatenated_value'
|
||||
),
|
||||
);
|
||||
|
||||
|
||||
:php:`ExpressionBuilder::concat()`
|
||||
----------------------------------
|
||||
|
||||
Can be used to concatenate values, row field values or expression results into
|
||||
a single string value.
|
||||
|
||||
.. note::
|
||||
|
||||
The created expression is built on the proper platform specific and preferred
|
||||
concatenation method, for example :sql:`string || string || string || ...`
|
||||
for SQLite and :sql:`CONCAT(...string)` for other database vendors.
|
||||
|
||||
.. code-block:: php
|
||||
:caption: Method signature
|
||||
|
||||
/**
|
||||
* @param string ...$parts Unquoted value or expression parts to
|
||||
* concatenate with each other
|
||||
* @return string Returns the concatenation expression compatible with
|
||||
* the database connection platform.
|
||||
*/
|
||||
public function concat(string ...$parts): string {}
|
||||
|
||||
.. code-block:: php
|
||||
:caption: Usage example
|
||||
|
||||
// use TYPO3\CMS\Core\Database\Connection;
|
||||
// use TYPO3\CMS\Core\Database\ConnectionPool;
|
||||
// use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
|
||||
->getQueryBuilderForTable('pages');
|
||||
$expressionBuilder = $queryBuilder->expr();
|
||||
$result = $queryBuilder
|
||||
->select('uid', 'pid', 'title')
|
||||
->addSelectLiteral(
|
||||
$expressionBuilder->concat(
|
||||
$queryBuilder->quoteIdentifier('title'),
|
||||
$queryBuilder->quote(' - ['),
|
||||
$queryBuilder->quoteIdentifier('uid'),
|
||||
$queryBuilder->quote('|'),
|
||||
$queryBuilder->quoteIdentifier('pid'),
|
||||
$queryBuilder->quote(']'),
|
||||
) . ' AS ' . $queryBuilder->quoteIdentifier('page_title_info')
|
||||
)
|
||||
->where(
|
||||
$expressionBuilder->eq(
|
||||
'pid',
|
||||
$queryBuilder->createNamedParameter(0, Connection::PARAM_INT)
|
||||
),
|
||||
)
|
||||
->executeQuery();
|
||||
|
||||
while ($row = $result->fetchAssociative()) {
|
||||
// $row = array{
|
||||
// 'uid' => 1,
|
||||
// 'pid' => 0,
|
||||
// 'title' => 'Site Root Page',
|
||||
// 'page_title_info' => 'Site Root Page - [1|0]',
|
||||
// }
|
||||
}
|
||||
|
||||
.. warning::
|
||||
|
||||
Be aware to properly quote values, identifiers and sub-expressions.
|
||||
No automatic quoting will be applied.
|
||||
|
||||
:php:`ExpressionBuilder::castVarchar()`
|
||||
---------------------------------------
|
||||
|
||||
Can be used to create an expression which converts a value, row field value or
|
||||
the result of an expression to varchar type with dynamic length.
|
||||
|
||||
.. note::
|
||||
|
||||
Use the platform specific preferred way for casting to dynamic length
|
||||
character type, which means :sql:`CAST("value" AS VARCHAR(<LENGTH>))`
|
||||
or :sql:`CAST("value" AS CHAR(<LENGTH>))` is used, except PostgreSQL.
|
||||
For PostgreSQL the :sql:`"value"::INTEGER` cast notation is used.
|
||||
|
||||
.. code-block:: php
|
||||
:caption: Method signature
|
||||
|
||||
/**
|
||||
* @param string $value Unquoted value or expression,
|
||||
* which should be casted.
|
||||
* @param int $length Dynamic varchar field length.
|
||||
* @param string $asIdentifier Used to add a field identifier alias
|
||||
* (`AS`) if non-empty string (optional).
|
||||
* @return string Returns the cast expression compatible for the database platform.
|
||||
*/
|
||||
public function castVarchar(
|
||||
string $value,
|
||||
int $length = 255,
|
||||
string $asIdentifier = '',
|
||||
): string {}
|
||||
|
||||
.. code-block:: php
|
||||
:caption: Usage example
|
||||
|
||||
// use TYPO3\CMS\Core\Database\ConnectionPool;
|
||||
// use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
|
||||
->getQueryBuilderForTable('some_table');
|
||||
|
||||
$fieldVarcharCastExpression = $queryBuilder->expr()->castVarchar(
|
||||
$queryBuilder->quote('123'), // integer as string
|
||||
255, // convert to varchar(255) field - dynamic length
|
||||
'new_field_identifier',
|
||||
);
|
||||
|
||||
$fieldExpressionCastExpression = $queryBuilder->expr()->castVarchar(
|
||||
'(100 + 200)', // calculate a integer value
|
||||
100, // dynamic varchar(100) field
|
||||
'new_field_identifier',
|
||||
);
|
||||
|
||||
.. warning::
|
||||
|
||||
Be aware to properly quote values, identifiers and sub-expressions.
|
||||
No automatic quoting will be applied.
|
||||
|
||||
:php:`ExpressionBuilder::castInt()`
|
||||
-----------------------------------
|
||||
|
||||
Can be used to create an expression which converts a value, row field value or
|
||||
the result of an expression to signed integer type.
|
||||
|
||||
.. note::
|
||||
|
||||
Use the platform specific preferred way for casting to dynamic length
|
||||
character type, which means :sql:`CAST("value" AS INTEGER)` for most database vendors
|
||||
except PostgreSQL. For PostgreSQL the :sql:`"value"::INTEGER` cast notation
|
||||
is used.
|
||||
|
||||
.. code-block:: php
|
||||
:caption: Method signature
|
||||
|
||||
/**
|
||||
* @param string $value Quoted value or expression result which
|
||||
* should be casted to integer type.
|
||||
* @param string $asIdentifier Used to add a field identifier alias
|
||||
* (`AS`) if non-empty string (optional).
|
||||
* @return string Returns the integer cast expression compatible with the
|
||||
* connection database platform.
|
||||
*/
|
||||
public function castInt(string $value, string $asIdentifier = ''): string {}
|
||||
|
||||
.. code-block:: php
|
||||
:caption: Usage example
|
||||
|
||||
// use TYPO3\CMS\Core\Database\ConnectionPool;
|
||||
// use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
|
||||
->getQueryBuilderForTable('pages');
|
||||
$queryBuilder
|
||||
->select('uid')
|
||||
->from('pages');
|
||||
|
||||
// simple value (quoted) to be used as sub-expression
|
||||
$expression1 = $queryBuilder->expr()->castInt(
|
||||
$queryBuilder->quote('123'),
|
||||
);
|
||||
|
||||
// simple value (quoted) to return as select field
|
||||
$queryBuilder->addSelectLiteral(
|
||||
$queryBuilder->expr()->castInt(
|
||||
$queryBuilder->quote('123'),
|
||||
'virtual_field',
|
||||
),
|
||||
);
|
||||
|
||||
$expression3 = queryBuilder->expr()->castInt(
|
||||
$queryBuilder->quoteIdentifier('uid'),
|
||||
);
|
||||
|
||||
// expression to be used as sub-expression
|
||||
$expression4 = $queryBuilder->expr()->castInt(
|
||||
$queryBuilder->expr()->castVarchar('(1 * 10)'),
|
||||
);
|
||||
|
||||
// expression to return as select field
|
||||
$queryBuilder->addSelectLiteral(
|
||||
$queryBuilder->expr()->castInt(
|
||||
$queryBuilder->expr()->castVarchar('(1 * 10)'),
|
||||
'virtual_field',
|
||||
),
|
||||
);
|
||||
|
||||
.. warning::
|
||||
|
||||
Be aware to properly quote values, identifiers and sub-expressions.
|
||||
No automatic quoting will be applied.
|
||||
|
||||
:php:`ExpressionBuilder::repeat()`
|
||||
----------------------------------
|
||||
|
||||
Create a statement to generate a value repeating defined :php:`$value` for
|
||||
:php:`$numberOfRepeats` times. This method can be used to provide the
|
||||
repeat number as a sub-expression or calculation.
|
||||
|
||||
.. note::
|
||||
|
||||
:sql:`REPEAT(string, number)` is used to build this expression for all database
|
||||
vendors except SQLite for which the compatible replacement construct expression
|
||||
:sql:`REPLACE(PRINTF('%.' || <valueOrStatement> || 'c', '/'),'/', <repeatValue>)`
|
||||
is used, based on :sql:`REPLACE()` and the built-in :sql:`printf()`.
|
||||
|
||||
.. code-block:: php
|
||||
:caption: Method signature
|
||||
|
||||
/**
|
||||
* @param int|string $numberOfRepeats Statement or value defining
|
||||
* how often the $value should
|
||||
* be repeated. Proper quoting
|
||||
* must be ensured.
|
||||
* @param string $value Value which should be repeated.
|
||||
* Proper quoting must be ensured.
|
||||
* @param string $asIdentifier Provide `AS` identifier if not
|
||||
* empty.
|
||||
* @return string Returns the platform compatible statement to create the
|
||||
* x-times repeated value.
|
||||
*/
|
||||
public function repeat(
|
||||
int|string $numberOfRepeats,
|
||||
string $value,
|
||||
string $asIdentifier = '',
|
||||
): string {}
|
||||
|
||||
.. code-block:: php
|
||||
:caption: Usage example
|
||||
|
||||
// use TYPO3\CMS\Core\Database\ConnectionPool;
|
||||
// use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
|
||||
->getQueryBuilderForTable('some_table');
|
||||
|
||||
$expression1 = $queryBuilder->expr()->repeat(
|
||||
10,
|
||||
$queryBuilder->quote('.'),
|
||||
);
|
||||
|
||||
$expression2 = $queryBuilder->expr()->repeat(
|
||||
20,
|
||||
$queryBuilder->quote('0'),
|
||||
$queryBuilder->quoteIdentifier('aliased_field'),
|
||||
);
|
||||
|
||||
$expression3 = $queryBuilder->expr()->repeat(
|
||||
20,
|
||||
$queryBuilder->quoteIdentifier('table_field'),
|
||||
$queryBuilder->quoteIdentifier('aliased_field'),
|
||||
);
|
||||
|
||||
$expression4 = $queryBuilder->expr()->repeat(
|
||||
$queryBuilder->expr()->castInt(
|
||||
$queryBuilder->quoteIdentifier('repeat_count_field')
|
||||
),
|
||||
$queryBuilder->quoteIdentifier('table_field'),
|
||||
$queryBuilder->quoteIdentifier('aliased_field'),
|
||||
);
|
||||
|
||||
$expression5 = $queryBuilder->expr()->repeat(
|
||||
'(7 + 3)',
|
||||
$queryBuilder->quote('.'),
|
||||
);
|
||||
|
||||
$expression6 = $queryBuilder->expr()->repeat(
|
||||
'(7 + 3)',
|
||||
$queryBuilder->concat(
|
||||
$queryBuilder->quote(''),
|
||||
$queryBuilder->quote('.'),
|
||||
$queryBuilder->quote(''),
|
||||
),
|
||||
'virtual_field_name',
|
||||
);
|
||||
|
||||
.. warning::
|
||||
|
||||
Be aware to properly quote values, identifiers and sub-expressions.
|
||||
No automatic quoting will be applied.
|
||||
|
||||
:php:`ExpressionBuilder::space()`
|
||||
---------------------------------
|
||||
|
||||
Create statement containing :php:`$numberOfSpaces` spaces.
|
||||
|
||||
.. note::
|
||||
|
||||
The :sql:`SPACE(number)` expression is used for MariaDB and MySQL and
|
||||
:php:`ExpressionBuilder::repeat()` expression as fallback for PostgreSQL
|
||||
and SQLite.
|
||||
|
||||
.. code-block:: php
|
||||
:caption: Method signature
|
||||
|
||||
/**
|
||||
* @param int|string $numberOfSpaces Expression or value defining how
|
||||
* many spaces should be created.
|
||||
* @param string $asIdentifier Provide result as identifier field
|
||||
* (AS), not added if empty string.
|
||||
* @return string Returns the platform compatible statement to create the
|
||||
* x-times repeated space(s).
|
||||
*/
|
||||
public function space(
|
||||
string $numberOfSpaces,
|
||||
string $asIdentifier = '',
|
||||
): string {}
|
||||
|
||||
.. code-block:: php
|
||||
:caption: Usage example
|
||||
|
||||
// use TYPO3\CMS\Core\Database\ConnectionPool;
|
||||
// use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
|
||||
->getQueryBuilderForTable('some_table');
|
||||
|
||||
$expression1 = $queryBuilder->expr()->space(
|
||||
'10'
|
||||
);
|
||||
|
||||
$expression2 = $queryBuilder->expr()->space(
|
||||
'20',
|
||||
$queryBuilder->quoteIdentifier('aliased_field'),
|
||||
);
|
||||
|
||||
$expression3 = $queryBuilder->expr()->space(
|
||||
'(210)'
|
||||
);
|
||||
|
||||
$expression3 = $queryBuilder->expr()->space(
|
||||
'(210)',
|
||||
$queryBuilder->quoteIdentifier('aliased_field'),
|
||||
);
|
||||
|
||||
$expression5 = $queryBuilder->expr()->space(
|
||||
$queryBuilder->expr()->castInt(
|
||||
$queryBuilder->quoteIdentifier('table_repeat_number_field'),
|
||||
),
|
||||
);
|
||||
|
||||
$expression6 = $queryBuilder->expr()->space(
|
||||
$queryBuilder->expr()->castInt(
|
||||
$queryBuilder->quoteIdentifier('table_repeat_number_field'),
|
||||
),
|
||||
$queryBuilder->quoteIdentifier('aliased_field'),
|
||||
);
|
||||
|
||||
.. warning::
|
||||
|
||||
Be aware to properly quote values, identifiers and sub-expressions.
|
||||
No automatic quoting will be applied.
|
||||
|
||||
:php:`ExpressionBuilder::left()`
|
||||
--------------------------------
|
||||
|
||||
Extract :php:`$length` character of :php:`$value` from the left side.
|
||||
|
||||
.. note::
|
||||
|
||||
Creates a :sql:`LEFT(string, number_of_chars)` expression for all supported
|
||||
database vendors except SQLite, where :sql:`substring(string, integer[, integer])`
|
||||
is used to provide a compatible expression.
|
||||
|
||||
.. code-block:: php
|
||||
:caption: Method signature
|
||||
|
||||
/**
|
||||
* @param int|string $length Integer value or expression
|
||||
* providing the length as integer.
|
||||
* @param string $value Value, identifier or expression
|
||||
* defining the value to extract from
|
||||
* the left.
|
||||
* @param string $asIdentifier Provide `AS` identifier if not empty.
|
||||
* @return string Return the expression to extract defined substring
|
||||
* from the right side.
|
||||
*/
|
||||
public function left(
|
||||
int|string $length,
|
||||
string $value,
|
||||
string $asIdentifier = '',
|
||||
): string {}
|
||||
|
||||
.. code-block:: php
|
||||
:caption: Usage example
|
||||
|
||||
// use TYPO3\CMS\Core\Database\ConnectionPool;
|
||||
// use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
|
||||
->getQueryBuilderForTable('some_table');
|
||||
|
||||
$expression1 = $queryBuilder->expr()->left(
|
||||
6,
|
||||
$queryBuilder->quote('some-string'),
|
||||
);
|
||||
|
||||
$expression2 = $queryBuilder->expr()->left(
|
||||
'6',
|
||||
$queryBuilder->quote('some-string'),
|
||||
);
|
||||
|
||||
$expression3 = $queryBuilder->expr()->left(
|
||||
$queryBuilder->castInt('(23)'),
|
||||
$queryBuilder->quote('some-string'),
|
||||
);
|
||||
|
||||
$expression4 = $queryBuilder->expr()->left(
|
||||
$queryBuilder->castInt('(23)'),
|
||||
$queryBuilder->quoteIdentifier('table_field_name'),
|
||||
);
|
||||
|
||||
.. tip::
|
||||
|
||||
For other sub string operations, :php:`\Doctrine\DBAL\Platforms\AbstractPlatform::getSubstringExpression()`
|
||||
can be used. Synopsis: :php:`getSubstringExpression(string $string, string $start, ?string $length = null): string`.
|
||||
|
||||
:php:`ExpressionBuilder::right()`
|
||||
---------------------------------
|
||||
|
||||
Extract :php:`$length` character of :php:`$value` from the right side.
|
||||
|
||||
.. note::
|
||||
|
||||
Creates a :sql:`RIGHT(string, number_of_chars)` expression for all supported
|
||||
database vendors except SQLite, where :sql:`substring(string, integer[, integer])`
|
||||
is used to provide a compatible expression.
|
||||
|
||||
.. code-block:: php
|
||||
:caption: Method signature
|
||||
|
||||
/**
|
||||
* @param int|string $length Integer value or expression
|
||||
* providing the length as integer.
|
||||
* @param string $value Value, identifier or expression
|
||||
* defining the value to extract from
|
||||
* the right.
|
||||
* @param string $asIdentifier Provide `AS` identifier if not empty.
|
||||
*
|
||||
* @return string Return the expression to extract defined substring
|
||||
* from the right side.
|
||||
*/
|
||||
public function right(
|
||||
int|string $length,
|
||||
string $value,
|
||||
string $asIdentifier = '',
|
||||
): string {}
|
||||
|
||||
.. code-block:: php
|
||||
:caption: Usage example
|
||||
|
||||
// use TYPO3\CMS\Core\Database\ConnectionPool;
|
||||
// use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
|
||||
->getQueryBuilderForTable('some_table');
|
||||
|
||||
$expression1 = $queryBuilder->expr()->right(
|
||||
6,
|
||||
$queryBuilder->quote('some-string'),
|
||||
);
|
||||
|
||||
$expression2 = $queryBuilder->expr()->right(
|
||||
'6',
|
||||
$queryBuilder->quote('some-string'),
|
||||
);
|
||||
|
||||
$expression3 = $queryBuilder->expr()->right(
|
||||
$queryBuilder->castInt('(23)'),
|
||||
$queryBuilder->quote('some-string'),
|
||||
);
|
||||
|
||||
$expression4 = $queryBuilder->expr()->right(
|
||||
$queryBuilder->castInt('(23)'),
|
||||
$queryBuilder->quoteIdentifier('table_field_name'),
|
||||
);
|
||||
|
||||
.. warning::
|
||||
|
||||
Be aware to properly quote values, identifiers and sub-expressions.
|
||||
No automatic quoting will be applied.
|
||||
|
||||
:php:`ExpressionBuilder::leftPad()`
|
||||
-----------------------------------
|
||||
|
||||
Left-pad the value or sub-expression result with $paddingValue, to a total
|
||||
length of $length.
|
||||
|
||||
.. note::
|
||||
|
||||
SQLite does not support :sql:`LPAD(string, integer, string)`, therefore a
|
||||
more complex compatible replacement expression construct is created.
|
||||
|
||||
.. code-block:: php
|
||||
:caption: Method signature
|
||||
|
||||
/**
|
||||
* @param string $value Value, identifier or expression
|
||||
* defining the value which should
|
||||
* be left padded.
|
||||
* @param int|string $length Value, identifier or expression
|
||||
* defining the padding length to
|
||||
* fill up on the left or crop.
|
||||
* @param string $paddingValue Padding character used to fill
|
||||
* up if characters are missing on
|
||||
* the left side.
|
||||
* @param string $asIdentifier Used to add a field identifier alias
|
||||
* (`AS`) if non-empty string (optional).
|
||||
* @return string Returns database connection platform compatible
|
||||
* left-pad expression.
|
||||
*/
|
||||
public function leftPad(
|
||||
string $value,
|
||||
int|string $length,
|
||||
string $paddingValue,
|
||||
string $asIdentifier = '',
|
||||
): string {}
|
||||
|
||||
.. code-block:: php
|
||||
:caption: Usage example
|
||||
|
||||
// use TYPO3\CMS\Core\Database\ConnectionPool;
|
||||
// use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
|
||||
->getQueryBuilderForTable('some_table');
|
||||
|
||||
$expression1 = $queryBuilder->expr()->leftPad(
|
||||
$queryBuilder->quote('123'),
|
||||
10,
|
||||
'0',
|
||||
);
|
||||
|
||||
$expression2 = $queryBuilder->expr()->leftPad(
|
||||
$queryBuilder->expr()->castVarchar($queryBuilder->quoteIdentifier('uid')),
|
||||
10,
|
||||
'0',
|
||||
);
|
||||
|
||||
$expression3 = $queryBuilder->expr()->leftPad(
|
||||
$queryBuilder->expr()->concat(
|
||||
$queryBuilder->quote('1'),
|
||||
$queryBuilder->quote('2'),
|
||||
$queryBuilder->quote('3'),
|
||||
),
|
||||
10,
|
||||
'0',
|
||||
);
|
||||
|
||||
$expression4 = $queryBuilder->expr()->leftPad(
|
||||
$queryBuilder->castVarchar('( 1123 )'),
|
||||
10,
|
||||
'0',
|
||||
);
|
||||
|
||||
$expression5 = $queryBuilder->expr()->leftPad(
|
||||
$queryBuilder->castVarchar('( 1123 )'),
|
||||
10,
|
||||
'0',
|
||||
'virtual_field',
|
||||
);
|
||||
|
||||
.. warning::
|
||||
|
||||
Be aware to properly quote values, identifiers and sub-expressions.
|
||||
No automatic quoting will be applied.
|
||||
|
||||
:php:`ExpressionBuilder::rightPad()`
|
||||
------------------------------------
|
||||
|
||||
Right-pad the value or sub-expression result with :php:`$paddingValue`, to a
|
||||
total length of :php:`$length`.
|
||||
|
||||
.. note::
|
||||
|
||||
SQLite does not support :sql:`RPAD(string, integer, string)`, therefore a
|
||||
complexer compatible replacement expression construct is created.
|
||||
|
||||
.. code-block:: php
|
||||
:caption: Method signature
|
||||
|
||||
/**
|
||||
* @param string $value Value, identifier or expression
|
||||
* defining the value which should be
|
||||
* right padded.
|
||||
* @param int|string $length Value, identifier or expression
|
||||
* defining the padding length to
|
||||
* fill up on the right or crop.
|
||||
* @param string $paddingValue Padding character used to fill up
|
||||
* if characters are missing on the
|
||||
* right side.
|
||||
* @param string $asIdentifier Used to add a field identifier alias
|
||||
* (`AS`) if non-empty string (optional).
|
||||
* @return string Returns database connection platform compatible
|
||||
* right-pad expression.
|
||||
*/
|
||||
public function rightPad(
|
||||
string $value,
|
||||
int|string $length,
|
||||
string $paddingValue,
|
||||
string $asIdentifier = '',
|
||||
): string {}
|
||||
|
||||
.. code-block:: php
|
||||
:caption: Usage example
|
||||
|
||||
// use TYPO3\CMS\Core\Database\ConnectionPool;
|
||||
// use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
|
||||
->getQueryBuilderForTable('some_table');
|
||||
|
||||
$expression1 = $queryBuilder->expr()->rightPad(
|
||||
$queryBuilder->quote('123'),
|
||||
10,
|
||||
'0',
|
||||
);
|
||||
|
||||
$expression2 = $queryBuilder->expr()->rightPad(
|
||||
$queryBuilder->expr()->castVarchar($queryBuilder->quoteIdentifier('uid')),
|
||||
10,
|
||||
'0',
|
||||
);
|
||||
|
||||
$expression3 = $queryBuilder->expr()->rightPad(
|
||||
$queryBuilder->expr()->concat(
|
||||
$queryBuilder->quote('1'),
|
||||
$queryBuilder->quote('2'),
|
||||
$queryBuilder->quote('3'),
|
||||
),
|
||||
10,
|
||||
'0',
|
||||
);
|
||||
|
||||
$expression4 = $queryBuilder->expr()->rightPad(
|
||||
$queryBuilder->castVarchar('( 1123 )'),
|
||||
10,
|
||||
'0',
|
||||
);
|
||||
|
||||
$expression5 = $queryBuilder->expr()->rightPad(
|
||||
$queryBuilder->quote('123'),
|
||||
10,
|
||||
'0',
|
||||
'virtual_field',
|
||||
);
|
||||
|
||||
.. warning::
|
||||
|
||||
Be aware to properly quote values, identifiers and sub-expressions.
|
||||
No automatic quoting will be applied.
|
||||
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
Extension authors can use the new expression methods to build more advanced
|
||||
queries without the requirement to deal with the correct implementation for
|
||||
all supported database vendors.
|
||||
|
||||
.. index:: Database, PHP-API, ext:core
|
||||
@@ -0,0 +1,34 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _feature-103331:
|
||||
|
||||
============================================================
|
||||
Feature: #103331 - Native support for language Maltese added
|
||||
============================================================
|
||||
|
||||
See :issue:`103331`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
TYPO3 now supports Maltese. Maltese language is spoken in Malta.
|
||||
|
||||
The ISO 639-1 code for Maltese is "mt", which is how TYPO3
|
||||
accesses the language internally.
|
||||
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
It is now possible to
|
||||
|
||||
* Fetch translated labels from translations.typo3.org / CrowdIn automatically
|
||||
within the TYPO3 backend.
|
||||
* Switch the backend interface to Maltese language.
|
||||
* Create a new language in a site configuration using Maltese.
|
||||
* Create translation files with the "mt" prefix (such as `mt.locallang.xlf`)
|
||||
to create your own labels.
|
||||
|
||||
TYPO3 will pick Maltese as a language just like any other supported language.
|
||||
|
||||
.. index:: Backend, Frontend, ext:core
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _feature-103372:
|
||||
|
||||
=================================================================
|
||||
Feature: #103372 - Native support for language Irish Gaelic added
|
||||
=================================================================
|
||||
|
||||
See :issue:`103372`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
TYPO3 now supports Irish Gaelic. Irish Gaelic language is spoken in Ireland.
|
||||
|
||||
The ISO 639-1 code for Irish Gaelic is "ga", which is how TYPO3
|
||||
accesses the language internally.
|
||||
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
It is now possible to
|
||||
|
||||
* Fetch translated labels from translations.typo3.org / CrowdIn automatically
|
||||
within the TYPO3 backend.
|
||||
* Switch the backend interface to Irish Gaelic language.
|
||||
* Create a new language in a site configuration using Irish Gaelic.
|
||||
* Create translation files with the "ga" prefix (such as `ga.locallang.xlf`)
|
||||
to create your own labels.
|
||||
|
||||
TYPO3 will pick Irish Gaelic as a language just like any other supported language.
|
||||
|
||||
.. index:: Backend, Frontend, ext:core
|
||||
@@ -0,0 +1,155 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _feature-103437-1712062105:
|
||||
|
||||
======================================
|
||||
Feature: #103437 - Introduce site sets
|
||||
======================================
|
||||
|
||||
See :issue:`103437`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
Site sets ship parts of site configuration as composable pieces. They are
|
||||
intended to deliver settings, TypoScript, TSconfig and reference enabled content
|
||||
blocks for the scope of a site.
|
||||
|
||||
Extensions can provide multiple sets in order to ship presets for different
|
||||
sites or subsets (think of frameworks) where selected features are exposed
|
||||
as a subset (example: `typo3/seo-sitemap`).
|
||||
|
||||
A set is defined in an extension's subfolder in :file:`Configuration/Sets/`, for
|
||||
example :file:`EXT:my_extension/Configuration/Sets/MySet/config.yaml`.
|
||||
|
||||
The folder name in :file:`Configuration/Sets/` is arbitrary, significant
|
||||
is the `name` defined in :file:`config.yaml`. The `name` uses a `vendor/name`
|
||||
scheme by convention, and *should* use the same vendor as the containing
|
||||
extension. It may differ if needed for compatibility reasons (e.g. when sets are
|
||||
moved to other extensions). If an extension provides exactly one set that should
|
||||
have the same `name` as defined in :file:`composer.json`.
|
||||
|
||||
The :file:`config.yaml` for a set that is composed of three subsets looks as
|
||||
follows:
|
||||
|
||||
.. code-block:: yaml
|
||||
:caption: EXT:my_extension/Configuration/Sets/MySet/config.yaml
|
||||
|
||||
name: my-vendor/my-set
|
||||
label: My Set
|
||||
|
||||
# Load TypoScript, TSconfig and settings from dependencies
|
||||
dependencies:
|
||||
- some-namespace/slider
|
||||
- other-namespace/fancy-carousel
|
||||
|
||||
|
||||
Sets are applied to sites via `dependencies` array in site configuration:
|
||||
|
||||
.. code-block:: yaml
|
||||
:caption: config/sites/my-site/config.yaml
|
||||
|
||||
base: 'http://example.com/'
|
||||
rootPageId: 1
|
||||
dependencies:
|
||||
- my-vendor/my-set
|
||||
|
||||
Site sets can also be edited via the backend module
|
||||
:guilabel:`Site Management > Sites`.
|
||||
|
||||
A list of available site sets can be retrieved with the console command
|
||||
:bash:`bin/typo3 site:sets:list`.
|
||||
|
||||
Settings definitions
|
||||
--------------------
|
||||
|
||||
Sets can define settings definitions which contain more metadata than just a
|
||||
value: They contain UI-relevant options like `label`, `description`, `category`
|
||||
and `tags` and types like `int`, `bool`, `string`, `stringlist`, `text` or
|
||||
`color`. These definitions are placed in :file:`settings.definitions.yaml`
|
||||
next to the site set file :file:`config.yaml`.
|
||||
|
||||
The description can make use of markdown syntax for richtext formatting.
|
||||
|
||||
.. code-block:: yaml
|
||||
:caption: EXT:my_extension/Configuration/Sets/MySet/settings.definitions.yaml
|
||||
|
||||
settings:
|
||||
foo.bar.baz:
|
||||
label: 'My example baz setting'
|
||||
description: 'Configure `baz` to be used in `bar`.'
|
||||
type: int
|
||||
default: 5
|
||||
|
||||
|
||||
Settings for subsets
|
||||
--------------------
|
||||
|
||||
Settings for subsets (e.g. to configure settings in declared dependencies)
|
||||
can be shipped via :file:`settings.yaml` when placed next to the set file
|
||||
:file:`config.yaml`.
|
||||
|
||||
Note that default values for settings provided by the set do not need to be
|
||||
defined here, as defaults are to be provided within
|
||||
:file:`settings.definitions.yaml`.
|
||||
|
||||
Here is an example where the setting `styles.content.defaultHeaderType` — as
|
||||
provided by `typo3/fluid-styled-content` — is configured via
|
||||
:file:`settings.yaml`:
|
||||
|
||||
.. code-block:: yaml
|
||||
:caption: EXT:my_extension/Configuration/Sets/MySet/settings.yaml
|
||||
|
||||
styles.content.defaultHeaderType: 1
|
||||
|
||||
|
||||
This setting will be exposed as site setting whenever the set
|
||||
`my-vendor/my-set` is applied to a site configuration.
|
||||
|
||||
|
||||
Hidden sets
|
||||
-----------
|
||||
|
||||
Sets may be hidden from the backend set selection in
|
||||
:guilabel:`Site Management > Sites` and the console command
|
||||
:bash:`bin/typo3 site:sets:list` by adding a `hidden` flag to the
|
||||
:file:`config.yaml` definition:
|
||||
|
||||
|
||||
.. code-block:: yaml
|
||||
:caption: EXT:my_extension/Configuration/Sets/MyHelperSet/config.yaml
|
||||
|
||||
name: my-vendor/my-helperset
|
||||
label: A helper Set that is not visible inside the GUI
|
||||
hidden: true
|
||||
|
||||
|
||||
Integrators may choose to hide existing sets from the list of available
|
||||
sets for backend users via User TSConfig, in case only a curated list of sets
|
||||
shall be selectable:
|
||||
|
||||
.. code-block:: typoscript
|
||||
:caption: EXT:my_extension/Configuration/user.tsconfig
|
||||
|
||||
options.sites.hideSets := addToList(typo3/fluid-styled-content)
|
||||
|
||||
|
||||
The :guilabel:`Site Management > Sites` GUI will not show hidden sets,
|
||||
but makes one exception if a hidden set has already been applied to a site
|
||||
(e.g. by manual modification of :file:`config.yaml`). In this case a set
|
||||
marked as hidden will be shown in the list of currently activated sets (that means
|
||||
it can be introspected and removed via backend UI).
|
||||
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
Sites can be composed of sets where relevant configuration, templates, assets
|
||||
and setting definitions are combined in a central place and applied to sites as
|
||||
one logical volume.
|
||||
|
||||
Sets have dependency management and therefore allow sharing code between
|
||||
multiple TYPO3 sites and extensions in a flexible way.
|
||||
|
||||
|
||||
.. index:: Backend, Frontend, PHP-API, YAML, ext:core
|
||||
@@ -0,0 +1,115 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _feature-103439-1712321631:
|
||||
|
||||
=========================================================
|
||||
Feature: #103439 - TypoScript provider for sites and sets
|
||||
=========================================================
|
||||
|
||||
See :issue:`103439`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
TYPO3 sites have been enhanced to be able to operate as TypoScript template
|
||||
provider. They act similar to :sql:`sys_template` records with "clear" and "root"
|
||||
flags set. By design a site TypoScript provider always defines a new scope
|
||||
("root" flag) and does not inherit from parent sites (for example, sites up in the
|
||||
root line). That means it behaves as if the "clear" flag is set in a `sys_template`
|
||||
record. This behavior is not configurable by design, as TypoScript code sharing
|
||||
is intended to be implemented via sharable sets (:ref:`feature-103437-1712062105`).
|
||||
|
||||
Note that :sql:`sys_template` records will still be loaded, but they are optional
|
||||
now, and applied after TypoScript provided by the site.
|
||||
|
||||
TypoScript dependencies can be included via set dependencies. This mechanism is
|
||||
much more effective than the previous static_file_include's or manual :typoscript:`@import`
|
||||
statements (they are still fine for local includes, but should be avoided for
|
||||
cross-set/extensions dependencies), as sets are automatically ordered and
|
||||
deduplicated.
|
||||
|
||||
|
||||
Site TypoScript
|
||||
---------------
|
||||
|
||||
The files :file:`setup.typoscript` and :file:`constants.typoscript` (placed next
|
||||
to the site's :file:`config.yaml` file) will be loaded as TypoScript setup and
|
||||
constants, if available.
|
||||
|
||||
Site dependencies (sets) will be loaded first, that means setup and constants
|
||||
can be overridden on a per-site basis.
|
||||
|
||||
|
||||
Set TypoScript
|
||||
--------------
|
||||
|
||||
Set-defined TypoScript can be shipped within a set. The files
|
||||
:file:`setup.typoscript` and :file:`constants.typoscript` (placed next to the
|
||||
:file:`config.yaml` file) will be loaded, if available.
|
||||
They are inserted (similar to `static_file_include`) into the TypoScript chain
|
||||
of the site TypoScript that will be defined by a site that is using sets.
|
||||
|
||||
Set constants will always be overruled by site settings. Since site settings
|
||||
always provide a default value, a constant will always be overruled by a defined
|
||||
setting. This can be used to provide backward compatibility with TYPO3 v12
|
||||
in extensions, where constants shall be used in v12, while v13 will always
|
||||
prefer defined site settings.
|
||||
|
||||
In contrast to `static_file_include`, dependencies are to be included via
|
||||
sets. Dependencies are included recursively. This mechanism supersedes the
|
||||
previous include via `static_file_include` or manual :typoscript:`@import` statements as
|
||||
sets are automatically ordered and deduplicated. That means TypoScript will not
|
||||
be loaded multiple times, if a shared dependency is required by multiple sets.
|
||||
|
||||
Note that :typoscript:`@import` statements are still fine to be used for local
|
||||
includes, but should be avoided for cross-set/extensions dependencies.
|
||||
|
||||
|
||||
.. _global_typoscript_in_site_sets:
|
||||
Global TypoScript
|
||||
-----------------
|
||||
|
||||
Site sets introduce reliable dependencies in order to replace the need for
|
||||
globally provided TypoScript. It is therefore generally discouraged to use
|
||||
global TypoScript in an environment using TypoScript provided by site sets.
|
||||
TypoScript should only be provided globally if absolutely needed.
|
||||
|
||||
It has therefore been decided that :file:`ext_typoscript_setup.typoscript` and
|
||||
:file:`ext_typoscript_constants.typoscript` are not autoloaded in site set
|
||||
provided TypoScript.
|
||||
|
||||
These files can still be used to provide global TypoScript for traditional
|
||||
:sql:`sys_template` setups. Existing setups do not need to be adapted and
|
||||
extensions can still ship globally defined TypoScript via
|
||||
:file:`ext_typoscript_setup.typoscript` for these cases, but should provide
|
||||
explicitly dependable sets for newer site set setups.
|
||||
|
||||
If global TypoScript is still needed and is unavoidable, it can be provided
|
||||
for site sets and :sql:`sys_template` setups in :file:`ext_localconf.php` via:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addTypoScriptSetup(
|
||||
'module.tx_foo.settings.example = 1'
|
||||
);
|
||||
|
||||
|
||||
There are some cases where globally defined TypoScript configurations are needed
|
||||
because backend modules rely on their availability. One such case is the form
|
||||
framework backend module which uses
|
||||
:typoscript:`module.tx_form.settings.yamlConfigurations` as a registry for
|
||||
extension-provided form configuration. Global form configuration can be loaded
|
||||
as described in
|
||||
:ref:`YAML registration <typo3/cms-form:concepts-configuration-yamlregistration>`
|
||||
Please make sure to only load backend-related form TypoScript globally and to
|
||||
provide TypoScript related to frontend rendering via site sets.
|
||||
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
Sites and sets can ship TypoScript without the need for :sql:`sys_template`
|
||||
records in database, and dependencies can be expressed via sets, allowing for
|
||||
automatic ordering and deduplication.
|
||||
|
||||
.. index:: Backend, Frontend, PHP-API, TypoScript, YAML, ext:core
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _feature-103441-1710969809:
|
||||
|
||||
========================================================================================
|
||||
Feature: #103441 - Request ID as public visible error reference in error handlers output
|
||||
========================================================================================
|
||||
|
||||
See :issue:`103441`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
The :php:`ProductionExceptionHandler` in EXT:core outputs error details, but not
|
||||
for everyone. As a normal visitor you don't see any traceable error information.
|
||||
|
||||
The :php:`ProductionExceptionHandler` in EXT:frontend outputs "Oops, an error
|
||||
occurred!" followed by a timestamp and a hash. This is part of log messages.
|
||||
|
||||
Whenever an error/exception is logged, the log message contains the request ID.
|
||||
|
||||
With this the request ID is also shown in web output of error/exception handlers
|
||||
as public visible error reference.
|
||||
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
Everyone sees a request id as traceable error information.
|
||||
|
||||
.. index:: Frontend, ext:core
|
||||
@@ -0,0 +1,168 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _feature-103504-1712041725:
|
||||
|
||||
=============================================
|
||||
Feature: #103504 - New ContentObject PAGEVIEW
|
||||
=============================================
|
||||
|
||||
See :issue:`103504`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
A new content object for TypoScript :typoscript:`PAGEVIEW` has been added.
|
||||
|
||||
This cObject is mainly intended for rendering a full page in the TYPO3 frontend
|
||||
with fewer configuration options over the generic :typoscript:`FLUIDTEMPLATE`
|
||||
cObject.
|
||||
|
||||
A basic usage of the :typoscript:`PAGEVIEW` cObject is as follows:
|
||||
|
||||
.. code-block:: typoscript
|
||||
|
||||
page = PAGE
|
||||
page.10 = PAGEVIEW
|
||||
page.10.paths.100 = EXT:mysite/Resources/Private/Templates/
|
||||
|
||||
:typoscript:`PAGEVIEW` wires certain parts automatically:
|
||||
|
||||
1. The name of the used page layout (backend layout) is resolved automatically.
|
||||
|
||||
If a page has a layout named "with_sidebar", the template file is then resolved
|
||||
to :file:`EXT:mysite/Resources/Private/Templates/Pages/With_sidebar.html`.
|
||||
|
||||
2. Fluid features for layouts and partials are wired automatically. They
|
||||
can be placed into :file:`EXT:mysite/Resources/Private/Templates/Layouts/`
|
||||
and :file:`EXT:mysite/Resources/Private/Templates/Partials/` with above example.
|
||||
|
||||
3. Default variables are available in the Fluid template:
|
||||
|
||||
- :typoscript:`settings` - contains all TypoScript settings (= constants)
|
||||
- :typoscript:`site` - the current :php:`Site` object
|
||||
- :typoscript:`language` - the current :php:`SiteLanguage` object
|
||||
- :typoscript:`page` - the current page record as object
|
||||
|
||||
.. note::
|
||||
The :php:`PageInformation` object contains all relevant information about
|
||||
the current page. Those are, for example, the corresponding page record, the
|
||||
root line, and many more. Worth mentioning is also the :php:`PageLayout`
|
||||
object, which provides all the information about the selected backend layout.
|
||||
This includes the identifier, the title, the available content areas
|
||||
with their corresponding name and `colPos`. Additionally, the full (raw)
|
||||
backend layout configuration is available.
|
||||
|
||||
There is no special Extbase resolving done for the templates.
|
||||
|
||||
Migration
|
||||
---------
|
||||
|
||||
Before
|
||||
~~~~~~
|
||||
|
||||
.. code-block:: typoscript
|
||||
|
||||
page = PAGE
|
||||
page {
|
||||
10 = FLUIDTEMPLATE
|
||||
10 {
|
||||
templateName = TEXT
|
||||
templateName {
|
||||
stdWrap {
|
||||
cObject = TEXT
|
||||
cObject {
|
||||
data = levelfield:-2, backend_layout_next_level, slide
|
||||
override {
|
||||
field = backend_layout
|
||||
}
|
||||
split {
|
||||
token = pagets__
|
||||
1 {
|
||||
current = 1
|
||||
wrap = |
|
||||
}
|
||||
}
|
||||
}
|
||||
ifEmpty = Standard
|
||||
}
|
||||
}
|
||||
|
||||
templateRootPaths {
|
||||
100 = {$plugin.tx_mysite.templateRootPaths}
|
||||
}
|
||||
|
||||
partialRootPaths {
|
||||
100 = {$plugin.tx_mysite.partialRootPaths}
|
||||
}
|
||||
|
||||
layoutRootPaths {
|
||||
100 = {$plugin.tx_mysite.layoutRootPaths}
|
||||
}
|
||||
|
||||
variables {
|
||||
pageUid = TEXT
|
||||
pageUid.data = page:uid
|
||||
|
||||
pageTitle = TEXT
|
||||
pageTitle.data = page:title
|
||||
|
||||
pageSubtitle = TEXT
|
||||
pageSubtitle.data = page:subtitle
|
||||
|
||||
parentPageTitle = TEXT
|
||||
parentPageTitle.data = levelfield:-1:title
|
||||
}
|
||||
|
||||
dataProcessing {
|
||||
10 = menu
|
||||
10.as = mainMenu
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
After
|
||||
~~~~~
|
||||
|
||||
.. code-block:: typoscript
|
||||
|
||||
page = PAGE
|
||||
page {
|
||||
10 = PAGEVIEW
|
||||
10 {
|
||||
paths {
|
||||
100 = {$plugin.tx_mysite.templatePaths}
|
||||
}
|
||||
variables {
|
||||
parentPageTitle = TEXT
|
||||
parentPageTitle.data = levelfield:-1:title
|
||||
}
|
||||
dataProcessing {
|
||||
10 = menu
|
||||
10.as = mainMenu
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
In Fluid, the pageUid is available as :html:`{page.uid}` and pageTitle
|
||||
as :html:`{page.title}`. The page layout identifier can be accessed
|
||||
using :html:`{page.pageLayout.identifier}`.
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
Creating new page templates based on Fluid follows conventions in order to
|
||||
reduce the amount of TypoScript needed to render a page in the TYPO3 frontend.
|
||||
|
||||
Sane defaults are applied, variables and settings are available at any time.
|
||||
|
||||
.. note::
|
||||
|
||||
This cObject is marked as experimental until TYPO3 v13 LTS as some
|
||||
functionality will be added.
|
||||
|
||||
.. note::
|
||||
|
||||
Default variable names cannot be set or overridden and trying to do
|
||||
will throw an exception.
|
||||
|
||||
.. index:: TypoScript, ext:frontend
|
||||
@@ -0,0 +1,32 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _feature-103522-1712323334:
|
||||
|
||||
============================================================
|
||||
Feature: #103522 - Page TSconfig provider for sites and sets
|
||||
============================================================
|
||||
|
||||
See :issue:`103522`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
TYPO3 sites have been enhanced to be able to provide page TSconfig on a per-site
|
||||
basis.
|
||||
|
||||
Site page TSconfig is loaded from :file:`page.tsconfig`, if placed next to the
|
||||
site configuration file :file:`config.yaml` and is scoped to pages within that
|
||||
site.
|
||||
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
Sites and sets can ship page TSconfig without the need for database entries or
|
||||
by polluting global scope when registering page TSconfig globally via
|
||||
:file:`ext_localconf.php` or :file:`Configuration/page.tsconfig`.
|
||||
Dependencies can be expressed via sets, allowing for automatic ordering and
|
||||
deduplication.
|
||||
|
||||
|
||||
.. index:: Backend, Frontend, PHP-API, TypoScript, YAML, ext:core
|
||||
@@ -0,0 +1,25 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _feature-103529-1712154338:
|
||||
|
||||
========================================================
|
||||
Feature: #103529 - Introduce hotkey for "Save and Close"
|
||||
========================================================
|
||||
|
||||
See :issue:`103529`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
A new hotkey is introduced in the FormEngine scope that lets editors invoke
|
||||
"Save and Close" via :kbd:`Ctrl`/:kbd:`Cmd` + :kbd:`Shift` + :kbd:`S`.
|
||||
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
Next to the existing :kbd:`Ctrl`/:kbd:`Cmd` + :kbd:`s` hotkey (Save), the
|
||||
hotkey :kbd:`Ctrl`/:kbd:`Cmd` + :kbd:`Shift` + :kbd:`S` (Save and Close)
|
||||
became available.
|
||||
|
||||
.. index:: Backend, JavaScript, ext:backend
|
||||
@@ -0,0 +1,77 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _feature-103560-1712562637:
|
||||
|
||||
==========================================================
|
||||
Feature: #103560 - Update Fluid Standalone to version 2.11
|
||||
==========================================================
|
||||
|
||||
See :issue:`103560`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
Fluid Standalone has been updated to version 2.11. This version includes new
|
||||
ViewHelpers that cover common tasks in Fluid templates. More ViewHelpers will
|
||||
be added with future minor releases.
|
||||
|
||||
A full documentation of the new ViewHelper's arguments is available in the
|
||||
ViewHelper reference <https://docs.typo3.org/other/typo3/view-helper-reference/main/en-us/>.
|
||||
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
The following ViewHelpers are now included and can be used in all Fluid
|
||||
templates:
|
||||
|
||||
:html:`<f:split>` ViewHelper:
|
||||
-----------------------------
|
||||
|
||||
The :php:`SplitViewHelper` splits a string by the specified separator, which
|
||||
results in an array.
|
||||
|
||||
.. code-block:: html
|
||||
|
||||
<f:split value="1,5,8" separator="," /> <!-- Output: {0: '1', 1: '5', 2: '8'} -->
|
||||
<f:split separator="-">1-5-8</f:split> <!-- Output: {0: '1', 1: '5', 2: '8'} -->
|
||||
<f:split value="1,5,8" separator="," limit="2" /> <!-- Output: {0: '1', 1: '5,8'} -->
|
||||
|
||||
|
||||
:html:`<f:join>` ViewHelper:
|
||||
----------------------------
|
||||
|
||||
The :php:`JoinViewHelper` combines elements from an array into a single string.
|
||||
|
||||
.. code-block:: html
|
||||
|
||||
<f:join value="{0: '1', 1: '2', 2: '3'}" /> <!-- Output: 123 -->
|
||||
<f:join value="{0: '1', 1: '2', 2: '3'}" separator=", " /> <!-- Output: 1, 2, 3 -->
|
||||
<f:join value="{0: '1', 1: '2', 2: '3'}" separator=", " separatorLast=" and " /> <!-- Output: 1, 2 and 3 -->
|
||||
|
||||
|
||||
:html:`<f:replace>` ViewHelper:
|
||||
-------------------------------
|
||||
|
||||
The :php:`ReplaceViewHelper` replaces one or multiple strings with other strings.
|
||||
|
||||
.. code-block:: html
|
||||
|
||||
<f:replace value="Hello World" search="World" replace="Fluid" /> <!-- Output: Hello Fluid -->
|
||||
<f:replace value="Hello World" search="{0: 'World', 1: 'Hello'}" replace="{0: 'Fluid', 1: 'Hi'}" /> <!-- Output: Hi Fluid -->
|
||||
<f:replace value="Hello World" replace="{'World': 'Fluid', 'Hello': 'Hi'}" /> <!-- Output: Hi Fluid -->
|
||||
|
||||
|
||||
:html:`<f:first>` and :html:`<f:last>` ViewHelpers:
|
||||
---------------------------------------------------
|
||||
|
||||
The :php:`FirstViewHelper` and :php:`LastViewHelper` return the first or last
|
||||
item of a specified array, respectively.
|
||||
|
||||
.. code-block:: html
|
||||
|
||||
<f:first value="{0: 'first', 1: 'second', 2: 'third'}" /> <!-- Outputs "first" -->
|
||||
<f:last value="{0: 'first', 1: 'second', 2: 'third'}" /> <!-- Outputs "third" -->
|
||||
|
||||
|
||||
.. index:: Fluid, Frontend, ext:fluid
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _feature-103563-1712569921:
|
||||
|
||||
=========================================================================
|
||||
Feature: #103563 - Add saving-related hotkeys to scheduler backend module
|
||||
=========================================================================
|
||||
|
||||
See :issue:`103563`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
Similar to editing regular content elements, it is now possible to save
|
||||
scheduler tasks being edited via keyboard shortcuts as well.
|
||||
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
It is possible to invoke the :kbd:`Ctrl`/:kbd:`Cmd` + :kbd:`s` hotkey to save a
|
||||
scheduler task, altogether with the hotkey :kbd:`Ctrl`/:kbd:`Cmd` + :kbd:`Shift` + :kbd:`S`
|
||||
to save and close a scheduler task.
|
||||
|
||||
.. index:: Backend, JavaScript, ext:scheduler
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _feature-103578-1712678936:
|
||||
|
||||
=========================================================================================
|
||||
Feature: #103578 - Add database default value support for TEXT, BLOB and JSON field types
|
||||
=========================================================================================
|
||||
|
||||
See :issue:`103578`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
Database default values for :sql:`TEXT`, :sql:`JSON` and :sql:`BLOB` fields
|
||||
could not be used in a cross-database, vendor-compatible manner, for
|
||||
example in :file:`ext_tables.sql`, or as default database scheme generation
|
||||
for TCA-managed tables and types.
|
||||
|
||||
Direct default values are still unsupported, but since
|
||||
`MySQL 8.0.13+ <https://dev.mysql.com/doc/relnotes/mysql/8.0/en/news-8-0-13.html#mysqld-8-0-13-data-types>`__
|
||||
this is possible by using default value expressions, albeit in a slightly
|
||||
differing syntax.
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
.. code-block:: sql
|
||||
:caption: EXT:my_extension/ext_tables.sql
|
||||
|
||||
CREATE TABLE `tx_myextension_domain_model_entity` (
|
||||
`some_field` TEXT NOT NULL DEFAULT 'default-text',
|
||||
`json_field` JSON NOT NULL DEFAULT '{}'
|
||||
);
|
||||
|
||||
.. code-block:: php
|
||||
:caption: Insert a new record using the defined default values
|
||||
|
||||
$connection = GeneralUtility::makeInstance(ConnectionPool::class)
|
||||
->getConnectionByName(ConnectionPool::DEFAULT_NAME);
|
||||
$connection->insert(
|
||||
'tx_myextension_domain_model_entity',
|
||||
[
|
||||
'pid' => 123,
|
||||
]
|
||||
);
|
||||
|
||||
Advanced example with value quoting
|
||||
-----------------------------------
|
||||
|
||||
.. code-block:: sql
|
||||
:caption: EXT:my_extension/ext_tables.sql
|
||||
|
||||
CREATE TABLE a_textfield_test_table
|
||||
(
|
||||
# JSON object default value containing single quote in json field
|
||||
field1 JSON NOT NULL DEFAULT '{"key1": "value1", "key2": 123, "key3": "value with a '' single quote"}',
|
||||
|
||||
# JSON object default value containing double-quote in json field
|
||||
field2 JSON NOT NULL DEFAULT '{"key1": "value1", "key2": 123, "key3": "value with a \" double quote"}',
|
||||
);
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
Database :sql:`INSERT` queries that do not provide values for fields with
|
||||
defined default values, and that do not use TCA-powered TYPO3
|
||||
APIs, can now be used, and will receive default values defined at databaselevel.
|
||||
This also accounts for dedicated applications operating directly
|
||||
on the database table.
|
||||
|
||||
.. note::
|
||||
|
||||
TCA-unaware API will not consider different TCA or FormEngine default
|
||||
value overrides and settings. So it's good to provide the basic default
|
||||
both in TCA and at database level, if added manually.
|
||||
|
||||
.. index:: Database, ext:core
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _feature-103671-1713511090:
|
||||
|
||||
============================================================================
|
||||
Feature: #103671 - Provide null coalescing operator for TypoScript constants
|
||||
============================================================================
|
||||
|
||||
See :issue:`103671`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
TypoScript constants expressions have been extended to support a null coalescing
|
||||
operator (`??`) as a way for providing a migration path from a legacy constant
|
||||
name to a newer name, while providing full backwards compatibility for the
|
||||
legacy constant name, if still defined.
|
||||
|
||||
Example that evaluates to `$config.oldThing` if set, otherwise the newer setting
|
||||
`$myext.thing` would be used:
|
||||
|
||||
.. code-block:: typoscript
|
||||
|
||||
plugin.tx_myext.settings.example = {$config.oldThing ?? $myext.thing}
|
||||
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
Since :ref:`feature-103439-1712321631` it is suggested to define site settings
|
||||
via :file:`settings.definitions.yaml` in site sets instead of TypoScript
|
||||
constants. Migration of TYPO3 Core extensions revealed that such migration is a
|
||||
good time to revisit constant names and the null coalescing operator helps to
|
||||
switch to a new setting identifier without breaking backwards-compatibility with
|
||||
previous constant names.
|
||||
|
||||
|
||||
.. index:: TypoScript, ext:core
|
||||
@@ -0,0 +1,52 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _feature-93942-1709722341:
|
||||
|
||||
==========================================
|
||||
Feature: #93942 - Crop SVG images natively
|
||||
==========================================
|
||||
|
||||
See :issue:`93942`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
Cropping SVG images via backend image editing or specific Fluid ViewHelper via
|
||||
:html:`<f:image>` or :html:`<f:uri.image>` (via :html:`crop` attribute) now
|
||||
outputs native SVG files by default - which are processed but again stored
|
||||
as SVG, instead of rasterized PNG/JPG images like before.
|
||||
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
Editors and integrators can now crop SVG assets without an impact to their
|
||||
output quality.
|
||||
|
||||
Forced rasterization of cropped SVG assets can still be performed by setting the
|
||||
:html:`fileExtension="png"` Fluid ViewHelper attribute or the TypoScript
|
||||
:typoscript:`file.ext = png` property.
|
||||
|
||||
:html:`<f:image>` ViewHelper example:
|
||||
-------------------------------------
|
||||
|
||||
.. code-block:: html
|
||||
|
||||
<f:image image="{image}" fileExtension="png" />
|
||||
|
||||
This keeps forcing images to be generated as PNG image.
|
||||
|
||||
`file.ext = png` TypoScript example:
|
||||
------------------------------------
|
||||
|
||||
.. code-block:: typoscript
|
||||
|
||||
page.10 = IMAGE
|
||||
page.10.file = 2:/myfile.svg
|
||||
page.10.file.crop = 20,20,500,500
|
||||
page.10.file.ext = png
|
||||
|
||||
If no special hard-coded option for the file extension is set, SVGs are now
|
||||
processed and stored as SVGs again.
|
||||
|
||||
.. index:: Backend, FAL, Fluid, Frontend, TypoScript, ext:fluid
|
||||
@@ -0,0 +1,21 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _important-103165-1708508519:
|
||||
|
||||
==========================================================
|
||||
Important: #103165 - Database table cache_treelist removed
|
||||
==========================================================
|
||||
|
||||
See :issue:`103165`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
Database table :sql:`cache_treelist` has been removed, the database
|
||||
analyzer will suggest to drop it if it exists.
|
||||
|
||||
That cache table was unused since a TYPO3 v12 patch level release, v13
|
||||
removed leftover handling throughout the Core and removed the table itself.
|
||||
|
||||
|
||||
.. index:: Database, ext:frontend
|
||||
@@ -0,0 +1,52 @@
|
||||
:template: changelogOverview.html
|
||||
.. include:: /Includes.rst.txt
|
||||
.. _changelog-13-1:
|
||||
|
||||
=============
|
||||
13.1 Changes
|
||||
=============
|
||||
|
||||
.. contents:: Table of contents
|
||||
:local:
|
||||
:depth: 1
|
||||
|
||||
Breaking Changes
|
||||
================
|
||||
|
||||
None since TYPO3 v13.0 release.
|
||||
|
||||
.. attention::
|
||||
|
||||
After TYPO3 v13.0, only new functionality with a solid migration path
|
||||
can be added on top, with aiming for as little as possible breaking changes
|
||||
after the initial v13.0 release on the way to LTS.
|
||||
|
||||
Features
|
||||
========
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:titlesonly:
|
||||
:glob:
|
||||
|
||||
Feature-*
|
||||
|
||||
Deprecation
|
||||
===========
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:titlesonly:
|
||||
:glob:
|
||||
|
||||
Deprecation-*
|
||||
|
||||
Important
|
||||
=========
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:titlesonly:
|
||||
:glob:
|
||||
|
||||
Important-*
|
||||
Reference in New Issue
Block a user