Fluid Syntax: ViewHelpers

ViewHelper calls can be written using two distinct syntaxes—tag syntax and inline syntax.

ViewHelpers are grouped into namespaces and can be organized in folders.

When a ViewHelper is called in a template, you specify the namespace identifier, followed by a colon and the path to the ViewHelper, separated by dots:

namespace:folder.subFolder.name
Copied!

Tag syntax

The tag syntax works just like HTML or XML. Tags can either be self-closing or can have a content, which can include other HTML tags or ViewHelper calls.

<!-- self-closing -->
<f:constant name="\Vendor\Package\Class::CONSTANT" />

<!-- text content -->
<f:format.case mode="upper">lowercase</f:format.case>

<!-- other ViewHelpers as content -->
<f:switch expression="{myVariable}">
    <f:case value="foo">Variable is foo</f:case>
    <f:case value="bar">Variable is bar</f:case>
    <f:defaultCase>Variable is something else</f:defaultCase>
</f:switch>

<!-- Nested format ViewHelpers -->
<f:format.trim>
    <f:replace search="foo" replace="bar">
        <f:format.case mode="upper">
            {myString}
        </f:format.case>
    </f:replace>
</f:format.trim>
Copied!

Inline syntax

The inline syntax works using curly braces {}. Most ViewHelpers can also be used with the inline syntax, although the syntax might get more complicated depending on the use case.

{f:constant(name: '\Vendor\Package\Class::CONSTANT')}

{f:format.case(value: 'lowercase', mode: 'upper')}

{myVariable -> f:format.case(mode: 'upper')}
Copied!

ViewHelpers that operate on a singular input value can usually be chained, which can make templates more readable:

{myString -> f:format.case(mode: 'upper') -> f:replace(search: 'foo', replace: 'bar') -> f:format.trim()}
Copied!

The inline syntax can also be indented and can contain trailing commas and whitespace:

{f:render(
    partial: 'MyPartial',
    arguments: {
        foo: 'bar',
    },
)}
Copied!

ViewHelper syntax comparison

Depending on the situation, it might be better to use the inline syntax instead of the tag syntax and vice versa. Here is a more complex example that shows where the inline syntax is still possible, but might make things more complicated:

<f:variable name="myArray" value="{0: 'foo', 1: '', 2: 'bar'}" />
<f:for each="{myArray}" as="item">
    <f:if condition="{item}">
        <f:render section="MySection" arguments="{item: item}" />
    </f:if>
</f:for>
Copied!

And its inline syntax variant:

<f:variable name="myArray" value="{0: 'foo', 1: '', 2: 'bar'}" />
{f:render(section:'MySection', arguments: {item: item}) -> f:if(condition: item) -> f:for(each: myArray, as: 'item')}
Copied!

Please note that, in chained inline notation, the f:if ViewHelpers should not use their usual then or else attributes, as they would directly output their value and thus break the chain!

ViewHelper namespaces

There are two syntax variants to import a ViewHelper namespace into a template. In the following examples, blog is the namespace available within the Fluid template and MyVendor\BlogExample\ViewHelpers is the PHP namespace to import into Fluid.

By default, the f namespace is predefined by Fluid. Depending on your setup, additional global namespaces, defined directly via the ViewHelperResolver, might be available.

HTML tag syntax with xmlns attribute

<html
    xmlns:blog="http://typo3.org/ns/Myvendor/MyExtension/ViewHelpers"
    data-namespace-typo3-fluid="true"
>
</html>
Copied!

This is useful for various IDEs and HTML autocompletion. The <html> element itself will not be rendered if the attribute data-namespace-typo3-fluid="true" is specified.

The namespace is built using the fixed http://typo3.org/ns/ prefix followed by the vendor name, package name, and the fixed ViewHelpers suffix.

Curly braces syntax

{namespace blog=MyVendor\BlogExample\ViewHelpers}
Copied!

Any line that uses the curly braces syntax results in a blank line. Multiple statements can be on either one line or across multiple lines.