TypoScript syntax comes with a couple of operators to assign values, copy from other identifier paths, and to manipulate values. Let's have a closer look at them.

Value assignment with "="

This most common operator assigns a single line value to an identifier path. Everything after the = character until the end of the line is considered to be the value. The value is trimmed, leading and trailing whitespaces are removed.

Values are parsed for constant references. With a value assignment like foo = someText {$someConstant} furtherText, the parser will look up the constant reference {$someConstant} and tries to substitute it with a defined constant value. If such a constant does not exist, it falls back to the string literal including the {$ and } characters.

A couple of examples:

Extension examples, file Configuration/TypoScript/Syntax/Assignment/setup.typoscript
# Identifier "myIdentifier" is set to the value "foo"
myIdentifier = foo

# Identifier path "myIdentifier.mySubIdentifier" is set to the value "foo"
myIdentifier.mySubIdentifier = foo

# "myIdentifier.mySubIdentifier" it set to the value "foo",
# but is immediately overwritten to value "bar"
myIdentifier.mySubIdentifier = foo
myIdentifier.mySubIdentifier = bar

# Same as above, value of "myIdentifier.mySubIdentifier" is "bar"
myIdentifier.mySubIdentifier = foo
myIdentifier {
   mySubIdentifier = bar

# Value assignments are not comment-aware, "#", "//" and "/*" after a
# "=" operator do not start a comment. The value of identifier
# "myIdentifier.mySubIdentifier" is "foo // not a comment"
myIdentifier.mySubIdentifier = foo // not a comment

# Value assignment using a constant:
# Ends up as "foo myConstantValue bar" if constant "myConstant" is set to "myConstantValue"
# Ends up as "foo {$myConstantValue} bar" if constant "myConstant" is not set
myIdentifier. mySubIdentifier = foo {$myConstantValue} bar

Multiline assignment with "(" and ")"

Opening and closing parenthesis are used to assign multi-line values. This allows defining values that span several lines and thus include line breaks.

The end parenthesis ) is important: If it is not found, the parser considers all following lines until the end of the TypoScript text snipped to be part of the value. This includes comments, [GLOBAL] conditions and @import file includes: They are not a syntax construct and are considered part of the value assignment.

However, the value is parsed for constants (text looking like {$myIdentifier.mySubIdentifier}: The parser will try to substitute them to their assigned constant value. The "TypoScript" and "Page TSconfig" backend modules may show a warning if a reference to a constant can't be resolved. If a constant reference can't be resolved, the value falls back to its string literal. Since multi-line values are sometimes used to output JavaScript, and JavaScript also uses a syntax construct like {$...}, this may lead to false positive warnings in those backend modules.

A couple of examples:

Extension examples, file Configuration/TypoScript/Syntax/OperatorMultiLine/setup.typoscript
myIdentifier= TEXT
myIdentifier.value (
   This is a
   multiline assignment

myIdentifier= TEXT
myIdentifier.value (
   <p class="warning">
      This is HTML code.

myIdentifier= TEXT
myIdentifier.value (
   This looks up the value for constant {$myConstant}
   and falls back to the string "{$myConstant}" if it can
   not be resolved.

Unset with ">"

This can be used to unset a previously defined identifier path value, and all of its sub identifiers:

Extension examples, file Configuration/TypoScript/Syntax/ObjectUnset/setup.typoscript
myIdentifier.mySubIdentifier = TEXT
myIdentifier.mySubIdentifier = myValue
myIdentifier.mySubIdentifier.stdWrap = <p>|</p>

# "myIdentifier.mySubIdentifier" is completely removed, including value
# assignment and sub identifier "stdWrap"
myIdentifier.mySubIdentifier >

# Same as above: Everything after ">" operator is considered a comment
myIdentifier.mySubIdentifier > // Some comment

Copy with "<"

The < character is used to copy one identifier path to another. The whole current identifier state is copied: both value and sub identifiers. It overrides any old sub identifiers and values at that position.

The copy operator is useful to follow the DRY - Don't repeat yourself principle. It allows maintaining a configuration set at a central place, and copies are used at further places when needed again.

The result of the below TypoScript is two independent sets which are duplicates. They are not references to each other but actual copies:

Extension examples, file Configuration/TypoScript/Syntax/OperatorCopy1/setup.typoscript
myIdentifier = TEXT
myIdentifier.value = Hello world
myOtherIdentifier = TEXT
myOtherIdentifier.value = Hello world

# The above is identical to this:
myIdentifier = TEXT
myIdentifier.value = Hello world
myOtherIdentifier < myIdentifier

The copy operator is allowed within code blocks as well:

Extension examples, file Configuration/TypoScript/Syntax/OperatorCopy2/setup.typoscript
myIdentifier {
   10 = TEXT
   10.value = Hello world
   20 < myIdentifier.10

In the above example, the copied identifier path is referred to with its full path myIdentifier.10. When copying on the same level, it is allowed to use a relative path, indicated by a prepended dot. The following produces the same result as above:

Extension examples, file Configuration/TypoScript/Syntax/OperatorCopy3/setup.typoscript
myIdentifier {
   10 = TEXT
   10.value = Hello world
   20 < .10

Using the copy operator creates a copy of the source path at exactly this point in the parsing process. Changing the source afterwards does not change the target, and changing the target afterwards does not change the source:

Extension examples, file Configuration/TypoScript/Syntax/OperatorCopy4/setup.typoscript
# The above is identical to this:
myIdentifier = TEXT
myIdentifier.value = Hello world
myOtherIdentifier < myIdentifier

# Changing myIdentifier *after* it has been copied over to myOtherIdentifier,
# does *not* change myOtherIdentifier. The below line only changes the
# value of myIdentifier, not myOtherIdentifier:
myIdentifier.value = Hello world 2

# Changing myOtherIdentifier *after* it has been copied from to myIdentifier,
# does *not* change myIdentifier. The below line only changes the
# value of myOtherIdentifier, not myIdentifier:
myOtherIdentifier.value = Hello world 3

References with "=<"

In the context of frontend TypoScript, it is possible to create references from one identifier path to another within the tt_content path. References mean that multiple positions can copy the same source identifier path without making an actual copy. This allows changes to the source identifier afterwards, which changes the targets as well. References can be convenient for this special case, but should be used with caution.

Extension examples, file Configuration/TypoScript/Syntax/OperatorReference/setup.typoscript
lib.myIdentifier = TEXT
lib.myIdentifier {
   value = Hello world
   stdWrap.wrap = <p>|</p>
tt_content.text =< lib.myIdentifier
tt_content.textpic =< lib.myIdentifier

# This changes lib.myIdentifier.stdWrap.wrap *and* tt_content.text.stdWrap.wrap
lib.myIdentifier.stdWrap.wrap = <h1>|</h1>
# This changes only tt_content.textpic.stdWrap.wrap
tt_content.textpic.stdWrap.wrap = <h2>|</h2>

Value modifications with ":="

This operator assigns a value to an identifier path by calling a predefined function which modifies the existing value in different ways. This is very useful when a value should be modified without completely redefining it again.

A modifier is referenced by its modifier name, plus arguments in parenthesis. These predefined functions are available:


Add a string to the beginning of the existing value.

foo = cd
foo := prependString(ab)
# foo is "abcd"

Add a string to the end of the existing value.

foo = ab
foo := appendString(cd)
# foo is "abcd"

Remove a string from the existing value.

foo = foobarfoo
foo := removeString(foo)
# foo is "bar"

Replace old with new value. Separate these using |.

foo = abcd
foo := replaceString(bc|123)
# foo is "a123d"

Add values to the end of a list of existing values. There is no check for duplicate values, and the list is not sorted in any way.

foo = 123,456
foo := addToList(789)
# foo is "123,456,789"

foo =
foo := addToList(123)
# foo is "123" (no leading comma added on empty existing value)

Remove a comma-separated list of values from an existing comma-separated list of values. Empty values are removed as well.

foo = foo,123,bar,456,foo,,789
foo:= removeFromList(foo,bar)
# foo is "123,456,789"

Remove duplicate entries from a comma-separated list of values.

foo = 123,456,abc,456,456
foo := uniqueList()
# foo is "123,456,abc"

Reverses the order of entries in a comma-separated list of values.

foo = 123,456,abc,456
foo := reverseList()
# foo is "456,abc,456,123"

Sorts the entries in a comma-separated list of values. There are optional sorting parameters, multiple can be separated using ,:

ascending (default)
Sort the items in ascending order: First numbers from small to big, then letters in alphabetical order.
Sort the items in descending order: First letters in descending order, then numbers from big to small.
Apply numeric sorting: Numbers from small to big, letters sorted after "0".
foo = 10,100,0,20,abc
foo := sortList()
# foo is "0,10,20,100,abc"

foo = 10,0,100,-20
foo := sortList(numeric)
# foo is "-20,0,10,100"

foo = 10,100,0,20,-20
foo := sortList(numeric,descending)
# foo is "100,20,10,0,-20"

Access a $_ENV value. Resolves to empty value if not set.

# $_ENV['foo'] = 'fooValue'
foo := getEnv(foo);
# foo is "fooValue"

Changed in version 12.0

The PSR-14 event \TYPO3\CMS\Core\TypoScript\AST\Event\EvaluateModifierFunctionEvent is available to define custom TypoScript functions. The event replaces the hook $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsparser.php']['preParseFunc'].

The section EvaluateModifierFunctionEvent provides an example and the API.