PHPackages                             sitegeist/csvpo - 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. [Localization &amp; i18n](/categories/localization)
4. /
5. sitegeist/csvpo

ActiveNeos-package[Localization &amp; i18n](/categories/localization)

sitegeist/csvpo
===============

CSV based translations handling for Neos for easy use and colocation with presentational fusion

v2.1.0(3mo ago)755.2k↓32.4%2[2 issues](https://github.com/sitegeist/Sitegeist.CsvPO/issues)3GPL-3.0-or-laterPHPCI passing

Since Sep 6Pushed 1mo ago3 watchersCompare

[ Source](https://github.com/sitegeist/Sitegeist.CsvPO)[ Packagist](https://packagist.org/packages/sitegeist/csvpo)[ RSS](/packages/sitegeist-csvpo/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (10)Dependencies (7)Versions (42)Used By (3)

Sitegeist.CsvPO
===============

[](#sitegeistcsvpo)

Neos package for easy handling of translation labels in csv files, with a backend module for label overriding and cli support
-----------------------------------------------------------------------------------------------------------------------------

[](#neos-package-for-easy-handling-of-translation-labels-in-csv-files-with-a-backend-module-for-label-overriding-and-cli-support)

This package allows to manage translations as csv-files directly in the fusion component folder with easy access in the style of css-modules.

[![](./Resources/Public/Images/backend-module.png)](./Resources/Public/Images/backend-module.png)

The package comes with a backend module for overriding translations and cli commands to bake overrides back to the csv files for versioning.

Advantages:

- Translations are managed directly in a \*translation.csv file in the fusion component folder
- Translations can be aded and used in a very simple way
- Translations can be edited in any spreadsheet app to spot missing translations directly
- Translations can be altered by customers and managers via backend module
- Altered translations can be stored back to the translation files via cli
- The Neos locale fallback chain and the formatters are used as in the classic xliff translations

Drawback:

- No pluralforms are supported (yet)
- This solution is probably not ideal for really large numbers of locales (&gt;10) as the files will get out of hand
- Translations for NodeType inspector labels are not supported

Authors &amp; Sponsors
----------------------

[](#authors--sponsors)

- Martin Ficzel -

*The development and the public-releases of this package is generously sponsored by our employer .*

Usage
-----

[](#usage)

The CsvPO helper provides the eel function `CsvPO.create` that takes the path to the translation csv file as argument. The returned object allows to access the translations in fusion and afx.

Example.fusion

```
prototype(Vendor.Site:Example) < prototype(Neos.Fusion:Component) {

    @private.i18n = ${CsvPO.create('resource://Vendor.Site/Private/Fusion/Presentation/Example.translation.csv')}

    renderer = afx`

            {private.i18n.title}
            {private.i18n["subtitle"]}
            {private.i18n.text({info:'foo'})}
            {private.i18n.missing}s

    `
}

```

Chain translations and optional overrides
-----------------------------------------

[](#chain-translations-and-optional-overrides)

When multiple csv files are given the labels from files at the end of the chain take precedence.

```
prototype(Vendor.Site:Example) < prototype(Neos.Fusion:Component) {
    i18n = ${CsvPO.create('resource://Vendor.Site/Private/Fusion/TranslationChainExample/Generic.translation.csv', 'resource://Vendor.Site/Private/Fusion/TranslationChainExample/Override.translation.csv')}
}

```

Combined with the `@private` syntax from fusion in Neos 8.3 this allows to specify generic translations and allow to optionally pass translation-files that will take precedence.

```
prototype(Vendor.Package:TranslationChainExample) < prototype(Neos.Fusion:Component) {

    # can be set from outside and is recommended to be null by default
    i18nOverride = 'resource://Vendor.Package/Private/Fusion/TranslationChainExample/Override.translation.csv'

    # combines a predefined translation with one that os passed as props.
    @private {
        i18n = ${CsvPO.create('resource://Vendor.Package/Private/Fusion/TranslationChainExample/Generic.translation.csv', props.i18nOverride)}
    }

    renderer = afx`

        {private.i18n.example}

    `
}

```

### Placeholders

[](#placeholders)

CSVPO supports the same syntax for placeholders as the classic xliff translations of Flow. See:

```
    # customize translation with params
    example1 = ${private.i18n.example('hello', 'world')}

    # placeholders can also be passed as array
    example2 = ${private.i18n.example(['hello', 'world'])}

    # or as named data-structure
    example3 = ${private.i18n.example({title:"hello"})}

```

### Global translations

[](#global-translations)

Global translations can be extracted into a prototype to be used across the whole project. It is recommended to use the `Neos.Fusion:Memo` as base prototype to only evaluate the prototype once.

```
prototype(Vendor.Site:GlobalTranslations) < prototype(Neos.Fusion:Memo) {
    discriminator = 'Vendor.Site:GlobalTranslations'
    value = ${CsvPO.create('resource://Vendor.Site/Private/Fusion/Presentation/Globals.translation.csv')}
}

prototype(Vendor.Site:Example) < prototype(Neos.Fusion:Component) {

    @private.i18n = Vendor.Site:GlobalTranslations

    renderer = afx`

            {private.i18n.title}
            {private.i18n.text({info:'foo'})}

    `
}

```

In `Development` context missing translations are marked with `-- i18n-add --`if the identifier is unknown and `-- i18n-translate --` if the translation value was empty. In `Production` context the identifier is returned when no translation could be determined.

CSV files
---------

[](#csv-files)

Each csv file manages a number of translations in all locales. The First line of the csv is treated as header and identifies the meaning of the translation.

Example.translation.csv

```
id,description,en,de
title,the title for the dialog,title,Titel
description,short explanation,text with {info} placeholder,Text mit {info} Platzhalter

```

Rules:

- The column `id` represents the label identifier
- The column `description` represents the label description
- All other columns are treated as beeing a translation for the locale from the header line
- Arguments passed to the translations replace placeholders in curly braces.
- Html markup in translation labels is supported
- The csv files uses `,` as delimiter and `"` as text delimiters.

CSV file are chosen because of the wide tooling support since literally every spreadsheet application can edit those files.

NOTE: Using xliff was evaluated and rejected because it requires multiple files, makes it exceptionally hard to spot missing translations and has very weak tooling support. The only xliff feature csv does not support is plural forms which is rarely used.

Backend Module &amp; Policies
-----------------------------

[](#backend-module--policies)

The Translations backend module allows to show all translations of the given source. Translation overrides can be defined and are visualized for the editors aswell as fallbacks.

The backend module is accessible to the roles `Administrator` and `TranslationEditor`. `Editors` must be given access to modify the translations explicitly.

CLI
---

[](#cli)

CvsPO comes with several cli commands

- `csvpo:list` Show a list of all translation sources
- `csvpo:show` Show the translations of the specified source
- `csvpo:showAll` Show the translations of the specified source
- `csvpo:bake` Bake the translations of the specified source back to the csv file
- `csvpo:bakeAll` Bake the overrides all source back to the csv files
- `csvpo:reset` Reset translation overrides of the specified source
- `csvpo:resetall` Reset translation overrides of all sources

Configuration
-------------

[](#configuration)

The following configurations allow to control the behavior of the package and the provided management options.

```
Sitegeist:
  CsvPO:

    # render visible hint for missing translations
    # is enabled by default for debug mode
    debugMode: false

    # Control which translation options are available in
    # the backend module and the cli
    management:
      # enable locallization overrides, disables in contexts
      # without database like visual regression testing
      enabled: true

      # package keys to scan for translation files
      packageKeys: []

      # list of locales to manage in the backend module
      locales: ['en']

      # file extension to search for translations
      fileExtension: '.translation.csv'

      # folder inside the package resources to search for translations
      resourcePath: 'Private/Fusion'

      # automatically flush the Neos Fusion content cache when translation overrides are updated via the backend module.
      # Enable this if you need instant translation updates.
      flushNeosFusionContentCacheOnTranslationUpdate: false
```

Caching
-------

[](#caching)

Translations are cached in the `Sitegeist_CsvPO_TranslationCache` Cache. A file monitor will invalidate the caches whenever a .csv file is changed inside a Fusion Folder of any Flow-Package.

If you are storing the translation csv files in another place make sure to call `./flow cache:flushone Sitegeist_CsvPO_TranslationCache` after changing a translation.csv.

**Note on Fusion content caching:** When translation overrides are updated through the backend module, you may need to flush the `Neos_Fusion_Content` cache to see changes immediately in the frontend. This can be automated by enabling the `flushNeosFusionContentCacheOnTranslationUpdate` setting (see Configuration section above). By default, this is disabled to avoid performance impacts on high-traffic sites.

### Installation

[](#installation)

Sitegeist.CsvPO is available via packagist. Just run `composer require sitegeist/csvpo`. We use semantic-versioning so every breaking change will increase the major-version number.

###  Health Score

55

—

FairBetter than 98% of packages

Maintenance80

Actively maintained with recent releases

Popularity35

Limited adoption so far

Community21

Small or concentrated contributor base

Maturity70

Established project with proven stability

 Bus Factor1

Top contributor holds 81.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 ~86 days

Recently: every ~177 days

Total

28

Last Release

109d ago

Major Versions

v1.6.1 → v2.0.02023-07-12

v1.6.2 → v2.0.22024-02-20

### Community

Maintainers

![](https://www.gravatar.com/avatar/1159e78bff9c03cc5ed626447ca5072097107f58af459a9b8bac8d933ba8298c?d=identicon)[wilhelm.behncke](/maintainers/wilhelm.behncke)

![](https://www.gravatar.com/avatar/829b4ccb51e8cff3c1e4b59d60cfe8d1b86f6d77fc31a6b3fc99227f432542ca?d=identicon)[mficzel](/maintainers/mficzel)

---

Top Contributors

[![mficzel](https://avatars.githubusercontent.com/u/1309380?v=4)](https://github.com/mficzel "mficzel (78 commits)")[![paavo](https://avatars.githubusercontent.com/u/1118783?v=4)](https://github.com/paavo "paavo (12 commits)")[![hedayati-m](https://avatars.githubusercontent.com/u/66601551?v=4)](https://github.com/hedayati-m "hedayati-m (3 commits)")[![grebaldi](https://avatars.githubusercontent.com/u/2522299?v=4)](https://github.com/grebaldi "grebaldi (2 commits)")[![nezaniel](https://avatars.githubusercontent.com/u/1687674?v=4)](https://github.com/nezaniel "nezaniel (1 commits)")

---

Tags

i18ninternationalizationl10nneoscmstranslation

###  Code Quality

Static AnalysisPHPStan

Code StylePHP\_CodeSniffer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/sitegeist-csvpo/health.svg)

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

###  Alternatives

[neos/neos

An open source Content Application Platform based on Flow. A set of core Content Management features is resting within a larger context that allows you to build a perfectly customized experience for your users.

116989.0k674](/packages/neos-neos)[illuminate/translation

The Illuminate Translation package.

6936.4M495](/packages/illuminate-translation)[sandstorm/neostwofactorauthentication

1223.6k](/packages/sandstorm-neostwofactorauthentication)[myoutdeskllc/salesforce-php

salesforce library for php8+

1560.8k](/packages/myoutdeskllc-salesforce-php)

PHPackages © 2026

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