networkteam/neos-contentsubstitution

Placeholder substitution for Neos CMS: replaces {{variable}} placeholders in rendered content with values configured via Fusion, including a Neos UI richtext editor plugin to insert placeholders.

Maintainers

Package info

github.com/networkteam/Networkteam.Neos.ContentSubstitution

Language:JavaScript

Type:neos-package

pkg:composer/networkteam/neos-contentsubstitution

Transparency log

Statistics

Installs: 1

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v0.1.0 2026-07-15 14:01 UTC

This package is auto-updated.

Last update: 2026-07-15 14:05:29 UTC


README

Placeholder substitution for Neos CMS: replaces {{variable}} placeholders in rendered content with values configured via Fusion. Ships with a Neos UI richtext editor plugin that lets editors insert placeholders from a searchable dropdown in the CKEditor toolbar.

Installation

composer require networkteam/neos-contentsubstitution

How it works

The package provides the Fusion object Networkteam.Neos:ContentSubstitution, which replaces all placeholders matching a configurable pattern (default: {{...}}) in a string with values from its variables map:

prototype(Networkteam.Neos:ContentSubstitution) {
    value = ${value}
    pattern = '/\{\{(.*?)\}\}/'
    variables = Neos.Fusion:DataStructure
}
  • Unknown placeholders are left untouched (the original {{...}} text is kept).
  • Substitution only happens in the live workspace — in the backend, editors see the raw placeholder, making it obvious that a substitution will happen.
  • Variable names are trimmed, so {{ myVariable }} and {{myVariable}} are equivalent.

By default the substitution is applied to the whole body of every page via a @process on Neos.Neos:Page:

prototype(Neos.Neos:Page) {
    body.@process.networkteamContentSubstitution = Networkteam.Neos:ContentSubstitution
}

Configuration

Define variables

Declare the available variables and their values in your site package's Fusion:

prototype(Networkteam.Neos:ContentSubstitution) {
    variables {
        companyName = 'ACME Inc.'
        supportMail = ${Configuration.setting('Vendor.Site.supportMail')}
    }
}

Values are evaluated per request with node in context, so they can depend on the current dimension, site, or any other context.

Editor dropdown (Neos UI)

To offer editors a dropdown for inserting placeholders in a richtext editor, list the variable names in the frontend configuration:

Neos:
  Neos:
    Ui:
      frontendConfiguration:
        'Networkteam.Neos.ContentSubstitution':
          variables:
            - companyName
            - supportMail

Entries can also be objects with a separate human-readable label shown in the dropdown (the value is what gets inserted as {{value}}):

          variables:
            - value: 'company.name'
              label: 'Company name'

and enable the feature per property via editorOptions:

'Vendor.Site:Content.Text':
  properties:
    text:
      ui:
        inline:
          editorOptions:
            contentSubstitution: true

Inserting placeholders from Fusion

The Networkteam.Neos:Placeholder prototype renders a placeholder string, e.g. for use in templates that should be substituted later:

placeholder = Networkteam.Neos:Placeholder {
    variable = 'companyName'
}

Usage in custom rendering (e.g. headless / Content API)

Networkteam.Neos:ContentSubstitution can be applied as a @process to any string value, as long as node is in context:

title = ${q(node).property('title')}
title.@process.contentSubstitution = Networkteam.Neos:ContentSubstitution

For PHP-based rendering (e.g. a custom Fusion implementation), declare the object as a sub-path of your prototype and evaluate it per value with the runtime — see the Fusion object's value property, which can be fed from any context variable.

Development

The editor plugin sources live in Resources/Private/Scripts/ContentSubstitutionEditor. Rebuild the bundle with:

yarn install
yarn build   # requires NODE_OPTIONS=--openssl-legacy-provider on Node >= 17

The build output is committed to Resources/Public/ContentSubstitution.

License

GPL-2.0-or-later, see LICENSE.