Rethinking Translation Handling (Based on a session of T3CMD 2022)

Rethinking Translation Handling

Based on the session “Rethinking translation handling” at T3CMD 2022 and some further conversations, I found encouragement from the participants to push my ideas forward and got the feedback that I should share and discuss my thoughts with members of the core development team. For this reason, I would like to write down my ideas as best I can and hope to be able to lead a lively discussion with the community.

Current Problems

The strict distinction between a concrete default language that must be defined and non-default languages (translations) in TYPO3 makes dealing with multiple languages a bit too inflexible and difficult for editors to understand.

Generally speaking, the default language has a special status in the language overlay concept and must be treated differently than non-standard languages. This leads to some editorial problems, which I would like to name as follows:

1. Distinction between “free” and “connected” mode

From an editor’s point of view, the distinction between “free” and “connected” mode in the context of content translation is difficult to understand and handle.

Example: Imagine a page where all content elements are associated with the default language. Now a new content element should only be output in the non-default language. To solve this you either create a hidden “helper” content element in the default language (Misuse of the default language as a structure provider and additional editorial effort) or you unlink all content elements of the non-default language (Loss of all features related to the connections). Both ways are not so easy to understand and have their drawbacks.

2. Translations between non-default languages

If an editor is supposed to do a translation from one non-default language to another non-default language, then he or she has no option to only display these two non-default languages in the page module. Unfortunately, the default language is always part of the display in the backend. It would be editorially desirable if any source language could be displayed instead of the default language.

Example: Imagine a website in default language German. A Spanish editor would now like to translate the English translations of this website into Spanish because he or she does not speak German. The German texts bother him in the backend and he or she would like to display the English texts instead. Since German editors also want to translate the German texts into English, a permanent change of the default language in the database is not practicable.

3. Fixed (default) language of the page tree

The page tree is always displayed in the default language. As noted in point 2, this can be a problem for editors who are not familiar with the default language. They would certainly like to be able to change the language of the page tree to a different source language.

Possible Solution

In Short

Rethink about the default language as a pure structure provider, that is independent of any particular language and is generated automatically in the background while editing particular languages.

In this way, we do not deviate too far from the current status of translation handling, since the language overlay concept can be retained and it mainly changes the type of display in the backend (hidden structural layer aka default language).

Example Structure and Graphics

In the context of pages you can imagine this as in the following graphic from Info > Localization overview:

or as a table:

Structural Layer English (USA) German (Germany) Spanish (Spain)
[1-root] Startpage Startseite Página de inicio
[1-1_customer_portal] Portal de clientes
[1-2_retailer] Fachhandel
[1-3_service] Service Servicio
[1-4_career] Career
[1-5_business_units] Business Units Unidades de negocio
[1-6_products] Products Produkte
[1-7_company] Company Unternehmen Empresa

In the context of content you can imagine this as in the following graphic from the page module:

or as a table:

Structural Layer English (USA) German (Germany) Spanish (Spain)
[content-1] [content-1_es-ES]
[content-2] [content-2_de-DE]
[content-3] [content-3_de-DE] [content-3_es-ES]
[content-4] [content-4_en-US]
[content-5] [content-5_en-US] [content-5_es-ES]
[content-6] [content-6_en-US] [content-6_de-DE]
[content-7] [content-7_en-US] [content-7_de-DE] [content-7_es-ES]

In both cases the structure of pages and content is clearly defined across all languages by the structural layer aka default language.

Discard the “free” mode

The free mode should be discarded then, since we are always connected with the structural layer, regardless of whether or not a record exists in the language previously defined as the default language.

Source and Target language(s)

On the one hand, an editor should be able to determine at runtime in which source language he or she would like to work. On the other hand, he or she should be able to determine into which target language(s) he or she would like to translate this source language if he or she is not currently working in column view.

Therefore a new option to select the source language in the TYPO3 backend needs to be introduced which replaces the default language column by the selected source language. The language menu, which currently already exists in the page module, can be retained for the purpose of selecting the target language.

Reduce displayed structure

Since each language can have its own structures, it can happen that the structure layer, that applies to all languages, becomes very complex.

To solve this problem the selected source language also determines the structures displayed in the backend. So only that part of the structural layer is used, that has a connection to the currently selected source language. In this way, the display can be kept clear and the focus can be placed on the language currently used and the language to be translated into.

Example 1: If we select “English (USA)” as source language and “Spanish (Spain)” as target language while using the structures shown in the grapics above the resulting page tree should look like this:

  • Startpage
  • Career
  • Business Units
  • Products
  • Company

And the page module should look like this:

English (USA) Spanish (Spain)
[content-4_en-US]
[content-5_en-US] [content-5_es-ES]
[content-6_en-US]
[content-7_en-US] [content-7_es-ES]

Example 2: If we select “Spanish (Spain)” as source language and “English (USA)” as target language while using the structures shown in the grapics above the resulting page tree should look like this:

  • Página de inicio
  • Portal de clientes
  • Servicio
  • Unidades de negocio
  • Empresa

And the page module should look like this:

English (USA) Spanish (Spain)
[content-1_es-ES]
[content-3_es-ES]
[content-5_es-ES] [content-5_en-US]
[content-7_es-ES] [content-7_en-US]

Side aspects that need decisions

Different sorting across languages?

As the participants of the session noted, it can happen that content should be connected to the same structure element across several languages, but should still be sorted differently from language to language. Here it has to be considered whether in such cases the connection to separate structural elements is necessary or whether there is a way how this deviation can be taken into account within a specific language.

Translation of the page tree as separate task?

One participant noted that translating the page tree based on the structure-layer concept could be considered a separate task. Implementation at page level will probably be easier to implement than at content element level.

New Database tables to provide the structural layer?

Since the structure layer requires far fewer fields than the actual pages and content elements of a specific language, one might consider moving these to separate tables to streamline processing.

What’s next?

Thank you for taking the time to engage with my thoughts. I would be very happy if you would let me know what you think about it.

  • Have I overlooked aspects of how translations are handled?
  • What do you think of the basic idea?
  • Is there something that you would solve differently or do you have completely different ideas about it?
  • How do you deal with the mentioned editorial problems?

Thanks in advance for your feedback.

Discussions on other platforms

Abandoning “free mode” seems a bit excessive to me, as it increases complexity significantly - especially for sites with similar page trees but completely different content - but everything else sounds reasonable at first glance.

However, you should also consider structured content containers, as they will also increase complexity many times over.

Thank you for your response. I agree with you about the “free mode” in cases like you described. The concept is particularly advantageous when the languages ​​have predominantly structural similarities. So let’s not do without the “free mode” completely, but use it less often in many cases thanks to the structural layer.

Since there is currently no uniformly defined standard for structured content containers (what would be desirable), I find it difficult to transfer this concept to it. In general, content nesting is structural information, which should then also be covered by the structural layer.

The concept looks promising

Thank you for creating this concept!

I’d like to add some aspects that originate from my experience as a TYPO3 developer.

What is “structure”?

If I’ve understood your concept correctly (with the help if the discussion in Facebook), the structural layer as visible and editable within the backend (seeing the screenshots one could think that it is hidden in the backend and completely handled in the background).
I think it is very difficult to make a clear and clean separation of structure and content within a CMS. Especially considering that you should not strictly bind any functionality / features to either content or structure regarding handling in translations.

Some examples:

  1. The text of a headline is content and we may all agree that the field containing this information is different in all languages (with an optional langauge fallback) and in this case there will be no requirement to keep this information in sync between languages (besides the fallback, but that is no “sync”).
    So within this concept this field will always reside within the content layer = languages.

  2. The year of birth of a person is content and we may all agree that this information is the same in all languages.
    Where does such a field reside in this concept? From a functional point of view it belongs to the structural layer, because it does not get translated, but I think we may all agree that we would not classify the year of birth as structural data.

  3. The style of a headline is imo both structure and content, and there may be the requirement that this information is either the same in all languages or that it should be possible to change it within translations.
    So there should be the possibility to define fields either as structure or as content?

  4. An image is content, but there may be the requiremnt to either change a certain image within a specific structure for all languages or to be able to define a different image file as image within a specific structure.
    Like the year field it would be not natural to see an image as structure.

The current language handling based on a default language has the l10n_mode=exclude setting for fields, so you edit those fields only within the default language, and it is the same in all translations.
That there is a default language that is “special” and defines certain aspects of all translations, is comprehensible in my opinion, as itself is a language. At the moment the structural layer concept seems harder to understand for editors if the structural layer is visible and has to be used for certain tasks. It is an abstract concept and seems not as graspable as a “special language”.

Breaking changes

In my experience there exists a lot of extension code with
if ($sysLanguageUid) {…} else {…}
and similar differentiations, and they will all break if this is introduced.
Especially with the separate table idea (which I don’t like), it could be a lot of work to make the existing code compatible. It will not always be as easy as to just keep one part of a condition.
The current concept seems to be focused on pages/tt_content data, but there also is extbase, and imho the translation handling of the pages/tt_content part of TYPO3 should be 100% identical to the translation handling of extbase.
So if we discuss a new translation handling, we should take extbase (and the existing extbase extensions) into account.

Thank you for your detailed reply.

In fact, to be clear, I imagine that the structure layer remains hidden by default as shown in the screenshots, since it doesn’t add any value to the editor, or at least it’s not supposed to. By default, the editor should only see the languages ​​that he has selected as the source language and target language(s).

The structures used for the backend display at runtime depend on the part of the structural layer for which there exists a translation into the currently selected source language.

Admittedly, I’m not quite sure if it will be conceptually possible to completely omit a possibility of displaying the structural layer in the backend, but at least this should be the exception and all processes as well as the backend display should be designed in such a way that the structural layer is generated and updated automatically based on the structures adapted to the respective languages.

In the end, it should therefore not be necessary to edit or view the structural layer. Imagine a default language that updates automatically and lies invisibly in the background, never appearing on the frontend or backend.

I wouldn’t necessarily say that the individual pieces of information provided by the structural layer need to be structural in nature themselves. These can also be content (like the date of birth, header style or images that are used across languages) that is displayed in the context of the individual languages, as is already done in the context of the default language.

Referring to l10n_mode=exclude, the field should then be displayed in the non-default language too (since we do not want to display the structural layer).

If we do that, we have to differentiate whether an entry only applies to the currently edited language (save it in the translation record) or whether it should apply to all languages ​​(save it in the structural layer aka default language). One could solve this by giving each l10n_mode=exclude field an additional checkbox “use globally” or something similar by default.

Yes, I agree with you regarding the idea of separate tables. I admit that introducing separate tables for the structural layer might create more problems than it solves. For this reason, I wouldn’t focus on that either. We can just as well work with the existing tables. It was more of a performance consideration.

Apart from that, the strength of the concept is, that most of the functions can be retained, except for the changed backend display and the simultaneous storage of data in the structural layer and the translation record. Only those extensions would have to be adjusted, which themselves make a form of storing data sets like any kind of import. Extensions that only define their domain model like the news extension does are not affected.

The only new thing of the concept is that the previously used default language 0 is never displayed in the backend or frontend. Accordingly, the condition if ($sysLanguageUid) {…} else {…} will never jump into the else block. Only non-default languages ​​are displayed in the frontend. This should result in leaner extension code or at least to the fact that no further adjustment is necessary.

Correct me if I’m wrong but as far as I can see the concept can be applied to any record type. It’s not just limited to pages and tt_content. Each translatable record uses a sys_language_uid (or a functionally similar) field. Accordingly, structural information can also be stored there under 0.

Thanks for your thoughts, but as always, things are not so easy.
You mainly focused on pages and content. What I’m missing is a more general approach more focused on entities (database rows) in general. Pages and content (and attached images) represent only a subset of everyday database relations we have.

Please consider all types of relations in relational database systems in your concept:

  • How does translation work with m:n relations?
  • Where do n:1 relation information (uid) reside? In the structural or content tables?

An example use case:
Your website shows reference projects. Those are translatable.
Projects have a relation to a “project status”, where exactly 1 can be chosen. (active, archived, in progress) Project status is translatable too.
Projects also have a relation to a manager, where exactly 1 can be chosen. Managers are not translatable.

  • What do you save in DB for the status field? uid of the structural layer, or the uid of the translation?

Generally though, thanks for rethinking the concept!

Thanks for your feedback.

As far as I understand, the concept can be applied to any translatable record with a languageField configuration in the ctrl section of the TCA (usually field “sys_language_uid”). It’s not limited to just pages or tt_content.

Short Answer: It’s entirely up to the extension author and is not influenced by this concept.

Long Answer: To answer your question, I would just strictly follow the current process that already exists when using the default language. For example most extensions already limit the selection within m:m relationships in TCA fields of type select to the default language 0 or to “All” -1 with option foreign_table_where.

Have a look at the TCA configuration for field tx_news_domain_model_news.categories of EXT:news:

'categories' => [
    'exclude' => true,
    'label' => $ll . 'tx_news_domain_model_news.categories',
    'config' => [
        'type' => 'select',
        'renderType' => 'selectTree',
        'treeConfig' => [
            'parentField' => 'parent',
            'appearance' => [
                'showHeader' => true,
                'expandAll' => true,
                'maxLevels' => 99,
            ],
        ],
        'MM' => 'sys_category_record_mm',
        'MM_match_fields' => [
            'fieldname' => 'categories',
            'tablenames' => 'tx_news_domain_model_news',
        ],
        'MM_opposite_field' => 'items',
        'foreign_table' => 'sys_category',
        'foreign_table_where' => ' AND (sys_category.sys_language_uid = 0 OR sys_category.l10n_parent = 0) ORDER BY sys_category.sorting',
        'size' => 10,
        'minitems' => 0,
        'maxitems' => 99,
        'behaviour' => [
            'allowLanguageSynchronization' => true,
        ],
    ]
],

On the other hand TCA fields of type group already limit the selection to the default language by default (if I understood correctly).

In addition, it is also possible in both cases that the option allowlanguagesynchronization=true was set. In these cases it is up to the editor if a field of a localized record should be kept in sync with the default language record, or the localized record it was derived from.

Actually, we don’t need to go too deep here. Since the structural layer is equivalent to the standard language in terms of storage in the database, in these cases the uid of that record(s) is stored that was made available for selection by the extension author based on his or her respective TCA configuration.

For the structural layer concept, however, it is irrelevant whether an extension author decides to use database relations to uids of the default language records or non-default language records. At the end, as without a structural layer concept, it is up to the author to correctly evaluate the stored relation in his code.

The only thing an extension author needs to be aware of is the fact that the structural layer aka default language is never shown in backend or frontend. He has to assume that only non-default languages/translations will be displayed. Everything else remains as it was before.

That answer was way longer than I anticipated.

It’s entirely up to the extension author and is not influenced by this concept.

This is exactly what it should not be like! The authors rely on Extbase (or at least some Core API, hopefully), where this functionality is (must be) covered.

Regarding TCA and stuff. I did not even think about this at this stage. You are about to redefine the data structure. For me this happens on the level of “how is data stored” and “how does the data belong/relate to each other”. TCA, hovever, is “how to configure all this”, which is on a way later stage for me.

So concept-wise I would first need to see a full picture how data shall be persisted. (this ideally leads to tests at a later stage) Optimum would be with real world use cases that correspond to the various persistence options.
After that a configuration concept can be crafted. (maybe some existing stuff like TCA can be reused)
Then an implementation concept for Core and Extbase is needed.
Finally a migration roadmap together with docs must be crafted.

Translation handling

In the past, I had similar issues with the translation handling and translation modes. After the camp I thought to some old notes, I would like to share.

In general, I would suggest avoiding additional structural layers in the translation handling. Instead, I would recommend the opposite and make things more explicit, as it could lead to the same result.

From my point of view, the two translation modes (connected, free) are great. The general concept of the translation handling for content elements should also apply for any other TCA record.

In order to get there and get rid of the default language, some quite hard conceptional decisions have to be taken. It also needs a lot of work to allow a consistent translation handling based on the both translation modes.

I would mainly see the following topics:

1) Define the set of records the translation mode is selected for

Current situation:

We need a definition for which set of records the translation mode is or should be selected by the editor. At the moment it is inconsistent as there are two different approaches regarding TCA records (excluding pages):

a) TCA records in general

The translation mode depends on the current page (pid) and the selected language (sys_language_uid).

b) Content elements (tt_content)

For content elements it depends on the current page (pid), the selected language and the selected column (colpos).

Possibilities:

Should the translation mode be selected based on the

a) pid and language or
b) pid, language and additional columns

Impact:

a) This is highly breaking change for all installations which using different modes based on the column. It could not be migrated without manual decisions for each page with different translation modes on the columns.

From my point of view, it is more comprehensible than two different translation modes on the same page.

b) If other columns like colpos should be taken into account, those should be configured explicit in TCA to allow the same behavior for all kind of records in TCA.

Therefore, it needs a decision which kind of columns and how many should be taken into account.

Those columns should be configured explicit in the TCA for each record.

2) Define which translation modes should be available for a record

Current situation:

The available translation modes aren’t configured explicit. They are set only by an assumption based on the available columns of a TCA record. In short: If sys_language_uid is available, the free mode is possible. If l10n_parent is also defined, the connected mode is also possible.

That leads to five possible states for records:

i) no translation possible

ii) connected mode

iii) free mode

iv) some mixture of free and connected mode

v) and not decided, which translation mode should apply, if no record is created in the set.

Possibilities:

Add an explicit configuration (for example [ctrl][translationModes]) to each TCA record.

The values could be none, if no translation handling should be available or free or connected or both free and connected mode.

Impact:

The configuration could be used to add a wizard for the translation handling to the list module, which could do the same as the wizard does in the page module.

It would also be possible to enforce the connected mode.

3) Get rid of “all languages” as inconsistency

Current situation:

The feature all languages (-1) violates common database normalization rules. It adds additional complexity to each language related operation.

Possibilities:

Remove or replace this feature:

a) Remove it without replacement.

b) Extract the all languages feature from the sys_language_uid column to an own column and copy those records to all available languages on each page. This need some kind of additional configuration to allow or deny such a feature. If the value (e.g. copy to all languages is set) the data handler should take care to update all records which have the record as parent or must find out the parent in the first place. It also needs a concept how to handle different order (sorting column) in different languages, as it is a valid use case.

Impact:

a) This is highly breaking and editors would have some additional work.

b) It is a breaking change and would require a lot of additional logic in the data handler.

4) Make language explicit for each translated record

Current situation:

The column sys_language_uid must be mapped to get the actual language (like de.DE or en.EN) of the record.

Possibilities:

Make the language of each record explicit by using language codes.

Impact:

It is a breaking change for all queries to select different languages. So it needed a long term compatibility layer, which also adds much more logic.

The benefit would be, that there would be no need for a default language anymore.

Conclusion:

As far as I see, it needs a lot of hard decisions and an enormous work to create a really consistent language handling.

Beside the core implementation, I would expect a lot of additional migration work.

In the long run, it would allow a consistent and stable translation handling.

This functionality is currently not fully covered by extbase even without this concept. The author is currently able to determine whether the uid of the default language record or the uid of the translation record is stored in the DB. I don’t want to use this concept to close gaps that exist without this concept, nor to introduce new gaps.

Actually, I hadn’t thought about changing the way data is stored. The way the data relates to each other should also remain untouched.

My thinking is more along the lines of “when a translation is created/edited/deleted, automatically create/edit/delete an associated record in the default language”. This might even be possible with the existing DataHandler hooks. (Of course, as mentioned above, l10n_mode=exclude fields must be taken into account with this approach)

The second, probably more difficult part of this concept would be to adapt the backend interface in such a way that the default language no longer appears in the backend and that a selectable non-default language is provided in its place.

Thanks for describing the necessary steps. Currently I still have the hope that such a far-reaching intervention, such as a redefinition of the persistence layer or a new TCA configuration concept, would not be necessary to solve the problems mentioned in relation to the handling of translations.

I’ve started testing the concept in my own extension. For now, I’m testing whether DataHandler hooks are sufficient to handle automatic saving of standard language records. Later changes to the core regarding the backend display and the selection of the source language have to be made. If I manage to create a fully working prototype to demonstrate my idea I will post it here for evaluation.

But be patient, if it succeeds at all, it will take some time. If there are developers who would also like to pursue this idea further, I would appreciate support. I’ll try, but I have no idea if I have enough resources and skills to put this idea into practice on my own.

Alright. I guess I simply misunderstood you on your goals.

My knowledge so far is, that the current language concept has its shortcomings and limits, which we hit from time to time in larger projects. Hence, I was hoping for a new concept to alleviate those pain points.

Looking forward to your results of course. :crossed_fingers:

@dawind Thank you for sharing your ideas on how to deal with translations. At first glance, it sounds interesting to be able to do without a structural layer.

But I don’t really see the big picture behind the individual points at the moment. There is talk of breaking changes, hard decisions and a lot of work, which I would like to avoid as much as possible in order to see any chance of success for the concept at all. In the end someone has to do all this work and convince the community members that there is no way around the breaking changes to solve the current problems of handling translations in the backend.

In my opinion, the structural layer idea has a better chance of success, since there are no breaking changes assuming an automatic migration process in the form of an upgrade wizard that converts the previous default language 0 into a new non-deafult language.

I still don’t understand why the available modes should be explicitly configured in any dependency. Be it fields of the data set like pid, colPos or sys_language_uid or be it any configuration in the TCA.

The mode of translation should be based on the respective editorial needs and not on the type of database record (explicit definition in the TCA) or how it is stored in relation to the page or content column position.

So far, I’ve found the “all languages” option to be a useful feature, as it makes editorial maintenance of data sets that don’t need to be translated, such as technical metrics, much easier. In my opinion, this added complexity is reasonable in terms of utility.

Apart from that, I cannot see to what extent this step would be necessary in order to come closer to the goal of doing without an explicitly defined default language.

This lost the flexibility to change the language behind an ID in the site configuration. The added value of this adjustment is not yet clear to me.

Just a short note on the modes “free” vs “connected” (I will need more time for a detailed answer):
Besides any possible confusion of editors the modes are not real modes of the page, ie properties of it, but only reflect the current language status of tt_content records. This makes it in my experience hard to deal with them.
a) as an admin I cannot configure a page to be in one of the modes (to allow only certain types of editing) and b) as an engineer I cannot do easily maintenance operations (ie find out data inconsistencies etc).
If these modes are to stay I want to see them materialised as a column in the pages table.

Just wanted to say: Nice to see a discussion from T3CMD turning up here. Thank you, @eric.bode! :+1:

Hey,

thank you for your thoughts and the compiled version of it.

In the past versions, what I’ve tried to achieve was:

  • Have a language configuration available for FE and BE (= until TYPO3 v9, the FE behaviour was configurable via TypoScript, while the BE did not know about it).
  • Simplify the language configuration by avoiding sys_language as DB field (hence, removal of hard-wired “languageId” from the DB)

In my opinion, the next steps towards a more flexible goal (that might be what you suggested) are

  • Feature: Allow multi-level fallbacks on a per-record level (patch pending, but I estimate another 2 weeks work until we have a unified behaviour also for Extbase).
  • Bugfix: In general the relational DB (esp. MM relations) need to be tackled, I know there are various issues in that regard, and that’s similar to what Markus described.
  • Feature: Have the Backend Page Module and the List module reflect the actual language configuration (incl. fallbacks) so editors know what the output is
  • Issue: Remove “sys_language_uid=-1” as this is THE worst part currently on working on multi-language functionality. This is super ugly when it comes to sorting and rendering (does not matter if it is free mode or connected mode!) Olly Hader already investigated in this change, and it’s a TON of work.
  • Migrate from “sys_language_uid” to locales for each record, which we already have in the site configuration. This is a) easily done for the actual records (I have something prepared here) but we have a lot of side-effects and special cases (next to “-1” records, we have handling of FAL sys_file_metadata, and sys_file_references which might not have a language (an image with a person on it, does not have a language). In any case, most work will be to adapt ALL core places to use locales, which currently expected a “languageId”. However, I do think we could achieve this.

Larger issues revolving around sorting (“tt_content.sorting” is a nasty thing) need to be sorted out for this.

This would be the next steps to come to a certain point where we do not need to know about the “language=0”. Why? Because, in the end, we do not care about “language=0” anymore then, but work with locales, and then are independent, however it might be good to define a “default language” per site, which does not have anything to do with the records. Once achieved, rendering the tree in a different page should be possible, and that’s when a concept like yours (having a “shell” for the pages structure) makes a lot of sense, because we still need a “pid” where the records are stored.

Just my 2 cents to the topic, maybe somebody can work with my brain dump :slight_smile:

Thank you Benni for your assessment and your further thoughts. I’m happy to see that the core development team also sees the current editorial issues and is working to resolve them.

Sounds promising. I look forward to testing this feature. Also, do you have in mind the possibility of falling back from one non-default language to another non-default language (e.g.: en-CA to en-US, while de-DE is default) without showing untranslated default language records (possibility to exclude the default language from fallback chain)?

thank you for that :+1:

That sounds cool and seems to go in the direction I would like it to go.

I initially was concerned about the introduction of locales/explicit language specifications for the languageField as mentioned by you and @dawind, because I feared losing flexibility in defining languages. But this has changed now.

I also discussed the topic with participants of the last t3see usergroup meeting and now understand that this adjustment makes sense to remove an unnecessary layer of abstraction and pave the way for further improvements.

In this context, it’s also great, for example, to be able to transfer translated records between two different instances without having to map the language IDs.

I understand that this is necessary to remain consistent, but I hope there will be some other way of flagging records to be displayed in all languages.

Sometimes there is content that does not need to be translated, such as technical metrics or, as you already mentioned, some FAL relations. It would be nice if you didn’t have to create redundant translation records here.

If there is no connection to the records anymore, it would be great if this adjustment could be made in real-time based on the editor’s preferences instead of being permanent.

With this we would also take up the Spanish editor from my example mentioned above, who is supposed to translate English translations into Spanish. He would choose English as default while the German editor would choose German as default to translate German records to English.

Current discussion related to this topic on Slack:
https://typo3.slack.com/archives/C025BQLFA/p1656323180408479

Just had a discussion about “Language ALL” because there are people having problems configuring their Gridelements frontend output accordingly.

The problem that “Language all” tries to solve could easily be solved by a completely different approach:

Actually redundant content is a good thing when it comes to translations, because then you can easily fetch a whole page in a certain language without even thinking about the default language or anything else besides that particular language. You could even take the records of that language, put them into a completely different database on a completely different server and they would still render nicely.

As long as those records are in the same instance on the same server, you just need to make sure, that any change to the original record will always be pushed to the “language all” records too.

This already happens with the feature “allow language synchronisation” which is currently limited to single fields, but it could easily be extended to a certain record translation behaviour type, so that changes will be applied automagically for that type of translated records.

These are my topics for the T3DD discussion:
https://coders.care/de/blog/artikel/uebersetzungen-wieder-auf-kurs

Default Language

Default Language = 0 is a coding problem, it should be configurable to a definable value.

For coding of bigger project, there is always this special case with the unset language – having always a defined language as a sys_language_uid is better.

Typical use case:

  • project starts with sys_language_uid=0 as DE and sys_language_uid=1 as EN.
    There is usually only one editor preferring a project setup in his native language, and translation to EN is the best way to get used to translation settings. DE usually is the leading language for content.

  • later you get more languages, and translation is now done in a nice chaos of TYPO3 translations, excel files and l10n_manager or exports
    => now EN as default language would be better, but you can‘t configure or change it

Free Mode – Connected Mode

For customers, the connected mode is too restricted, and with free mode we loose all translation connections. Another mode that keeps translation connections would be great.

Typical Workarounds:

  • create unwanted content in default language to have it available in other languages

Unsolved problems in connected mode:

  • different sorting of content elements in other languages is not possible

  • IRRE records: you are in trouble when adding a new IRRE record in translated content that does not exist in default language

  • still some problems with images in translated content, expecially with crop variants. Once you change your translated image you never come back to the originial image. Some kind of reload or reset image to original would be great

Languages and Regions

Typical use case: Switzerland → de_CH, fr_CH, it_CH

On a page there are usually 10 content elements, and only 1 is changed in the specific region.
So you have a 9 copy-paste content elements and a lot of unneccessary work for the editors.

And it blows up the content: de_DE, de_CH, de_IT makes it more and more messy, expecially together with the other unsolved topic: keep track of changes

Having an additional setting for region, additional to language, would be the solution, so any kind of combinations are possible.

L10n_manager

First of all the current situation should be improved: this is a very important extension, and it should be somehow supported, and not letting Jo Hasenau begging for money to update.
Not having it at LTS 11 was a big update blocker for bigger installations.

Maybe we need some new kind of funding for extensions like l10n_manager or news – most installations use them and they depend on one main developer.

This is a very specific feature wishlist for l10n_manager:

  • one more configuration option for page tree:
    use case: I want all pages under one page tree to be translated (like the products section).
    Currently there is only option: „translate all pages“ and „translate pages from selection“, so it ends with clicking through all subpages.

  • hook before translation is written to XML for customization (I have already code for this)

  • hook before translation is imported for verification and customization

  • disable field configuration for tables (exclude some fields for translation export, if you see something unwanted in export xml)

  • IRRE records can produce unneccessary records in translations => check TCA for fields that are defined for the content element, only export these fields
    Why? Unneccessary copy-paste records produces costs per line, and questions come up like: where does this line in translation file come from, I can‘t see it anywhere in FE or BE

  • User interface refactoring, or a second BE module for editors to manage exports and imports. The interface is not changed since V4 and needs a usability update

  • good preview function before import – with selections like: yes import this, no do not import this

Best practices for translation process

Good working examples for setups with 20+ languages would be awesome, and about the process the editors and translation agencies work with it.

More than 50% of the costs are from misunderstandings and wrong exports/imports.

And in my experience, the translations are often done by people in poor countries, on very old computers, outdated Windows versions and Hardware not capable to run a modern software like TYPO3 Backend.
The only tools that work then are Word and Excel, so manual translation steps still have to be in the process as well, together with the professional tools.

Also a tutorial for developers on how translators work and which tools they use would be great, to get this process tested and verified before it goes out to customer and agencies.

How to keep track of translation changes

First translation is nice to implement, we can use export and import for a whole page.
But keeping track of changes is a pain, expecially in a living environment with changes in TYPO3 while translation files are out for some weeks at the translation offices.

A big improvement would be a backend module with an overview of the translation changes that are currently displayed only in the content elements. And here a direct export option for all changed fields.

Workspaces and translations

In V10 workspace uids were in exported l10n_manager files, and could not be imported because workspace got published in the meantime.
Maybe this is fixed in V11 already, but maybe not. Should be verified.

Integration of AI tools

How to integrate deepl.com, google translate and other tools in TYPO3 translation process?