TYPO3 v15 dev-main snapshot ()

This commit is contained in:
2026-08-10 22:31:09 +02:00
commit af8cc155b5
6818 changed files with 642608 additions and 0 deletions
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
+52
View File
@@ -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-*