I'm really impressed with Payload's field level support for localization. We are using po and pot files to manage localized strings, which we are looking to import into our Payload system. I can't imagine we're the first to want to do this, is there any existing tooling to support this? If not, what would be a good way to design such tooling, and if we build it, might there be interest to incorporate that into Payload?
I would LOVE to incorporate that into Payload!!!
We want to build a significantly more robust translations workflow.... so any ideas or feedback that you have there would be amazing
So this is what I think it should look like: Iterate over all the documents, within each, iterate over all the localized fields, take their values (in the default locale) and produce a POT file. Send the POT file to translators and get back N PO files, one for each supported locale. Iterate over all the documents again, iterate over the localized fields as before, update the docs with the strings in each of the N locales taken from the N PO files. This will be using the strings in the default locale as keys to look up the corresponding strings in all the other locales. Use a gettext implementation to deal with all the PO/POT files, there are a few different implementations in npm, not sure yet which would be the best to go with.
https://www.npmjs.com/package/node-gettextand
https://www.npmjs.com/package/@types/node-gettextmight be a good place to start
Hey Dan, I'll respond to your email here so we can get the discussion going.
Can you give me a summary of what it is you are working on and trying to achieve? Is this to make po files for localized content from Payload projects or does this have to do with admin panel i18n?
This is to support localization of
content, not of the admin panel ui. I believe you already have some support for localizing the admin UI, but none yet for the content.
This is what I have so far (not everything is working yet):
* Given a collection config, pull out the paths to all localized text fields in the config, including fields nested inside groups, arrays, etc. Naturally, this will be extended to handle multiple collections, perhaps all. I'm looking for direction on how to best configure the behaviour of the tool here.
* Given a document from this collection, pull out all the string values of all the localized text fields in the document. For each value, I also get the path to where the value come from, e.g. the string "The south Pacific" came from collectionX.documentY.groupZ.fieldW.
* Given the set of string values, write the strings to file in POT format
The work flow from here would then be to send the POT file off to translation, getting back a PO file for each language, where those PO files map from strings like "The south Pacific" to "Der Südpazifik". PO/POT files are widely used, there are lots of tools for managing and manipulating them, see getText. Now we would need to choose a getText implementation to facilitate the process of looking up translations from the source language to each translated language. There are a couple of different implementations to choose from. I have not decided, so I am mocking out the getText() function in the folloing.
* Given a function getText() which maps from the source language to each translated language, and given a set of documents in the collection, look up all values in all documents and save all localized fields.
PO/POT files work best for strings that are no more than a paragraph long. I'm looking for a solution that would work well for strings that are longer than that, such as a blog post. Maybe there are getText() based tools that work well for that, or perhaps getText() is not a good choice. The overall workflow is still going to be close, though.
Some of the questions I have:
* Is this of interest, does it align with the direction you want to take Payload?
* Is the overall approach valid? Does it look like it would play well with the existing support for localizing the admin UI?
* What is the best way to update payload documents with localized strings? Your docs are pretty thin on this, this page
https://payloadcms.com/docs/configuration/localizationcovers how to pull localized data, but not how to update it.
* Which getText implementation to use, e.g.
https://www.npmjs.com/package/node-gettext* Consider whether PO/POT is the correct file format or whether there are others that are better suited for translating strings longer than a paragraph.
* Once we start looking at the code, perhaps there are smarter ways to code this, I don't know the Payload codebase well.
I'm coming from a spot of never having used PO/POT files before, so I need to catch up a little before I can offer much here.
Without digging in, I wonder if this can handle things like html tags. Suppose you have to translate something from a richtext field:
<p> Something <bold> bold </bold> and <a href="">link</a></p>Are you able to parameterize it enough to make it work with this for example?
I don't want a half-baked feature. If is supported, then we can move forward. I'm imagining there will be a place to upload translation files that goes to a special collection that has hooks to do the document creation/updating using the local api.
We have to decide if this is a core feature or a plugin. I'm leaning towards an official plugin under payloadcms/plugin-
whatever-we-call-it.
I'll do some learning and reply to your specific questions tomorrow.
About the HTML tags, I think the use case here is that there is a blog post in English that contains
Something <bold> bold </bold>, and the translator would translate this as
quelque chose <bold> d'audacieux </bold>. Since this is about translating
contentonly, it seems to me that the use cases for needing to handle strings with placeholders, plurals and such is not there. Perhaps I am overlooking something? That
doesneed to be handled in the localization of the admin interfaces, and also any other custom React component that can be build in Payload to support any particular document collection, but that is a separate thing.
We build a multilingual app, using PO/POT files for translation of UX elements. Our toolchain consists of lingui
https://lingui.dev/that handles exporting strings from JSX to POT and importing the translated strings from PO and making the strings appear in the correct locale in the app. Lingui contains a
<Trans>component so we can flag in the JSX that a particular string should be translated by having
<Text><Trans>This is the string</Trans><Text>. It can also handle placeholders like so we can translate
"City - \"{city}\"to
"Ville – « {city} »".There are several alternatives to lingui
https://react.libhunt.com/js-lingui-alternativesWe also use Weblate
https://weblate.org/en/to manage the translation of UX strings, great for keeping track of which strings are new/changed in each release so we know what strings to send for translation.
This new plugin to Payload would do for content roughly what lingui does for code, with a feature set that is appropriate for the needs of translating content, which i
thinkis quite a bit simpler than for code.
Star
Discord
online
Get dedicated engineering support directly from the Payload team.