RFC: Simplifying translations in Fusion components

For a while now I’ve been thinking on how to reduce clutter when translating labels in Fusion/AFX.
I also blogged about the TranslationHelper a while ago https://mind-the-seb.de/blog/the-translation-helper-in-neos-cms.

Yesterday after again looking at an AFX template that contained many super long translation calls with package and source and so on, I played with a helper that would provide me with a TranslationParameterToken and prefills the package and source argument based on the currently rendered name of the prototype.

This is would allow something like this:

prototype(Shel.Site:Content.Text) < prototype(Neos.Neos:ContentComponent) {
    i18n = Shel.Site:Helper.I18n {
        prefix = 'NodeTypes'
    }
    renderer = afx`
        <div>
            {props.i18n.id('test').value('fallback')}
        </div>
    `
}

It would then read the labels from Resources/Private/Translations/en/NodeTypes/Content/Text.

But what about providing this automatically in every Neos.Fusion:Component so i18n is available in the renderer like the props?

Then the example would look like this:

prototype(Shel.Site:Content.Text) < prototype(Neos.Neos:ContentComponent) {
    renderer = afx`
        <div>
            {i18n.id('test').value('fallback')}
        </div>
    `
}

Of course it should be a lazy prop as many components don’t need the translation feature.
And if i18n is provided as prop, it wouldn’t override it.

Maybe there are even better ways to do this?
Is it adding too much magic?

We at Sitegeist use our CsvPo package for component translations that are collocated with the fusion file in a single folder. It even has a backend module to adjust the labels.

1 Like

Simplifying the translations is definitely a good thing but I fear that there is no easy way to tell the i18n.helper about the current fusion path. It simply has no access to the fusion runtime to ask for that.

Maybe Neos.Fusion:Component could do that? That way all translations would be relative to the prototype of the last Component.

1 Like

Yes exactly that was I meant with my last example. I my first example the implementation of Shel.Site:Helper.I18n looks at the parent path and takes the prototype name from there. But if the Component can do it by itself, it would already have the correct name in fusionObjectName.

I’m just afraid it could maybe cause more confusion when people inherit from a type and the translations don’t work anymore. In that case the original component should define the i18n part explictely instead.

But probably the component should only do that if something inherits from it, or in many cases it would try to read translations from Neos.Neos.

I like your CSVPO package but I think it currently still has too many drawbacks for a generic solution IMO (besides I don’t like CSV files :wink: ).
I would especially dislike having the multiple translation files in a component folder.

Totally agree that cspo is not for everything and especially not for massive multilanguage use cases. We were a bit sick of maintaining translations far away from the components in multiple files/folders.

BTW: We chose CSV because we were not able to find a single simple tool that could edit xliff and show a label | language matrix to fill like any spreadsheet can with csv. For a framework|CMS or massive multilanguage site xliff is definetely the way to go.

Intellij Idea has a really nice editor for Resource Bundles. Something like that would be really neat for XLIFF files :slight_smile:

Since it’s in the community edition, I will see if I can manage to implement something like this, since translations are a major pain point for me as well. There are just to many files to handle if there is more than one language…

2 Likes