Feature: #85829 - Implement symfony expression language for TypoScript conditions

See Issue #85829

Description

The symfony expression language has been implemented for TypoScript conditions in both frontend and backend. The existing conditions are available as variables and/or functions. Please check the following tables in detail.

General Usage

To learn the full power of the symfony expression language please check the documentation for the common expression syntax. Here are some examples to understand the power of the expression language:

[page["uid"] in 18..45]
# This condition matches if current page uid is between 18 and 45
[END]

[frontend.user.userId in [1,5,7]]
# This condition matches if current logged in frontend user has the uid 1, 5 or 7
[END]

[not ("foo" matches "/bar/")]
# This condition does match if "foo" **not** matches the regExp: `/bar/`
[END]

[applicationContext == "Production" && userId == 15]
# This condition matches if application context is "Production" AND logged in user has the uid 15
# Note that the old syntax with two blocks combined with && is deprecated
# and will not work in v10:
# [applicationContext == "Production"] && [userId == 15]
[END]

[request.getNormalizedParams().getHttpHost() == 'typo3.org']
# This condition matches if current hostname is typo3.org
[END]

[like(request.getNormalizedParams().getHttpHost(), "*.devbox.local")]
# This condition matches if current hostname is any subdomain of devbox.local
[END]

[request.getNormalizedParams().isHttps() == false]
# This condition matches if current request is **not** https
[END]

[request.getPageArguments().get('foo_id') > 0]
# This condition matches if the GET parameter foo_id is greater than 0.
# getPageArguments() contains resolved route parts from enhancers which
# request.getQueryParams() does not contain.
[END]

[traverse(request.getQueryParams(), 'tx_news_pi1/news') > 0]
# This condition matches if current query parameters have tx_news_pi[news] set to a value greater than zero
[END]

Variables

The following variables are available. The values are context related.

Variable Type Description
applicationContext String current application context as string
page Array current page record as array
{$foo.bar} Constant

Any TypoScript constant is available like before. Depending on the type of the constant you have to use different conditions, see examples below:

  • if constant is an integer: [{$foo.bar} == 4711]
  • if constant is a string put constant in quotes: ["{$foo.bar}" == "4711"]

tree

.level

.rootLine

.rootLineIds

.rootLineParentIds

Object

Integer

Array

Array

Array

object with tree information

current tree level

array of arrays with uid and pid

an array with UIDs of the root line

an array with parent UIDs of the root line

backend

.user

.user.isAdmin

.user.isLoggedIn

.user.userId

.user.userGroupList

Object

Object

Boolean

Boolean

Integer

String

object with backend information (available in BE only)

object with current backend user information

true if current user is admin

true if current user is logged in

UID of current user

comma list of group UIDs

frontend

.user

.user.isLoggedIn

.user.userId

.user.userGroupList

Object

Object

Boolean

Integer

String

object with frontend information (available in FE only)

object with current frontend user information

true if current user is logged in

UID of current user

comma list of group UIDs

workspace

.workspaceId

.isLive

.isOffline

Object

Integer

Boolean

Boolean

object with workspace information

id of current workspace

true if current workspace is live

true if current workspace is offline

typo3

.version

.branch

.devIpMask

Object

String

String

String

object with TYPO3 related information

TYPO3_version (e.g. 9.4.0-dev)

TYPO3_branch (e.g. 9.4)

$GLOBALS['TYPO3_CONF_VARS']['SYS']['devIPmask']

Functions

Functions take over the logic of the old conditions which do more than a simple comparison check. The following functions are available in any context:

Function Parameter Description

request

.getQueryParams()

.getParsedBody()

.getHeaders()

.getCookieParams()

.getNormalizedParams()

.getPageArguments()

Custom Object

This object provides 6 methods

[request.getQueryParams()['foo'] == 1]

[request.getParsedBody()['foo'] == 1]

[request.getHeaders()['Accept'] == 'json']

[request.getCookieParams()['foo'] == 1]

[request.getNormalizedParams().isHttps()]

[request.getPageArguments().get('foo_id') > 0]

date String

Get current date in given format. Examples:

  • true if day of current month is 7: [date("j") == 7]
  • true if day of current week is 7: [date("w") == 7]
  • true if day of current year is 7: [date("z") == 7]
  • true if current hour is 7: [date("G") == 7]
like String This function has two parameters: the first parameter is the string to search in the second parameter is the search string Example: [like("foobarbaz", "*bar*")]
traverse Array and String This function has two parameters: - first parameter is the array to traverse - second parameter is the path to traverse Syntax: <array-key>[/<array-key>]* Example: [traverse(request.getQueryParams(), 'tx_news_pi1/news') > 0]
ip String Value or Constraint, Wildcard or RegExp possible special value: devIP (match the devIPMask)
compatVersion String version constraint, e.g. 9.4 or 9.4.0
loginUser String

value or constraint, wildcard or RegExp possible Examples:

  • [loginUser('*')] // any logged in user
  • [loginUser(1)] // user with uid 1
  • [loginUser('1,3,5')] // user 1, 3 or 5
  • [loginUser('*') == false] // not logged in
getTSFE Object

TypoScriptFrontendController ($GLOBALS['TSFE'])

Conditions based on getTSFE() used in a context where TSFE is not available will always evaluate to false.

getenv String PHP function: getenv()
usergroup String value or constraint, wildcard or RegExp possible

The following functions are only available in frontend context:

Function Parameter Description
session String

Get value from session

Example, matches if session value = 1234567 [session("session:foo|bar") == 1234567]

site String

get value from site configuration, or null if no site was found or property does not exist

Example, matches if site identifier = foo [site("identifier") == "foo"]

Example, matches if site base = http://localhost [site("base") == "http://localhost"]

siteLanguage String

get value from siteLanguage configuration, or null if no site was found or property does not exist

Example, match if siteLanguage locale = foo [siteLanguage("locale") == "de_CH"]

Example, match if siteLanguage title = Italy [siteLanguage("title") == "Italy"]

Extending the expression language with own functions (like old userFunc)

It is possible to extend the expression language with own functions like before userFunc in the old conditions. An example could be TYPO3\CMS\Core\ExpressionLanguage\FunctionsProvider\TypoScriptConditionFunctionsProvider which implements the most core functions.

Please read .. _the introduction: https://docs.typo3.org/typo3cms/extensions/core/Changelog/9.4/Feature-85828-MoveSymfonyExpressionLanguageHandlingIntoEXTcore.html first.

Add new methods by implementing own providers which implement the ExpressionFunctionProviderInterface and register the provider for the key typoscript in your own Configuration/ExpressionLanguage.php file:

return [
   'typoscript' => [
      \TYPO3\CMS\MyExt\ExpressionLanguage\MyCustomProvider::class,
   ]
];

The code above will extend the TypoScript condition configuration with your own provider, which provide your own functions.