TYPO3 v15 dev-main snapshot ()
This commit is contained in:
@@ -0,0 +1,166 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _feature-97816-1656350667:
|
||||
|
||||
================================================
|
||||
Feature: #97816 - TypoScript syntax improvements
|
||||
================================================
|
||||
|
||||
See :issue:`97816`
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
TYPO3 v12 comes with a new TypoScript syntax parser that is more performant,
|
||||
more robust and allows better tooling in the Backend.
|
||||
|
||||
The new parser is more forgiving in many places, this documentation lists
|
||||
the new capabilities.
|
||||
|
||||
Also see :ref:`breaking-97816-1656350406`
|
||||
for an overview of breaking syntax changes.
|
||||
|
||||
Impact
|
||||
======
|
||||
|
||||
Improved comment parsing
|
||||
------------------------
|
||||
|
||||
TypoScript comment detection had various nasty quirks with the old parser. The confusing
|
||||
behavior did lead to many headaches in the past and not sticking to the weird parser
|
||||
restrictions in comment parsing could easily lead to unexpected results, often ignoring
|
||||
bigger sections of the subsequent TypoScript lines.
|
||||
|
||||
This has been relaxed heavily: Comment detection should almost always act as developers
|
||||
and integrators would expect from a language. Especially the former obligation to place
|
||||
a closing multiline comment (:typoscript:`*/`) on a single line to close the comment
|
||||
section has been removed.
|
||||
|
||||
A couple of examples to clarify:
|
||||
|
||||
.. code-block:: typoscript
|
||||
|
||||
foo # This is a comment to an invalid line
|
||||
|
||||
foo < bar // This is a comment
|
||||
foo < bar /* This is a valid comment, too */
|
||||
|
||||
foo > # Another valid comment
|
||||
|
||||
foo := addToList(1) # Yes, a comment
|
||||
|
||||
[foo = bar] # Much comment. Much wow.
|
||||
|
||||
<INCLUDE_TYPOSCRIPT: source="..."> /* A comment */
|
||||
|
||||
foo (
|
||||
# This is NOT a comment but part of the value assignment!
|
||||
bar = barValue
|
||||
) # This is a comment
|
||||
|
||||
foo = bar // This is NOT a comment but part of the value assignment!
|
||||
|
||||
@import in conditions
|
||||
---------------------
|
||||
|
||||
Placing an :typoscript:`@import` keyword within a condition is now supported,
|
||||
the example below works. Note this obsoletes the clumsy :typoscript:`<INCLUDE_TYPOSCRIPT:`
|
||||
syntax, and integrators are encouraged to fully switch to :typoscript:`@import`.
|
||||
|
||||
.. code-block:: typoscript
|
||||
|
||||
[frontend.user.isLoggedIn]
|
||||
@import 'EXT:my_extension/Configuration/TypoScript/LoggedInUser.typoscript'
|
||||
[ELSE]
|
||||
@import 'EXT:my_extension/Configuration/TypoScript/NotLoggedInUser.typoscript'
|
||||
[END]
|
||||
|
||||
Scope restriction to file / snipped level
|
||||
-----------------------------------------
|
||||
|
||||
The old TypoScript parser merged the entire TypoScript for a page into one big
|
||||
chunk of text. The new parser does not do that anymore, but parses each included
|
||||
snippet one-by-one. This automatically means state no longer leaks to subsequent
|
||||
snippets. Missing closing brackets :typoscript:`}` in one file do not destroy block
|
||||
integrity of a following include anymore. Same for conditions: A missing closing
|
||||
condition block (:typoscript:`[END]` or :typoscript:`[GLOBALS]`) no longer leaks
|
||||
to another file - a conditions ends at the end of a file or snippet.
|
||||
|
||||
Nesting conditions is partially supported
|
||||
-----------------------------------------
|
||||
|
||||
Nesting conditions is partially possible with the new TypoScript parser, **if** the
|
||||
conditions are in different files. As example, let's first sort what happens when
|
||||
two conditions follow directly in one snippet:
|
||||
|
||||
.. code-block:: typoscript
|
||||
|
||||
[frontend.user.isLoggedIn]
|
||||
@import 'EXT:my_extension/Configuration/TypoScript/LoggedInUser.typoscript'
|
||||
[applicationContext == "Development"]
|
||||
@import 'EXT:my_extension/Configuration/TypoScript/Development.typoscript'
|
||||
[END]
|
||||
|
||||
This always worked and did not change with the new parser: Opening a new condition
|
||||
automatically closes the preceding one. In the example above, both conditions are
|
||||
standalone: :file:`Development.typoscript` is included no matter if a user is
|
||||
logged in or not.
|
||||
|
||||
But, and this in new, nesting conditions within different files is possible now.
|
||||
In the example below, file :file:`LoggedInUserDevelopment.typoscript` is only
|
||||
included if a user is logged in *and* the application is in development context.
|
||||
|
||||
.. code-block:: typoscript
|
||||
|
||||
[frontend.user.isLoggedIn]
|
||||
@import 'EXT:my_extension/Configuration/TypoScript/LoggedInUser.typoscript'
|
||||
[END]
|
||||
|
||||
# File LoggedInUser.typoscript:
|
||||
[applicationContext == "Development"]
|
||||
@import 'EXT:my_extension/Configuration/TypoScript/LoggedInUserDevelopment.typoscript'
|
||||
[END]
|
||||
|
||||
Irrelevant order of <INCLUDE_TYPOSCRIPT: tokens
|
||||
-----------------------------------------------
|
||||
|
||||
The :typoscript:`<INCLUDE_TYPOSCRIPT:` keywords has the three properties
|
||||
:typoscript:`source`, :typoscript:`condition` and :typoscript:`extensions`. They had to
|
||||
be in a specific order with the old parser, but can be placed in arbitrary order now.
|
||||
|
||||
Further clarifications
|
||||
----------------------
|
||||
|
||||
* The "reference" :typoscript:`=<` operator is not a direct language construct. The parser
|
||||
understands the syntax, but does not resolve it. Allowed :typoscript:`=<` operator are very
|
||||
limited: In general, it can *only* be used for Frontend Content Objects, typically like this:
|
||||
:typoscript:`tt_content.bullets =< lib.contentElement`. Another usage is referencing :typoscript:`lib.parseFunc`.
|
||||
Using the :typoscript:`=<` operator in these cases can have a performance advantage since it
|
||||
avoids an expensive copy operation that is done lazily if really needed. There are two methods
|
||||
that resolve this operator, namely :php:`ContentObjectRenderer->cObjGetSingle()` and
|
||||
:php:`ContentObjectRenderer->mergeTSRef()`.
|
||||
This also means: The :typoscript:`=<` operator is *not supported* in TypoScript constants,
|
||||
is only supported for specific elements in TypoScript setup, and is *not supported* in TSconfig.
|
||||
Also note the reference operator does not support "relative" copies like the "copy" operator supports
|
||||
with :typoscript:`20 < .10` and similar.
|
||||
|
||||
* The new parser has a minor change in behavior with the "copy" :typoscript:`<` operator on top-level.
|
||||
This shouldn't have huge impact in real life usage and is documented for completeness. Consider this
|
||||
example:
|
||||
|
||||
.. code-block:: typoscript
|
||||
|
||||
lib.viewConfig {
|
||||
baz = bazValue
|
||||
}
|
||||
|
||||
first = FLUIDTEMPLATE
|
||||
first < lib.viewConfig
|
||||
|
||||
The situation is there that :typoscript:`lib.viewConfig` has no assigned value (just children). The
|
||||
target :typoscript:`first` however has value :typoscript:`FLUIDTEMPLATE`. The old TypoScript parser
|
||||
usually keeps the "target" value in such cases, but only if the TypoScript object is not on top level
|
||||
(:typoscript:`first` in contrast to :typoscript:`first.10` or similar). In the example above, value
|
||||
:typoscript:`FLUIDTEMPLATE` would vanish with the old parser, but is now kept with the new parser.
|
||||
|
||||
.. index:: Backend, Frontend, TSConfig, TypoScript, ext:core
|
||||
Reference in New Issue
Block a user