Building mirrored Plone sites with

Hello community,

I'm sorry in advance for this lengthy article about improving
In the end I don't know, whether this should be a PLIP or maybe just a discussion.

Either way, here we go:

The problem

While offers a great way for building sites with individually curated language versions (probably with a dedicated editor team per language), it does not necessarily suit well for everyone. For example when building a site where each page which needs to be represented in different languages - with editors not changed and where content structure does not change per language necessarily either.

Other CMSes like TYPO3 or Neos have suitable solutions for different multilingual approaches in form of single- and multi-tree modes, whereas Plone offers only one solution for building (multi-tree) multilingual sites.

Now, building a single-tree solution from scatch is a totally different beast and I understand, that pursuing that way will bear lots of risks. Therefor I would like to focus at first on a solution which is built upon to make the world better for everyone.

So the main nagging points for us on the current state of are:

  • When an editor wants to build a mirrored site and creates content with its translations, the editing process should be as easy as possible - that means skipping tedious linking of translations, managing workflows for individual objects, keeping synchronized permissions. The whole process to keep everything the same demands much attention from the editor.
  • The lack of support to allow local language settings in a deeper level of the site. There might be parts of the site that offer new languages, which are not necessarily available at the whole site.
  • Even with allowing all possible languages from the root, creating a new translations from an existing object will create a new object in the root folder with no relation to its parent object. This eventually leads to a mess, where the structure is lost, unless one replicates/translates each container one by one from root to the current object.
  • Managing resources at places other than root. We established at our site the concept of resource folders, that collects the available resources (images, files, etc.) to the respective group - with different permission settings. While offers a singular language independent resource folder in the root, this is not sufficient in a scale of many different editor groups.

The solution(?)

To make things constructive, I would like to share a possible solution and I would appreciate your feedback, whether you consider this attempt to be suitable for the aforementioned problems or to be just not worth for further elaboration.

Synchronized subtrees

Think of this as an orthogonal workflow to the usual publication workflows, which allows to synchronize the state of objects across all languages.
In terms of this would mean that all objects within a translation group (i.e. one object and its translations) have synchronized actions like

  • Workflow actions Like publishing, submit, retract ..
  • Adding/Pasting/Moving/Deleting objects
  • Specialized actions like adding/remove persons in collective.workspace
  • etc.

to be applied on all language trees. The last point is especially important in order to have the very same permission situation in the respective language tree.
There is already one add-on collective.multilingualtools that would allow this for some actions.

Combining those actions might take proportionally longer with an increasing number of languages, but might be off-loaded with asynchronous tasks in the background to ease loading time.

Special content in language trees

One still can create content for a language-exclusive audience by disabling synchronization for an container/item.
When a container is not synchronized, all its children are also not synchronized.
The editor is then responsible to manually link translations if needed, but that is in the end the default editor experience with

Local language settings

By default language settings are coupled with the Plone site. There are add-ons like ftw.subsite or collective.lineage to mimic a Plone site, that probably could work to achieve local language settings, but this is yet to explored. In one thread it is being said, that there might problems with and collective.lineage.

Another approach could be to make the language utility context-specific, where the hierarchy could be checked, if any object offers local language settings. But that would require probably many changes in the core.

Place holder objects

The idea of place holders are to solve the problem of losing the original hierarchy in the different language trees, which happens, when one translate an object without translating all its ancestor objects before.

One idea discussed at the Plone Tagung 2020 in Dresden (with @fredvd et al) was be to automatically create these ancestor objects, when creating a new object/translation. This is done by cloning the counter-part from the main-language, ideally with the language-specific id, and labeling them explicitly as place holder.

Place holders will not be offered as available translation for the end user, but can be used by the editor, once the language is available in the respective level. Place holders are also synchronized with their original object, making it easier later to pick them off and finish the full translation.

Risks / Open issues

At the time of writing I am afraid to see risks both in terms of maintainability and scalability.

To allow working with synchronous actions, the language versions must to be perfectly in sync. If one language version is out of sync, the whole action is turned futile. This might easily happen, when one object is locked. I am not sure if this level of synchronization can be held in the long term.

The idea of copying an object and labeling it as place-holder also seems to be quite expensive compared to the benefit (restored structure, correct permission settings).
Maybe there are some more efficient solutions with a smaller memory-footprint?


Attempting to implement these ideas is a potentially big endeavour and I therefor would like to hear your feedback. Maybe you do see other ways to improve the way in order to deal with the mirrored site approach?


Edit: I redacted my texts and retracted the idea of the common/cross-lingual view on resource folders.


I always preferred the idea that fields can be made multilingual. Back in 2003 (before linguaplone), I made 2 multilingual sites using multilingual fields; I proposed my solution to the Plone devs, but it was (politely) dismissed. The, while proposing (imposing?) a solution for every possible situations, is a bit too complex. The translation process could be made simple and intuitive for both the developers and the users. Instead of creating new objects, translation of multilingual fields could be saved within the objects; it may not be a silver bullet, but for simple sites, with simple edition and publication workflows, it works...

Edit: there's a discussion about multilingual fields here: About raptus.multilanguagefields, Plone 5 and beyond

We, as a company, have worked with both multilanguages fields (back in plain Zope era, using Localizer) and with different content per language (such as with LinguaPlone and p.a.multilingual).

I find myself the actual way more elegant: you have different content-trees, with different URLs, properly adapted for search engines and in my point of view, easily explainable for an average content-editor.

There are points like the ones commented here that could be improved, such as synchonizing actions accross languages (which can be achieved using an addon), that require that all content should be in all languages; or a way to "copy" the content-tree to another language and then let the content-editor translate it.

What I would love to see is a way to make Local Language Settings work, to be able to add different languages in different points of the content-tree. This would definetely require changes in p.a.multilingual, but I think it's achievable.

I find all other items as features that could be implemented in different addons.

Multilingualism is hard, and every solution does not work for everyone, anyway I think that the current solution we have in Plone fulfils most of the requirements of a multilingual site.

It can be done by using:

i think the idea of having at least the containers (folders) available in all languages, are they translated or not makes a lot easier. The best of course would be if the folders are translated, where only the title is important here, to have the final url paths. But even if they get translated and renamed after, the redirection tool will take care.

Syncing the trees should not be an issue. Syncing deep trees, on the other side is and will be here as well. So if you update page by page, folder by folder, there is no issue.
For the workflow actions, one could want to publish just one language or multible lanuages.
Whats important here, is that it's clear to the user what happens. So it would be nice to have an extra info which tells me that there are other translations and to list there WF status and even let me change them right from that list.

But even though most people where saying don't go the other way, as you have it right now with your linguafields, what is right for your usecase you know best. Don't let people tell you what is best for you. It makes sence to rethink what is the right way, as you are doing. But if you think you are better of with the linguafield solution, go ahead. There are pros and cons in both ways, there is no one true answer here.

Thank you for your responses, @marclava, @erral and @MrTango. Very much appreciated! :slight_smile:

@marclava: This is our current approach! We use raptus.multilanguagefields to store all translations within the object. A known downside is that there is only one id, but that was solved with raptus.multilanguageurls. Somehow we overlooked this add-on, but in principal this problem can be considered solved.

@erral: Both ways of handling multilingualism are perfectly valid and can be explained to the users. For me it is not so relevant, whether the improvements end up in the core or in an add-on. Latter ones are probably to get things started.

@MrTango: The main reason to apply workflow actions to all language versions was to maintain identical permissions across them. When working somewhere deeper in the tree, the actions should still work. We probably emphasize this, because this synced state is the norm case for us. When prefering to disable synchronization should be done explicitly by the user.

I also agree with you, that the user should be informed about the consequences. In daily business however, the user should be made aware of that, but should not care particularily about that either - there ist still normal editor work to be done. :wink:

We ought it would be better that we reach out for the indubitably larger p.a.m. crowd for better community support and longevity. Adopting the language fields solution but will in the end mean, that we are probably the only ones maintaining this solution and it is harder to catch errors. We are lucky to currently have a strong dev team at our university to even think about maintaining a solution alone - but that may change.