Thursday, November 04, 2010

Approaching Language Fallback with Sitecore


Greetings,
Today I would like to present to you a prototype I have been working over past couple of weeks. This solution is built around a story about language fallback requirements of a fictitious multinational company. This is just an example of how you can approach similar requirement.
There is a number of alternative solutions that the Sitecore gurus from all over the world came up with, so you could naturally ask me: what is so special about this approach?


Well, here is a couple of things coming to my mind:
1. It is granular, field based solution.
2. It is consistent with the product architecture, relying on proven technologies such as Standard Values provider.
3. It is friendly to business users as they can clearly see what attributes falls back using familiar Content Editor UI.
4. This solution covers all major data access methods: direct API, Sitecore Query, Search via in-built Lucene engine.
I should mention, that Fast Query, is not respecting these settings, because this data access technology is simply not language aware. No language fallback solution that I’ve seen works with Fast Query.
5. It has minor impact on performance – I ran a few performance tests and confirmed it.
6. It is quite generic.
7. It is flexible.
8. It is plug and play.
Anyways, hope you find this useful. Any feedback (good or bad) is always welcome. Enjoy!
image

60 comments:

Unknown said...

Great Presentation and outstanding solution. Thank you!

Natalia

Unknown said...

Excellent video Alex! This approach will come in very handy. Thanks for putting this together.
--jeff

Brian Pedersen said...

Even though I am not fond of language fallbacks, it can be very handy. Your solution is very elegant. And nice video BTW :-)

Unknown said...

Thank you for the great feedback - I am hoping to record a more technical session soon. Stay tuned!

Gulle said...

Alex, outstanding solution. Did you publish the source code for this article?
Koen

Unknown said...

Thanks!

The source code is available on Shared Source:

http://trac.sitecore.net/LanguageFallback/browser/Trunk/Sitecore.SharedSource.PartialLanguageFallback

Let me know your thoughts on it...

Gulle said...

Hi Alex,
I installed your solution and changed the itemManager default provider but nothing changed (in the content editor).
I also see that the config you talk about in the video isn't the same as what's mentioned in the documention file (on the shared source lib).
Can you shed a light on this?
thx
Koen

Unknown said...

Hello Koen,

The project on tract actually contains two solutions. One is mine (field based), another one is item based. It looks like you have installed the item based solution. The field based does not have the documentation yet, but it is plug and play. All you need is the compiled assembly and a .config file. After that, modify the EnforceVersionPresenceTemplates as needed and use the "Fallback" buttons on the ribbon to configure the fallback for your templates. I covered this in the screencast. Let me know if you have questions.

Wooinvi said...

Thank very much Alex Shyba. It is useful for us.

David said...

Excellent solution!

I wish had chosen this approach 2 years ago. We had fallback requirements (on item base), we used a special workflow which copied the item versions in the local languages which is erronous and resource intensive and slows down publication and... and ...

Unknown said...

Excellent solution and solves most of my clients needs for languages.

Is there a way to allow the "Preview" mode to show fallback values? Currently only the the fields that have been overridden with specific values show in the "Preview" window.

Gulle said...

Hi Alex,

I'm trying to install the fallback solution on Sitecore 6.4 but it generates an 503 error when I included your config file. Not sure what's happening.

Koen

Unknown said...

Hi Koen,

Can you confirm you checked out the latest codebase from shared source? There was a problem with circular reference in 6.4 that I fixed some time ago.

If you can confirm, could you please send me your configuration file?

Unknown said...

Monty: I have an update for the preview problem. Can you shoot me an email? AS at sc net

Rob said...

I'm having an issue getting it to work properly, it appears to work within sitecore, but when I navigate to the site, I'm not seeing any default language content. I posted in the forum, but I haven't got a response yet. Love the solution, just wish I could get it to work.

Unknown said...

Hi Rob,

I've updated the code recently (8 days ago) to support this. This update included both changes in the config file and code.

Please make sure you run the latest version of the code and configuration. Let me know if this does not help.

-Alex

Asif Maniar said...

Hi Alex,
Is there a tech document/video available?

Thanks
Asif

Rob said...

Thanks for the reply, I downloaded the new version, but I'm still having issues. I might be having issues with the necessary configuration in the web.config. Could you post the code that needs to be added to the web.config?

Thanks for your help.

Unknown said...

Rob,

All the configuration needed is supplied within the auto include config file.

Can you email me (AS at sitecore dot net) and send your web.config, along with the exact version you use?

Mick said...

I'm using the new Language Fallback Module, and want to know that if the item being requested does not have the current language version, and does not have a fallback, will the item returned be null? At the moment, I'm still being returned an item, but if I cast as StubItem, that is null?

Pilko said...

We have a multi-site implementation using version SiteCore 6.4.1 (rev. 110324) using .Net framework 4. I have installed the Sitecore.SharedSource.PartialLanguageFallback package. Always Enforce Fallback is working as expected, but I am unable to get Enable fallback If configured to work either in the editor or the published sites. We have a multisite set up and I have set enableFallback="true" for the shell database as well as the one I want to fallback. Do you have any ideas as to why it is not working?

Unknown said...

Pilko - can you send me an email with your configuration files (web.config and all from App_Config/Include)?

My initials@sitecore.net

freddie said...

Alex, I've just tried to install your Language Fallback Module into my Sitecore 6.2 site but I got two "Field not found: 'Sitecore.FieldIDs.Source'" during the install. I get the same error whenever I click any item in the content tree.

No one else seems to have had any problems getting past the install.

Any thoughts.

thanks

Unknown said...

Hi Mick,

If "enforceLanguagePresence" is enabled for the context website and "Fallback.EnforceVersionPresenceTemplates" settings contains the item template GUID, then item with no language version will be returned as null.

Sounds like this feature is not enabled on your side. So to check whether an item is "translated" or not, do Item.Versions.Count > 0

Hope this helps

Unknown said...

Freddie,

The latest version on Trac is built for 6.4, you have a conflict, because the Source property is missing in 6.2.

Try removing line 84 from FallbackLanguageManager.cs and rebuild the code:

if(field.ID.Equals(FieldIDs.Source)) return false;

I had to add this line to avoid infinite code execution in 6.4 and later.

Hope it helps.

Parit said...

Hi Alex,

I think your solution is ideal for my requirements, but I am having issues building the current version. I am on Sitecore 6.2, so needed to rebuild the code to avoid the issue raised by Freddie. However on building the current version against the Sitecore 6.2 dll's I came across the following build issues on the FallbackEditorFormatter:

1. Arguments does not exist in the current context on Arguments.Item.Fields[field.ItemField.ID];

2. InheritsValueFromOtherItem does not exist on itemField.InheritsValueFromOtherItem.

I assume Arguments can be replaced with Args, but not sure about the InheritsValueFromOtherItem property.

Thanks,

Parit

Chälli said...

Hi Alex

do you know if the fallback works on 6.5? I added the project, put the config file into the include folder and added a template guid to EnforceVersionPresenceTemplates but I just don't see any change on the desktop... do I need to make additional changes? update the IDs in constants? execute SetupFallbackCommand somehow?

cheers
Michael

PS: I just downloaded the project.. so it should be the most current version

Chälli said...

I installed the package for 6.4 and it works almost perfects. the only problem (sadly a killer) is, that I get an "Object reference not set to an instance of an object." on "Field itemField = Arguments.Item.Fields[field.ItemField.ID];" (line 48 of Shell/EditorFormatter.cs) whenever I open a rendering controls edit window... any ideas about that?

jamesbrett said...

Hi Alex

I've installed the module but I'm having problem when the fallback language is set to a language other than en. All of the content will be initially created using the en-GB locale then language variants created thereafter. If I set the fallback language to en it works fine but if I set the fallback language to en-GB the IIS worker process stops on the server due to a stack overflow exception.

Does this have anything to do with the fact all system items (inc data templates) are created using the en locale and not en-GB?

Cheers
James

Unknown said...

James,

Yeah sounds like infinite loop.
I just tried the scenario but can't repro on the latest version on 6.5. Set 'en' to fallback to 'en-GB', even tried setting 'en-GB' to fallback to 'en' at the same time, which is a bad idea, but still does not break.

Send me a copy of your serialized content tree so I can repro at: AS at sc dot net.

kelvin t said...

paHi Alex,

Great video! on top of all these...
If i have a user that create all this pages in japanese language on a eng version.. which is totally wrong way of doing.. is there anyway we can change the version to japanese and we still keep the contents migrated?:) hope to hear from your expertise. kelvin.tang@sungard.com

Unknown said...

kelvin,

You would need to have this content transferred from one language version to another via a script. I think I have one. Email me at AS at sitecore do net.

-alex

Pilko said...

Alex, been using this for a couple of months, excellent, thanks, all fields throughout the site need to be set to "Enable Fallback If Configured" I tried using a standard value on "/sitecore/Templates/System/Templates/Template field" which appears to generate a recursive loop. Any other idea's of how to do this so that we don't forget to set this value when creating new fields?
Duncan

Unknown said...

After configuring everything I only get 2 buttons in the Fallback section on my template items and fields. I have Enable Fallback and Don't Enable Fallback but I don't have Enforce Fallback and Don't Enforce Fallback. If I go to my template field, I also don't have the Enforce Fallback checkbox. enforceVersionPresense="true" is on my website and I un-commented the lines in the App_Config file needed for specifying "EnforceVersionPresenceTemplates".

Unknown said...

Hi Frank, that's expected. The enforce feature was deprecated. I did not see any value in it and it was impacting performance.

-alex

Dobryak said...

Hi, Alex.
After update from Sitecore 6.3 to Sitecore 6.5 Partial Language Fallback stopped working at all. Could you confirm, that it is working in Sitecore 6.5? We've also tried to install it on clean Sitecore 6.5 - and still no luck

Unknown said...

Hi Dobryak,

What exact rev. of 6.5 are you using?

Also, is it the latest build of PLF?

Dobryak said...

Sitecore.NET 6.5.0 (rev. 111230).

First try was to use package attached in trac - it was not working.
Than, we've checked out sources from trac and built them anew - still no luck

Josh Jenkins said...

I'm having the same experience as Dobryak, Sitecore 6.5 Rev 111230

Fresh install downloaded from Trac. Enabled Fallback on the fields but not seeing it fallback when playing with lang context

Josh Jenkins said...

I'm having the same issue as Dobryak, running the same version of Sitecore. I am fairly certain I have things configured correctly but I'm not seeing any fallback happening.

Anything I should be looking at?

Liz at Verndale said...

Similarly to the last few comments here, I'm not seeing fallback take effect nor any indicators that anything is falling back. The site is 6.5.0, rev 111230.

I installed the package and didn't make any changes to the config file. The new ribbon settings are there, as well as the checkboxes on the fields to specify if fallback is enabled.

But when I add a new language version, nothing is prefilled and there is no gray fallback designation.

Additionally, since you removed the 'enforce' options, I'm a little confused about how you designate whether an item appears at all anymore if there is no version for it in a language. I assume the EnforceVersionPresenceTemplates setting has something to do with it?

Is there documentation somewhere that gives the very basics of how to simply get this up and running?

Our client is really excited about this option and we are in the midst of development now, so any pointers would be greatly appreciated!

Thanks, Liz

Unknown said...

Sorry for not responding so long. I've just tried it on 6.5.0x111230, and it's working fine. Please make sure that when you enable the fallback checkbox on a field definition item, you do that on the same language version that is supposed to fallback. I.e. if en-CA falls back to 'en', then you need to create a en-CA version of the template definition item and enable the flag there, not on the 'en' version. I've added this feature to support different fallback settings for different languages instead of having one global fallback setting per field. Should have documented that, and actually, should have made it configurable. Apologies for the trouble.

Liz at Verndale said...

Thanks for the update Alex! I have tried creating a GB version of my template and setting the fallback checkboxes there instead and sure enough, it started working. I hadn't considered that.

One thing though, I'm still not seeing any gray [fallback value] text near each field that is set to fallback and hasn't been overridden. Is that normal?

Finally, could you just give me a pointer on how to set if an item shouldn't appear at all on the site if a version does in the language does not exist?

Much appreciated!
Liz

Liz at Verndale said...

Alex, setting the checkboxes on the language version of the template was indeed what had to happen. I am getting it to fallback now.

Two more questions/comments.

First, although the fields are falling back, I don't see any gray text flagging that it is happening, as you remarked that you had added in your update blog [fallback value].

Second, as in your Japanese example, I want to make sure certain items don't show up at all if they don't have a version in that language (won't show in navigation, etc). How exactly do you do that with this?

All your time in answering is much appreciated!

Liz

Unknown said...

Liz,

The [fallback value] label works for me on 6.5.0 rev. 111230, Please make sure that the values are actually fallback values by resetting them. If it does not work, try stepping through the code and explore it in detail, as I cannot reproduce. This is the processor where the magic should happen with the label:
Sitecore.SharedSource.PartialLanguageFallback.Pipelines.RenderContentEditor.CustomRenderSkinedContentEditor

Regarding the second question, all you need to do is enable the 'enforceVersionPresence' setting on your site definition in web.config. See Sitecore.SharedSource.PartialLanguageFallback.config for example.
Note that your site name can be different.

Also, you will need to put the pipe separated list of template GUIDs into the "Fallback.EnforceVersionPresenceTemplates" setting. See the comment above the setting.

Hope it helps.

Dobryak said...

Yes, this helped. Though I found it frustrating to create 15 language versions of 300 fields :).

Unknown said...

Hi Dobryak,

Well, the ribbon button would create the language version for you, so you only need to do it once per language :-)
If you select a folder with templates and click "enable fallback", the logic will process all fields within all the templates in that folder, and will create a language version in the selected language before enabling the fallback.

Also, in the latest commit I've added a setting controlling this behavior. It is called "Fallback.VaryFallbackSettingsPerLanguage" and disabled by default.
With this feature disabled you now don't have to create language version for every field.
If you want to have language specific fallback settings, you will need to enable this setting and create language versions for the fields the same way as I described above.

Hope this helps.

Dobryak said...

Yes, this helps a lot (but a little bit late) :)

Liz at Verndale said...

Hi Alex,

This code:

GetContentEditorSkinArgs args2 = new GetContentEditorSkinArgs(args.Item, args.Sections);
using (new LongRunningOperationWatcher(Settings.Profiling.RenderFieldThreshold, "GetContentEditorSkin pipeline", new string[0]))
{
CorePipeline.Run("getContentEditorSkin", args2);
}

string skin = args2.Skin;

always seems to result in a null args2.Skin, which is why it isn't rendering any label text to designate whether it is fallback or not.

I don't understand enough about how the sitecore items are rendered in the cms editor to debug it much further than there....

Thanks, Liz

Dobryak said...

Hello, Alex...
After we fixed the issue, with no fallbacked languages at all, now we face another problem: if Supported databases contains also web database - Partial Language fallback begin to work as Full Language fallback (even if no item language version is present - content of an item is shown from fallback language). After removal of web database from supported databases - we face another issue: if no changes was made to fallbacked field - no data for this field is delivered to web database, thus, you need to make changes to a field to be 100% sure that item is delivered.

Dobryak said...

A little update - Partial Language Fallback begin performing like this if target site in fallback config is patched with enableFallback. If it is not patched - than on frontend no data is shown for not edited fields, though in backend, in web database fields seems to be filled by fallback values

Natalie said...

Hi Alex,

I am trying to implement the solution in my multilingual website with English and Japanese. I now ran into an issue that the website displays Japanese content on the english website when the english version is not created. Any ideas on how to solve this?

Unknown said...

Hi Alex,

Could you help me with some technical document on how to implement the language fallback, we installed the package but we haven't been able to make it work.

Do we have to make any changes on our code to read the data?

Chälli said...

Hi Alex

I'm a thankful user of your solution and just installed the newest version together with sitecore 6.6.

I came across a problem with versioned media-items that I did not have with the version from about a year ago. When I load an image in a language where it does not have a version I get an exception on each second request.

The UTC time represented when the offset is applied must be between year 0 and 10,000.
Parameter name: offset
in: Sitecore.Resources.Media.Streaming.Preconditions.IfModifiedSincePrecondition.CheckRequestPreconditionAndSetResponseStatus(HttpContext context) +124

The problem seems to be that this check uses Item.Statistics.Updated and this does not fall back as internally the "Updated" gets its value via GetValue(false, false) => no standard-values and no default-values allowed). (I added an exception to your checks for system fields, so that item["__Update"] falls back correctly)

Due to this fact, the fallback is currently unusable for media items...

do you have any idea/plan on how to solve this?

I'm currently also in contact with sitecore support - if I get a solution from their side, I'll post it here.

Thanks for the module anyway - it absolutely rocks! makes Sitecore so much easier to sell ;)

Cheers,
Michael

Unknown said...

Liz - the fix to your issue is to hide Standard Fields in the content editor (View ribbon tab -> Standard Fields). The args2.Skin is null because when Standard Fields are enabled in the content editor, the first processor in the getContentEditorSkin pipeline (Sitecore.Shell.Applications.ContentEditor.Pipelines.GetContentEditorSkin.ShowStandardFields) aborts the pipeline, causing the Skin property to never be populated.

Unknown said...

I am having the exact same problem as Chälli, on every second request the error comes up. The thing is, if I deploy to the develop or live server, no problems whatsoever, so I guess it must be a server setting of some kind, a misinterpretation of the dot or comma for the miliseconds or something?

Anonymous said...

Hi Alex,

I was wondering if this could be used for the following scenario.

We will have 3 sites, Americas, Europe and Asia. Asia will have languages such as simplified Chinese, English, etc.. Europe would have Spanish, eng-GB, eng-us, Americas would have eng-us, Portuguese etc...

We were hoping if there was anyway to set it up to fallback all sites to en assuming one of the sites was set as the master language.

The reason for the separate sites is the users would be in charge of a region/site and thought doing this would be easier for them to manage


Thanks

Anonymous said...

Hi Alex,

I have the same issue as Marcelo, we installed the module from Sitecore Marketplace and followed the instructions in the documentation but it didn't work. We start to have now the dropdown for language fallback in the languages but nothing more. no checkboxes or new new config section in the Ribbon even after installing the PartialLanguageFallback dll.

Any advice on this? we tried this using Sitecore 6.6

Thank you

Prasanna said...

Hi Alez,
I'm working in Sitecore.NET 6.6.0 (rev. 130529) and using the fallback approach. The problem i'm facing is , if the site is with the .com instance the fall back approach is not working ex www.xxx.com/en-ca and www.xxx.com.ar/es-ar are displaying a blank page with $name. The same works fine for www.xxxx.ca/en-ca or www.xxx.ar/es-ar

Unknown said...

Hi Prasanna,

Could you please make sure all fallback-enabled site have enableFallback="true" setting on corresponding site definitions in configuration.

-alex