---
title: "View helpers"
manual: "schema"
version: "main"
permalink: "https://docs.typo3.org/permalink/brotkrueml/schema:view-helpers@main"
source: "Developer/ViewHelpers.rst"
rendered: "2026-09-28T16:42:13+00:00"
---

# View helpers {#view-helpers}

Target group: **Developers, Integrators**

**Table of Contents**

-   [Introduction](https://docs.typo3.org/permalink/brotkrueml/schema:introduction@main)
-   [<schema:type> view helpers](https://docs.typo3.org/permalink/brotkrueml/schema:html-schema-type-view-helpers@main)
-   [<schema:multipleType> view helper](https://docs.typo3.org/permalink/brotkrueml/schema:html-schema-multipletype-view-helper@main)
-   [<schema:nodeIdentifier> view helper](https://docs.typo3.org/permalink/brotkrueml/schema:html-schema-nodeidentifier-view-helper@main)
-   [<schema:blankNodeIdentifier> view helper](https://docs.typo3.org/permalink/brotkrueml/schema:html-schema-blanknodeidentifier-view-helper@main)
-   [<schema:property> view helper](https://docs.typo3.org/permalink/brotkrueml/schema:html-schema-property-view-helper@main)
-   [<schema:orderedList> view helper](https://docs.typo3.org/permalink/brotkrueml/schema:html-schema-orderedlist-view-helper@main)
-   [<schema:breadcrumb> View Helper](https://docs.typo3.org/permalink/brotkrueml/schema:html-schema-breadcrumb-view-helper@main)

## Introduction {#introduction}

With the help of `<schema:type>` view helpers you can define schema markup
in Fluid templates. This can be helpful if you can't use the [API](https://docs.typo3.org/permalink/brotkrueml/schema:api@main),
for example, in third-party extensions.

Each type in the schema.org vocabulary is mapped into an according view helper.
The properties of a type are available as view helper arguments. As you will see
in the example, you can also nest view helpers into each other.

There are currently over 600 view helpers available.

> [!NOTE]
> The extension registers `schema` in the global Fluid namespace. So there is
> no need to import the namespace in your templates.

## `<schema:type>` view helpers {#schema-type-view-helpers}

Let's start with a simple example. It's the same markup about John Smith as in
the [API reference](https://docs.typo3.org/permalink/brotkrueml/schema:types@main), so you can compare the differences.

Imagine you describe a [person](https://schema.org/Person) on a plugin's detail page that you want to
enrich with structured markup:

```html
<schema:type.person
   -id="https://example.org/#person-42"
   givenName="John"
   familyName="Smith"
   gender="https://schema.org/Male"
>
   <schema:type.event
      -as="performerIn"
      name="Fancy Event"
      image="https://example.org/event.png"
      url="https://example.org/"
      isAccessibleForFree="true"
   >
      <schema:property -as="sameAs" value="https://mastodon.social/@fancy-event"/>
      <schema:property -as="sameAs" value="https://pixelfed.social/@fancy-event"/>
   </schema:type.event>
</schema:type.person>
```

Every type view helper starts with `<schema:type.xxx>` where `xxx`
is the lower camel case variant of the schema.org type name.

> [!NOTE]
> If the type name starts with a number (for example, `3DModel`) then the first
> number of the view helper is written out (`<schema:type.threeDModel`).

The according properties (like `givenName` and `familyName`) are attributes.
You can find a list of all available properties for a specific type on the
schema.org page, for example, for the [person](https://schema.org/Person).

In the example, there are two attributes that begin with a `-`. They are
explained in detail in the chapter [Special attributes](https://docs.typo3.org/permalink/brotkrueml/schema:view-helpers-special-attributes@main).

As you can see, the value `true` (and `false` accordingly) can be
used. They are mapped later to the schema types `https://schema.org/True` and
`https://schema.org/False`.

Please also recognise the `<schema:property>` view helper. With this view
helper you can pass more than one string value to the according type.

You can also use the default Fluid view helpers:

```html
<schema:type.blogPosting
   -isMainEntityOfWebPage="1"
   headline="{data.title}"
   description="{data.description}"
   datePublished="{f:format.date(format:'Y-m-d', date: data.publishDate)}"
>
   <f:if condition="{data.lastUpdated}">
       <schema:property -as="dateModified" value="{f:format.date(format:'Y-m-d', date: data.lastUpdated)}"/>
   </f:if>
</schema:type.blogPosting>
```

### Special attributes {#view-helpers-special-attributes}

Special attributes start with a dash (`-`) to separate them
from the common properties of the schema.org specification and to avoid
collisions. Let's have a deeper look on them.

-   **-id**

    This attribute sets a unique id for the type and is mapped in JSON-LD to the
    `@id` property. The LD in JSON-LD means "linked data". With an `@id` you
    can define a type on one page (for example, `Event`):

    ```json
    {
       "@context": "https://schema.org/",
       "@type": "Event",
       "@id": "https://example.org/#event-1",
       "name": "Fancy Event",
       "image": "https://example.org/event.png",
       "url": "https://example.org",
       "isAccessibleForFree": "https://schema.org/True",
       "sameAs": ["https://mastodon.social/@fancy-event", "https://pixelfed.social/@fancy-event"]
    }
    ```

    and reference it on the same or another page (for example, `Person`):

    ```json
    {
       "@context": "https://schema.org/",
       "@type": "Person",
       "@id": "https://example.org/#person-42",
       "givenName": "John",
       "familyName": "Smith",
       "gender": "https://schema.org/Male",
       "performerIn": {
          "@type": "Event",
          "@id": "https://example.org/#event-1",
          "name": "Fancy Event"
       }
    }
    ```

    > [!TIP]
    > You can also cross-reference the types between different websites. The
    > `@id` is globally unique, so a best practise is to use an
    > IRI for it. It is also
    > good practise to add the `name` property as attribute.

-   **-as**

    This attribute is used to connect a type to its parent. In the above example,
    you can see that the event type view helper uses `-as` to connect to
    the `performerIn` property of the person type view helper.

    > [!NOTE]
    > The usage of the attribute makes only sense in a child. If it is used in a
    > parent type the view helper is ignored.

-   **-specificType**

    Sometimes it can may be helpful to set a specific type. Imagine you have
    records of places in the backend where you can select which type of specific
    place a record has: for example, `Museum`, `Airport`, `Park` or `Zoo`. In a
    Fluid template you can loop over these records when they are on the same
    page. But it is not very convenient to use a `<f:switch>` or
    `<f:if>` view helper to choose the correct type. For this scenario you
    can benefit from this argument:

    ```html
    <f:for each="{places}" as="place">
       <schema:type.place
          name="{place.name}"
          -specificType="{place.type}"
       />
    </f:for>
    ```

    > [!NOTE]
    > When using the `-specificType` attribute you can only set the
    > properties of the original type view helper (here: place), no additional
    > ones from the specific type.

-   **-isMainEntityOfWebPage**

    This argument defines the type as a [main entity](https://docs.typo3.org/permalink/brotkrueml/schema:main-entity-of-web-page@main)
    of a [web page](https://docs.typo3.org/permalink/brotkrueml/schema:web-page-type@main):

    ```html
    <schema:type.person
       -id="https://example.org/#person-42"
       -isMainEntityOfWebPage="1"
       givenName="John"
       familyName="Smith"
       gender="https://schema.org/Male"
    />
    ```

    which results in the output:

    ```json
    {
       "@context": "https://schema.org/",
       "@type": "WebPage",
       "mainEntity": {
          "@type": "Person",
          "@id": "https://example.org/#person-42",
          "givenName": "John",
          "familyName": "Smith",
          "gender": "https://schema.org/Male"
       }
    }
    ```

    Main entities can be prioritised, please have a look into the
    [Prioritisation](https://docs.typo3.org/permalink/brotkrueml/schema:main-entity-prioritisation@main) section.

## `<schema:multipleType>` view helper {#schema-multipletype-view-helper}

You can also add a [multiple type](https://docs.typo3.org/permalink/brotkrueml/schema:multiple-types@main) node:

```html
<schema:multipleType
   -id="https://example.org/#my-product-and-service"
   types="Product,Service"
   properties="{
      name: 'My product and service',
      manufacturer: 'Acme Ltd.',
      provider: 'Acme Ltd.'
   }"
/>
```

In the `types` argument the types are delimited by commas. Add in the
`properties` argument the name/value pairs of the according properties.
Here you can mix the properties from the defined types.
The special properties `-as`, `-id` and
`-isMainEntityOfWebPage` can also be used as [described above](https://docs.typo3.org/permalink/brotkrueml/schema:view-helpers-special-attributes@main).

The example results in the following JSON-LD:

```json
{
   "@context": "https://schema.org/",
   "@type": ["Product", "Service"],
   "@id": "https://example.org/#my-product-and-service",
   "manufacturer": "Acme Ltd.",
   "name": "My product and service",
   "provider": "Acme Ltd."
}
```

You can also use the [PropertyViewHelper](https://docs.typo3.org/permalink/brotkrueml/schema:schema-property-view-helper@main) to
add properties to a multiple type instead the `properties` argument:

```html
<schema:multipleType
   -id="https://example.org/#my-product-and-service"
   types="Product,Service"
>
   <schema:property -as="name" value="My product and service"/>
   <schema:property -as="manufacturer" value="Acme Ltd."/>
   <schema:property -as="provider" value="Acme Ltd."/>
</schema:multipleType>
```

## `<schema:nodeIdentifier>` view helper {#schema-nodeidentifier-view-helper}

Sometimes it is useful to reference a node with just the ID. For this case the
`<schema:nodeIdentifier>` view helper is available:

```html
<f:variable name="identifier1" value="{schema:nodeIdentifier(id: 'https://example.org/#john-smith')}"/>
<f:variable name="identifier2" value="{schema:nodeIdentifier(id: 'https://example.org/#sarah-jane-smith')}"/>
<schema:type.person name="John Smith" -id="{identifier1}" knows="{identifier2}"/>
<schema:type.person name="Sarah Jane Smith" -id="{identifier2}" knows="{identifier1}"/>
```

This generates the following JSON-LD:

```json
{
   "@context": "https://schema.org/",
   "@graph": [
      {
         "@type": "Person",
         "@id": "https://example.org/#john-smith",
         "name": "John Smith",
         "knows": {
            "@id": "https://example.org/#sarah-jane-smith"
         }
      },
      {
         "@type": "Person",
         "@id": "https://example.org/#sarah-jane-smith",
         "name": "Sarah Jane Smith",
         "knows": {
            "@id": "https://example.org/#john-smith"
         }
      }
   ]
}
```

The view helper has only one attribute which is required:

-   **id**

    This attribute defines the id and is mapped in JSON-LD to the `@id`
    property.

## `<schema:blankNodeIdentifier>` view helper {#schema-blanknodeidentifier-view-helper}

Sometimes it is not necessary (or possible) to define a globally unique ID
with an IRI. For these cases you can use a blank node identifier:

```html
<f:variable name="blankIdentifier1" value="{schema:blankNodeIdentifier()}"/>
<f:variable name="blankIdentifier2" value="{schema:blankNodeIdentifier()}"/>
<schema:type.person name="John Smith" -id="{blankIdentifier1}" knows="{blankIdentifier2}"/>
<schema:type.person name="Sarah Jane Smith" -id="{blankIdentifier2}" knows="{blankIdentifier1}"/>
```

This generates the following JSON-LD:

```json
{
   "@context": "https://schema.org/",
   "@graph": [
      {
         "@type": "Person",
         "@id": "_:b0",
         "name": "John Smith",
         "knows": {
            "@id": "_:b1"
         }
      },
      {
         "@type": "Person",
         "@id": "_:b1",
         "name": "Sarah Jane Smith",
         "knows": {
            "@id": "_:b0"
         }
      }
   ]
}
```

The view helper has no arguments.

You can find more information in the [Blank node identifier API section](https://docs.typo3.org/permalink/brotkrueml/schema:blank-node-identifier@main).

## `<schema:property>` view helper {#schema-property-view-helper}

You can only set one string value in the argument of a type view helper, but
sometimes it is necessary to add more than one value to it. There comes the
property view helper into the game:

```html
<schema:type.corporation
   name="Acme Ltd."
   image="https://example.org/logo.png"
   url="https://example.org/"
>
   <schema:property -as="sameAs" value="https://mastodon.social/@acme"/>
   <schema:property -as="sameAs" value="https://pixelfed.social/@acme"/>
</schema:type.corporation>
```

You can use as much property view helpers as you like for the same property. If
you prefer, you can combine the view helpers as follows:

```html
<schema:type.corporation>
   <schema:property -as="name" value="Acme Ltd."/>
   <schema:property -as="image" value="https://example.org/logo.png"/>
   <schema:property -as="url" value="https://example.org/"/>
   <schema:property -as="sameAs" value="https://mastodon.social/@acme"/>
   <schema:property -as="sameAs" value="https://pixelfed.social/@acme"/>
</schema:type.corporation>
```

The `<schema:property>` view helper accepts two argument, both are
required.

-   **-as**

    You know already the `-as` attribute from the [type view helpers](https://docs.typo3.org/permalink/brotkrueml/schema:schema-type-view-helpers@main). Its purpose is the same, it references the
    property in the parent `<schema:type>` view helper.

-   **value**

    The `value` argument sets the value of the property, as you guessed
    already.

## `<schema:orderedList>` view helper {#schema-orderedlist-view-helper}

<!-- TODO: no Markdown rendering for "versionadded" -->

The view helpers adds a property value as an [ordered list](https://docs.typo3.org/permalink/brotkrueml/schema:list@main) item:

```html
<f:variable name="positiveNotes" value="{
   0: 'Tougher and water resistant design.',
   1: 'Cheery bright colours and solid feel.',
   2: 'Excellent amplification.',
}"/>

<schema:type.review name="Megaphone 11 review">
   <schema:orderedList -as="positiveNotes" items="{positiveNotes}"/>
</schema:type.review>
```

The `<schema:orderedList>` view helper accepts two argument, both are
required.

-   **-as**

    You know already the `-as` attribute from the [type view helpers](https://docs.typo3.org/permalink/brotkrueml/schema:schema-type-view-helpers@main). Its purpose is the same, it references the
    property in the parent `<schema:type>` view helper.

-   **items**

    The `items` argument sets the value to a list of items (a string or
    a node identifier).

## `<schema:breadcrumb>` View Helper {#html-schema-breadcrumb-view-helper}

This view helper is described in-depth in the chapter
[View helper \<schema:breadcrumb>](https://docs.typo3.org/permalink/brotkrueml/schema:breadcrumb-view-helper@main).
