Ticket #1626 (closed feature request: fixed)

Opened 2 months ago

Last modified 1 month ago

Add automated/transparent MultiLang workflow support with multiple fallback languages

Reported by: jval Assigned to: jval
Priority: major Milestone: 8.09.8 Ragnaroek
Component: MidCOM core Version: 8.09 Ragnaroek
Keywords: Cc:

Description

The MultiLang feature in Ragnaroek has only one fallback language and the default workflow has the concept of one certain master language (content is always created in the same specific language and translated in others).

I needed a different kind of MultiLang where I can create content in any language. Different areas of the site have different languages and there's no common language which could be used as a master language in the whole site. Also it should be possible to create the initial content in any language, so the workflow should be automated/transparent instead of the default master language one.

Unfortunately it is too hard to actually implement this correctly in midgard-core. It is too hard to actually have multiple fallback languages. That's because the internal SQL queries must return only the best matches (the MultiLang is basically impemented in SQL level) and adding more fallback languages to the queries would complicate them a lot... (I wasn't sure if it's impossible but at least it would be very complicated to do and doing it would risk introducing new hard to solve bugs.)

It seems the best practical way to solve this is to just automatically copy the content to all site's languages. I first tried to copy the best matching content to lang0, which worked, but deleting the objects become impossible then (MidCOM doesn't understand that even though the content is only in lang0, it should be deleted from langX so that when content is gone, the fallback is also gone as otherwise the content would just show indefinitely - the actual delete would have been possible to implement but the problem was toolbar and components which couldn't of course understand that they should provide the delete links/forms...). I implemented it as an external feature but for easier usage and better maintenance, it should be added to MidCOM itself.

This unfortunately can't be a component because default_lang needs to be set very early in the request to make sure everything works correctly in all circumstances. Well this *can* be a purecode component (or a similar watcher could be implemented but that would not handle deletes automatically) of course but then its usage requires multiple lines of code (would be almost the same as not having this in MidCOM). Easiest usage requires that this feature is a midcom.core service which is added to midcom_config and activated automatically in midcom.php when enabled. This is not something absolutely necessary to have in midcom.core but it seems having it there is the best option (I bet the code is simpler this way than as a component - also this code is simpler/shorter/faster and more bullet-proof than if the same functionality is done as a watcher - with this code this basically goes straight to Midgard API and therefore belongs to midcom.core). This is purely a new feature and if this is not used, the *only* line of code being executed is the check for its midcom_config setting (one if clause which checks if the setting has something or is false/empty).

Change History

02/02/10 17:45:42 changed by jval

  • status changed from new to closed.
  • resolution set to fixed.

(In [24971]) Add automated/transparent MultiLang? workflow support with multiple fallback languages, fixes #1626

02/02/10 18:14:46 changed by jval

(In [24972]) Parameter domains use dots, use here too, refs #1626

02/03/10 09:11:31 changed by jval

Actually automated lang0 syncing (using lang0 as a fallback where best match is placed) would have also been possible if deletions would have been per language only and last langX delete would have always deleted full objects (possible with action_delete and action_deleted callbacks).

I tried to create the workflow in a way deletes affect full objects and that was impossible with that syncing solution because MidCOM can't see the object in langX if object doesn't have a langX translation. Well, not fully impossible as it would have worked from languages where translation exists. (It would have been a bit unclear but it would have worked in practice because translation would exist in practice in those cases usually.)

If someone actually needs that kind of workflow, we can add new method(s) to the class for that purpose. You know, we now have "auto" workflow but we could also have e.g. "lang0" workflow in the future.

Now that I think about this, it seems there are multiple different kind of workflows which are possible. There are at least two different kind of fallback handling possibilities (in addition to the built-in one). Then there are at least two different kind of delete handling possibilities (delete only translation vs. delete full object).

Some of the workflows would require a bit more complex code to be written. For example when deleting a full object, it should always be done in a way its children are all also deleted as full objects (otherwise the database is left in a state where there are active objects without parents). Normally midcom.admin.folder (and Asgard) handle those recursive deletions but in this case as the delete workflow would be different/special, it would have to be handled in the workflow itself I guess. (The "lang0" workflow would need this kind of solution in both delete handling cases because that workflow would not have all translations in the current language in all situations.)

Clearly implementing all possibilities would take a bit of time. I guess it makes no sense to do it without actual real life need. If there is a need it's quite fast to implement a new worklow to the class then because it's just one workflow then in question.

It seems the worklow I ended up implementing is indeed the simplest one. We need no special delete handling code because the language always has all the objects visible and all objects are deleted recursively in normal MidCOM operations.

02/03/10 11:03:42 changed by jval

(In [24976]) Add multilang auto workflow support to fi.protie.navigation's untranslated CSS class handling, refs #1626

02/03/10 11:09:51 changed by jval

(In [24977]) Use the service's own get_lang() because we want to get the empty string instead of null in lang0 case (lang0 usage is discouraged but this way it should work if used), refs #1626

02/03/10 12:13:49 changed by jval

  • status changed from closed to reopened.
  • resolution deleted.

I think I need to reconsider the implementation of deletes because it seems it adds difficulty a lot when lang0 is not used. You know, page elements etc. don't function like you'd assume because they are normally in lang0 and setting default_lang masks them. (Actually I still got style working but root topic was strangely found but incorrect...) Of course we could put everything into correct lang but I don't like the idea of duplicating everything because of this. It might make more sense to handle lang0 a bit similarly as SG0 is handled regarding the sitegroups functionality.

Reopening to state it clearly that this feature/ticket is not yet finished. Implementation (and even behavior) might still change a bit. I need to make some tests and decide what is the best implementation.

02/03/10 12:17:43 changed by jval

(In [24978]) Don't change default_lang but instead change lang to default_lang when deleting (same end effect but allows lang0 to be used like SG0 is used with sitegroups), refs #1626

02/03/10 13:07:45 changed by jval

(In [24980]) Add generic get_default_lang() and use it, refs #1626

02/03/10 13:52:46 changed by jval

(In [24982]) Rename reset_lang() to set_lang_back() because we actually want to return to latest lang (which needs to be set by calling set_lang_back() first) instead of initial lang (although in practice they are of course the same). Move set_lang_back() lower so that we have the event handlers ordered logically in the class. As set_lang_back() is now called always before it's used, remove reset_lang() call from the auto workflow method as it's no longer needed. Refs #1626

02/03/10 14:31:32 changed by jval

  • status changed from reopened to closed.
  • resolution set to fixed.

Ok, this implementation seems to work and is still simple (and simpler to use than the original one). Feature is complete.

02/03/10 15:11:58 changed by jval

I realized that if delete fails, lang is left to lang0. I thought about it and it seems it's still better this way because this solution solved a real life problem and that problem is more like a theoretic one.

It's theoretic because this version of Midgard doesn't check for privileges internally except for sitegroup boundary crossing. Basically delete can fail only if the object doesn't really exist or is somehow corrupted. MidCOM checks all those cases before it tries to delete objects so in practice we shouldn't ever get to the point where delete fails internally.

I also thought about whether it is better to change lang to default_lang or the other way and it seems the current implementation is better because lang0 is used for the actual site and langX for content. It is a much bigger problem if the site's language changes than if content language changes. (Because if site language changes, MidCOM's finish stage would not be executed.)

Although this is not perfect it seems this is the best solution in practice. This ticket itself is a solution which is the best in practice but not perfect. :)

02/03/10 18:25:22 changed by jval

  • status changed from closed to reopened.
  • resolution deleted.

It seems using default_lang like SG0 is used with sitegroups (master one which can control everything) is not something which can be relied on.

I guess it should be done the other way then: default_lang should be changed to lang before delete() and back afterwards. (This means lang needs to be set back also because of the way set_default_lang() works.)

Even though I wrote above that doing it that way might be a bit problematic it shouldn't be an issue in real life.

Reopening because feature is not complete yet because of this. It works with current Midgard version but should be changed so that it works with future versions as well.

02/03/10 18:40:50 changed by jval

  • status changed from reopened to closed.
  • resolution set to fixed.

(In [24995]) Change delete implementation, fixes #1626