PHPackages                             networkteam/neos-contentsubstitution - 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. networkteam/neos-contentsubstitution

ActiveNeos-package

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.

v0.1.0(1mo ago)012↓66.7%GPL-2.0-or-laterJavaScript

Since Jul 15Pushed 1mo agoCompare

[ Source](https://github.com/networkteam/Networkteam.Neos.ContentSubstitution)[ Packagist](https://packagist.org/packages/networkteam/neos-contentsubstitution)[ RSS](/packages/networkteam-neos-contentsubstitution/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (1)Dependencies (1)Versions (3)Used By (0)

Networkteam.Neos.ContentSubstitution
====================================

[](#networkteamneoscontentsubstitution)

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
------------

[](#installation)

```
composer require networkteam/neos-contentsubstitution
```

How it works
------------

[](#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
-------------

[](#configuration)

### Define variables

[](#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)

[](#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

[](#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)
-------------------------------------------------------

[](#usage-in-custom-rendering-eg-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
-----------

[](#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
-------

[](#license)

GPL-2.0-or-later, see [LICENSE](LICENSE).

###  Health Score

33

—

LowBetter than 72% of packages

Maintenance90

Actively maintained with recent releases

Popularity7

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity25

Early-stage or recently created project

 Bus Factor1

Top contributor holds 50% 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

Unknown

Total

1

Last Release

47d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/790179df9a15d9175b9ec8fdc2df5c4c660a52a4fb6d429376cf66b66b0a595c?d=identicon)[chlu](/maintainers/chlu)

---

Top Contributors

[![bweinzierl](https://avatars.githubusercontent.com/u/30659291?v=4)](https://github.com/bweinzierl "bweinzierl (2 commits)")[![hlubek](https://avatars.githubusercontent.com/u/33351?v=4)](https://github.com/hlubek "hlubek (2 commits)")

### Embed Badge

![Health badge](/badges/networkteam-neos-contentsubstitution/health.svg)

```
[![Health](https://phpackages.com/badges/networkteam-neos-contentsubstitution/health.svg)](https://phpackages.com/packages/networkteam-neos-contentsubstitution)
```

###  Alternatives

[neos/neos-ui

Neos CMS UI written in React

2671.1M129](/packages/neos-neos-ui)[neos/neos-base-distribution

Neos Base Distribution

4467.0k](/packages/neos-neos-base-distribution)[neos/demo

Site package for the Neos Demo Site

18194.6k13](/packages/neos-demo)[sitegeist/kaleidoscope

Responsive-images for Neos

29383.0k14](/packages/sitegeist-kaleidoscope)[sandstorm/neostwofactorauthentication

1330.1k](/packages/sandstorm-neostwofactorauthentication)[neos/seo

SEO configuration and tools for Neos

141.1M37](/packages/neos-seo)

PHPackages © 2026

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