PHPackages                             flowpack/nodetemplates - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Templating &amp; Views](/categories/templating)
4. /
5. flowpack/nodetemplates

ActiveNeos-package[Templating &amp; Views](/categories/templating)

flowpack/nodetemplates
======================

Neos package that allows to modify nodes on creation via templates.

3.0.0(1y ago)32492.9k—8.1%11[7 issues](https://github.com/Flowpack/Flowpack.NodeTemplates/issues)[2 PRs](https://github.com/Flowpack/Flowpack.NodeTemplates/pulls)14GPL-3.0+PHPCI passing

Since Sep 22Pushed 1y ago12 watchersCompare

[ Source](https://github.com/Flowpack/Flowpack.NodeTemplates)[ Packagist](https://packagist.org/packages/flowpack/nodetemplates)[ RSS](/packages/flowpack-nodetemplates/feed)WikiDiscussions 3.0 Synced 1mo ago

READMEChangelog (10)Dependencies (3)Versions (30)Used By (14)

Neos Node Templates
===================

[](#neos-node-templates)

When using Neos CMS as an editor, you often work with nested node structures that have to be created manually. This packages aims at easing the editing workflow by automatically creating helpful child nodes and making useful modifications to node properties when creating new nodes in the Neos UI.

In contrast to child nodes that are defined in the regular node type definition (which cannot be removed by the editor), all modifications that are made when a template is applied can be changed or removed by the editor.

The desired node structure is defined in a declarative way in the NodeTypes.yaml under the path `options.template`.

TL;DR
-----

[](#tldr)

1. `composer require flowpack/nodetemplates`
2. Add templates to your nodetypes configuration in NodeTypes.yaml, as described in the examples below
3. Or use the command to dump the template based on your workspace

Hello world
-----------

[](#hello-world)

The following example will add a text child node with the content "Hello World" to the main content collection of all pages that are created via the UI:

```
'Neos.NodeTypes:Page':
  options:
    template:
      childNodes:
        mainContentCollection:
          name: 'main'
          childNodes:
            helloWorldTextNode:
              type: 'Neos.NodeTypes:Text'
              properties:
                text: 'Hello world!'
```

Using the node creation dialog
------------------------------

[](#using-the-node-creation-dialog)

The Neos UI comes with a configurable node creation dialog. You can access the data entered in the node creation dialog in your node templates using EEL queries. You could let the editor choose between different dummy texts like this:

```
'Neos.NodeTypes:Page':
  ui:
    creationDialog:
      elements:
        dummyText:
          type: string
          ui:
            label: 'Dummy text'
            editor: 'Neos.Neos/Inspector/Editors/SelectBoxEditor'
            editorOptions:
              values:
                'Hello world':
                  label: 'Hello world'
                'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.':
                  label: 'Lorem ipsum'
  options:
    template:
      childNodes:
        mainContentCollection:
          name: 'main'
          childNodes:
            helloWorldTextNode:
              type: 'Neos.NodeTypes:Text'
              properties:
                text: '${"" + data.dummyText + ""}'
```

You can also access data from the node creation dialog if you use the `showInCreationDialog` feature:

```
'Some.Package:SomeNodeType':
  # ...
  properties:
    'firstName':
      type: string
      label: 'First Name'
      ui:
        showInCreationDialog: true
    'lastName':
      type: string
      label: 'First Name'
      ui:
        showInCreationDialog: true
    'cardTitle':
      type: string
      label: 'Card Title'
  options:
    template:
      properties:
        cardTitle: '${"" + data.firstName + " " + data.lastName + ""}'
```

Conditions and loops
--------------------

[](#conditions-and-loops)

### Conditions

[](#conditions)

If you want to apply a template only under some conditions, you can use the `when` configuration key. It can be used in the main node template or in any child node template.

The following example only creates a text node if the option was selected in the creation dialog:

```
'Your.NodeType:ContentCollection':
  ui:
    creationDialog:
      elements:
        createText:
          type: boolean
  options:
    template:
      childNodes:
        text:
          type: 'Your.NodeType:Text'
          properties:
            text: "bar"
          when: '${data.createText}'
```

As a `when` condition that evaluates to `false` prevents the whole template (and all child templates) from being applied, its most common use case is conditional child node creation.

### Loops

[](#loops)

Loops can be used to create multiple child nodes. You can use `withItems` to define the items of the loop. When using EEL, be sure to return an array. The current item is available in EEL expressions as the `item` context variable.

The following example creates three different text child nodes in the main content collection:

```
'Neos.NodeTypes:Page':
  options:
    template:
      childNodes:
        mainContentCollection:
          name: 'main'
          childNodes:
            multipleTextNodes:
              type: 'Neos.NodeTypes:Text'
              properties:
                text: '${"" + item + ""}'
              withItems:
                - 'Hello world'
                - 'Different text'
                - 'Yet another text'
```

We call conditions `when` and loops `withItems` (instead of `if` and `forEach`), because it inspires a more declarative mood. The naming is inspired by Ansible.

EEL context variables
---------------------

[](#eel-context-variables)

There are several variables available in the EEL context for example.

Variable nameTypeDescriptionAvailabilitydata`array`Data from the node creation dialogGlobalsite`Node`The site node in which the new node be created inGlobalparentNode`Node`The node where the new utmost node will be created insideGlobalitem`mixed`The current item value inside a loopInside `withItems` loopkey`string`The current item key inside a loopInside `withItems` loop> **Notice**`triggeringNode` was removed with version 3.0. Please use `site` or `parentNode` instead.

> **Warning**The behaviour of `parentNode` changed from version 1.x to version 2.2 Previously it referenced the parent node of the current template part and its nesting. With version 2.0 it was removed and 2.2 reintroduced the variable identifying the parent node of the first/utmost node that will be created.

### Additional context

[](#additional-context)

You can add more context variables to a template via the `withContext` setting. `withContext`takes an arbitrary array of items whose values might also contain EEL expressions:

```
template:
  withContext:
    someText: 'foo'
    processedData: "${String.trim(data.bla)}"
    booleanType: true
    arrayType: ["value"]
  childNodes:
    column0Tethered:
      name: column0
      childNodes:
        content0:
          type: 'Flowpack.NodeTemplates:Content.Text'
          when: "${booleanType}"
          withItems: "${arrayType}"
          properties:
            text: ${someText + processedData + item}
```

Inside `withContext` the parent context may be accessed in EEL expressions, but sibling context values are not available. As `withContext` is evaluated before `when` and `withItems`, you can access context variables from `withContext` in `withItems` at the same level – but not the other way around.

If you want to use a custom EEL helper, make sure to register it in the package's Settings. EEL helpers configured for Neos.Fusion are not automatically available:

```
Flowpack:
  NodeTemplates:
    defaultEelContext:
      My.Foo: 'My\Site\Eel\Helper\FooHelper'
```

Fine-grained error handling, resuming with the next possible operation.
-----------------------------------------------------------------------

[](#fine-grained-error-handling-resuming-with-the-next-possible-operation)

In the first step the configuration is processed, exceptions like those caused by an EEL Expression are caught, and any malformed parts of the template are ignored (with their errors being logged). This might lead to a partially processed template with some properties or childNodes missing.

You can decide via the error handling configuration `Flowpack.NodeTemplates.errorHandling`, if you want to start the node creation of this partially processed template (`stopOnException: false`) or abort the process (`stopOnException: true`), which will only lead to creating the root node, ignoring the whole template.

```
Flowpack:
  NodeTemplates:
    errorHandling:
     templateConfigurationProcessing:
        stopOnException: false
```

In case exceptions are thrown in the node creation of the template, because a node constraint was not met or the `type` field was not set, the creation of the childNode is aborted, but we continue with the node creation of the other left over parts of the template. It behaves similar with properties: In case a property value doesn't match its declared type the exception is logged, but we will try to continue with the next property.

Commands
========

[](#commands)

Validate simple node templates
------------------------------

[](#validate-simple-node-templates)

It might be tedious to validate that all your templates are working especially in a larger project. To validate the ones that are not dependent on data from the node creation dialog (less complex templates) you can utilize this command:

```
flow nodetemplate:validate []
```

**options:**

- `--site`: the Neos site, which determines the content repository. Defaults to the first available one.

In case everything is okay it will succeed with `X NodeType templates validated.`.

But in case you either have a syntax error in your template or the template does not match the node structure (illegal properties) you will be warned:

```
Content repository "default": 76 of 78 NodeType template validated. 2 could not be build standalone.

My.NodeType:Bing
 Property "someLegacyProperty" in NodeType "My.NodeType:Bing" | PropertyIgnoredException(Because property is not declared in NodeType. Got value `"bg-gray-100"`., 1685869035209)

My.NodeType:Bar (depends on "data" context)
  Configuration ""${data.aListOfThings}"" in "childNodes.pages.withItems" | RuntimeException(Type NULL is not iterable., 1685802354186)

```

The standalone validation should detect errors and prevents editors having to deal with these errors at runtime.

For more complex templates, which are dependent on the node creation data, it is recommended to write separate tests. Currently, errors in templates depending on the data context will only be treated as warning, as they are probably not an issue at runtime.

Create template from node subtree
---------------------------------

[](#create-template-from-node-subtree)

When creating a more complex node template (to create multiple pages and content elements) it can be helpful to take the current node subtree from your workspace as reference. For this case you can use the command:

```
flow nodeTemplate:createFromNodeSubtree  []
```

- `--starting-node-id`: specified root node of the node tree

**options:**

- `--site`: the Neos site, which determines the content repository. Defaults to the first available one.
- `--workspace-name`: custom workspace to dump from. Defaults to 'live'.

It will give you the output similar to the yaml example above. References to Nodes and non-primitive property values are commented out in the YAML.

More examples
-------------

[](#more-examples)

For more examples have a look at the node templates demo package:

###  Health Score

52

—

FairBetter than 96% of packages

Maintenance42

Moderate activity, may be stable

Popularity48

Moderate usage in the ecosystem

Community32

Small or concentrated contributor base

Maturity74

Established project with proven stability

 Bus Factor1

Top contributor holds 86.3% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~110 days

Recently: every ~117 days

Total

26

Last Release

409d ago

Major Versions

0.3 → 1.0.02018-04-12

1.4.1 → 2.0.02023-06-07

2.2.0 → 3.0.02025-04-04

### Community

Maintainers

![](https://www.gravatar.com/avatar/25d49a6af82b72d2764774a05c307808375016d7aeaaef3862472a6580ff38a7?d=identicon)[flowpack](/maintainers/flowpack)

---

Top Contributors

[![mhsdesign](https://avatars.githubusercontent.com/u/85400359?v=4)](https://github.com/mhsdesign "mhsdesign (221 commits)")[![daniellienert](https://avatars.githubusercontent.com/u/642226?v=4)](https://github.com/daniellienert "daniellienert (13 commits)")[![Sebobo](https://avatars.githubusercontent.com/u/596967?v=4)](https://github.com/Sebobo "Sebobo (9 commits)")[![dimaip](https://avatars.githubusercontent.com/u/837032?v=4)](https://github.com/dimaip "dimaip (5 commits)")[![theilm](https://avatars.githubusercontent.com/u/1016315?v=4)](https://github.com/theilm "theilm (3 commits)")[![jonnitto](https://avatars.githubusercontent.com/u/4510166?v=4)](https://github.com/jonnitto "jonnitto (2 commits)")[![lorenzulrich](https://avatars.githubusercontent.com/u/1816023?v=4)](https://github.com/lorenzulrich "lorenzulrich (1 commits)")[![ahaeslich](https://avatars.githubusercontent.com/u/1756367?v=4)](https://github.com/ahaeslich "ahaeslich (1 commits)")[![pkaminski-at-180hb](https://avatars.githubusercontent.com/u/94170524?v=4)](https://github.com/pkaminski-at-180hb "pkaminski-at-180hb (1 commits)")

---

Tags

neoscms

###  Code Quality

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

![Health badge](/badges/flowpack-nodetemplates/health.svg)

```
[![Health](https://phpackages.com/badges/flowpack-nodetemplates/health.svg)](https://phpackages.com/packages/flowpack-nodetemplates)
```

###  Alternatives

[neos/neos-base-distribution

Neos Base Distribution

4464.9k](/packages/neos-neos-base-distribution)[flowpack/media-ui

This module allows managing media assets including pictures, videos, audio and documents.

2184.5k2](/packages/flowpack-media-ui)[shel/neos-colorpicker

A plugin for Neos CMS which provides a colorpicker editor

1494.4k6](/packages/shel-neos-colorpicker)[shel/neos-terminal

Neos CMS Ui terminal for running Eel expressions and other commands

1441.3k](/packages/shel-neos-terminal)[shel/critical-css

Allows inlining and optimising styles for components in Neos CMS

102.5k](/packages/shel-critical-css)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
