Thursday, October 21, 2010

Sitecore Language Settings, what is your best practice?

After reading Alistair Deneys recent blog post about the Sitecore Dictionary, the whole issue about Sitecore and langguages started stirring in the back of my mind again. I’ve come across issues with it on a number of different occasions, and especially so in the past 2-3 years or so since my work as a Sitecore Consultant has taken me to many different environments across Europe.

To start with, just so we’re clear, there’s nothing inherently wrong with the way Sitecore handles multiple languages. Atleast not as far as I am aware. Various features have been discussed in the Sitecore Community in regards to feature requests and so on, and perhaps in summary this post could be interpreted as such as well.

My beef, if you will, is with how the language features are being used. And what best practices can be put in place, when implementing multi-lingual solutions.

As Alistair points out; “English” is not just english.   This becomes even more evident, when you pair the language with a flag (as Sitecore does, when selecting languages in the Content Editor for instance).

languages

The issue isn’t just with English though. I am pretty sure regionalization is an issue in many places around the world. I recently worked with a German Sitecore Partner, and right from the word “go”, they were dealing with multiple variations of German (de-DE, de-AT (Austria) and so on… I might remember it wrong with the code for Austria, I don’t use it much personally).

Even a small country such as Denmark could have a similar issue; da-GL, da-FO and so on.

Now, to get to my point.

In most cases that I have worked on, regionalization is being used for geographically specific information, while the bulk of the solution runs on the root language. English sites run on English, and only rarely will it become an issue whether we’re dealing with British English, American English or Australian English for that matter. Rarely – except for the fact that you can be almost positively sure your clients/editors will complain if the flag isn’t what they expect ;-)

Ideally (in my book), this would be configured in Sitecore as “en” (without any regional specifier), the flag would be neutral, and that would be that. Whenever regional information was in play, this would be further qualified with en-GB, en-US or en-AU and so on. When the site was configured to display “en-GB”, it would grab content in that language, and “fall back” to the root (stem, perhaps?) language when specific content wasn’t available.

Sadly, this is not how Sitecore works at present.

What we do these days, is install new languages via the Control Panel, and then configure Sitecore (well the site) to exclusively run on this new language. No obvious fallback mechanisms are in place (although I will discuss a few options at the bottom of this post).

Given no fallback mechanism, I would argue that one should always explicitly declare Language and Region whenever configuring new languages in Sitecore. Fortunately, Sitecore seems to agree because this is the default behaviour as well.

languageselection

And

languagedialog

Notice how, after selecting one of the (many) predefined languages, a full ISO code is generated. en-NZ in this example.

All good. This is also what I have been recommending my clients to follow, for as long as I can recall. Specify full languages, and then we’ll see if Sitecore in the future comes up with something new and clever in terms of language fallback and so on.

But to every exception, there is a rule… or is it the other way around? ;-))

While Sitecore will, by default, install for instance the Danish language as “da-DK” (fully regionalized), the actual content we get whenever Sitecore releases localized functionality will be only “da”. (just as “en” has always been just that, without regional information although with an American flag).

Here’s a view on a Conditional in the OMS. The Danish language has been installed using default Sitecore settings, and now we end up with this.

languagemess

Which was, I’m betting, not entirely what one expected. It certainly wasn’t what I expected, this much is certain :-)

And this is where I now pass the ball on to you, readers of this blog. What are your own experiences in this area? What do you recommend?

In summary, personally, I would love to see a fallback mechanism. This would allow me to run my regional sites in en-GB, and fall back to “en” where required. I’ve implemented a similar mechanism on some sites I’ve worked, although this was sort of messy and hooking into field renderers and whatnot.

Today, I would probably go about it differently. Thinking something like a Condition/Action to the effect of “when no language version exists set item language to “en””. Maybe this could be a feature at some point?

(and yes, I’ll be happy to mock up something to this effect and Share Source it, if there’s enough interest)

Your thoughts?

So what’s your view?

In the meantime

Here’s a fix to the above language issue. It will work whether you prefer your Danish (or whatever language) as “da” or “da-DK”, just reverse the statements. Alistair has his Revolver, I only have my standard tools… :P

You do this at your own risk however.

  • Backup your solution. Don’t tell me I didn’t warn you ;-)
  • Do a full publish
  • Stop your IIS
  • Open up your Sql Management Studio (Express, if that’s what you have)
  • Execute the following:

USE Sitecore_master
UPDATE UnversionedFields SET [Language]='da-DK' WHERE [Language]='da'
UPDATE VersionedFields SET [Language]='da-DK' WHERE [Language]='da'

After which, you are one step closer to avoiding language confusion later on. I’ve done exactly this on a solution I am working on, and have found no ill effects from this procedure. However, do keep in mind that directly working on the Sitecore database is not (and probably never will be) supported and you’re on your own.

Here’s the result, in my solution

languagesorted

Thursday, September 02, 2010

Disabling Lucene indexes (programatically)

Over the past 18 months or so, my work has taken me around a great deal of integration jobs. As those of you who follow this blog will know, integration of external data into Sitecore is something that has often been explored (and still is).

Recently, while faced with the task of importing, cross-referencing, IDTable mapping – about 14.000 items on a regular (scheduled) basis, I began to look for even further ways of improving integration performance.

One thing I put my attention towards, was entries like these in the log files, while the import was running:

3796 10:34:59 INFO  'ImportCategories' Executing
ManagedPoolThread #2 10:35:13 INFO  Starting update of index for the database 'master' (7 pending).
ManagedPoolThread #2 10:35:13 INFO  Update of index for the database 'master' done.
ManagedPoolThread #5 10:35:13 INFO  Starting update of index for the database 'master' (8 pending).
ManagedPoolThread #5 10:35:13 INFO  Update of index for the database 'master' done.
ManagedPoolThread #4 10:35:13 INFO  Starting update of index for the database 'master' (9 pending).
ManagedPoolThread #4 10:35:14 INFO  Update of index for the database 'master' done.
ManagedPoolThread #4 10:35:14 INFO  Starting update of index for the database 'master' (10 pending).
ManagedPoolThread #4 10:35:14 INFO  Update of index for the database 'master' done.
ManagedPoolThread #4 10:35:14 INFO  Starting update of index for the database 'master' (1 pending).
ManagedPoolThread #4 10:35:14 INFO  Update of index for the database 'master' done.
ManagedPoolThread #4 10:35:14 INFO  Starting update of index for the database 'master' (1 pending).
ManagedPoolThread #4 10:35:14 INFO  Update of index for the database 'master' done.

So basically, as the items were being imported, the indexer ran along in the background desperately trying to catch up. Well maybe not desperately… ;-)

I started looking around for an official way to disable these indexes. The idea being, disable the indexes – run the integration – enable them again and let them catch up. Has to be more effective yea?  Kind of like harddisk trashing otherwise, for those of you who still remember that phenomenon ;-)

Alex Shyba came up on top of most searches I did, describing how to disable Lucene indexes. The post is minded towards how to improve performance in the production environments however, and not to mention it’s well over a year old by now. Sitecore has been doing a lot of work on the Lucene/Sitecore search API, and odds are that things may have changed in the year that passed.

Besides, I needed a way to do it programatically.

I started looking into ways of achieving this. Basically exploring APIs, configuration settings, even considering … patching-via-reflection into the Sitecore Patching Configuration API to comment out sections of Sitecore Configuration *grin*.  Fortunately, before exploring any of these options in great detail, I had the common sense to approach the excellent Sitecore Support team to get a better (and more importantly, supported) solution. And fortunately, as it turns out, there is one. Clean, and very very simple. Thanks guys :-)

Sitecore.Configuration.Settings.Indexing.Enabled = false;

Couldn’t be simpler :-)

And the configuration equivalent exists as well, even if it is not shown in the 6.3 default web.config.

<setting name="Indexing.Enabled" value="false" />

Thursday, July 29, 2010

Sitecore 6.3, ComponentArt, WebForms For Marketers, and you

Apologies for the almost complete silence in this blog, but Real Life(tm) has been taking me for quite a spin these past months.

Just a quick heads-up, in case you run into the same issue that I just had.

After installing Sitecore 6.3 (100716), WebForms For Marketers 2.1 (100629), I ran into the following issue when attempting to edit values on a DropList Field.

WFM1

“Could not load file or assembly ‘ComponentArt.Web.UI, Version=2007.1.1617.2,Culture=neutral,PublicKeyToken=9bc9f846553156bb’ or one of its dependencies. HRESULT: 0x80131040”

It seems, Sitecore 6.3 comes with an upgraded version of the ComponentArt library, and version information on this new assembly reads 2010.1.2637.35. Also seems that WFFM is compiled against the previously distributed version, and fails because of it.

The fix I applied is relatively straight forward, and should work for you as well. Add a new assembly dependency mapping in your web.config as

<dependentAssembly>
  <assemblyIdentity name="ComponentArt.Web.UI" publicKeyToken="9bc9f846553156bb" />
  <bindingRedirect oldVersion="2007.1.1617.2" newVersion="2010.1.2637.35" />
</dependentAssembly>

And the problem goes away. I don’t know if the assembly versions are fully compatible, so don’t come banging on my door if this fix doesn’t make all potential problems go away ;-)   It appears to work like a charm here, in our solution.

Issue has been raised with Sitecore Support (331878).