Recently I tried to localize MS WSS 3.0 site collection to unsupported language – Serbian, cyrillic (Serbia). LCID of this culture is 3098. This language is almost the same as existing latin localization to Serbian (Serbia) with LCID 2074. To get cyrillic version of resource files (resx), I installed Serbian latin language pack and searched wwwroot and 12 folders for “sr-latn-cs”, and took following files: core.sr-latn-cs.resx, resources.sr-latn-cs.resx, spadmin.sr-latn-cs.resx, spcore.sr-latn-cs.resx, spsearchadmin.sr-latn-cs.resx and wss.sr-latn-cs.resx
I got Search Center and language pack for it installed, so in an environment without search center, there should be some of these files missing.
To get sr-cyrl-cs.resx versions of theese files, I made small console application which parsed through xml files and replaced latin letters with cyrillic. Character swap is simple, and to parse xml I used following code:
static void Main(string[] args) { if (args.Length == 0) args = new string[]{"source", "destination"}; DirectoryInfo source = new DirectoryInfo(args[0]); foreach (FileInfo file in source.EnumerateFiles()) { XmlTextReader reader = new XmlTextReader(file.OpenText()); XmlDocument doc = new XmlDocument(); doc.Load(reader); reader.Close(); FileInfo dest = file.CopyTo(Path.Combine(args[1], file.Name.Replace(SourceLang, DestLang)), true); XmlDocument destination = new XmlDocument(); foreach (XmlNode node in doc.ChildNodes) { ParseChildren(node); } XmlTextWriter writer = new XmlTextWriter(dest.OpenWrite(), Encoding.Unicode); doc.Save(writer); writer.Close(); } } private static void ParseChildren(XmlNode sourceNode) { foreach (XmlNode node in sourceNode.ChildNodes) { switch (node.NodeType) { case XmlNodeType.Text: if (node.Name == "#text" && node.HasChildNodes == false && node.Value.Length > 0 && node.ParentNode.ParentNode.Name == "data") { if (!node.ParentNode.ParentNode.Attributes["name"].Value.ToUpper().Contains("accesskey".ToUpper()) && !node.ParentNode.ParentNode.Attributes["name"].Value.ToUpper().Contains("_AK".ToUpper())) { node.Value = SmartConvertToCyrillic(node.Value); } else { break; } } break; default: break; } if (node.HasChildNodes) ParseChildren(node); } } |
Important lines here are in case XmlNodeType.Text:
Those lines discriminate nodes which are values and need to be transliterated to Cyrillic.
When new resx files have been placed back to same respective folders where their sources for transliteration were found, then new language had to be enabled in Sharepoint.
Registry key HKEY_LOCAL_MACHINESOFTWAREMicrosoftShared ToolsWeb Server Extensions12.0InstalledLanguages contains string values whose names are LCID-s of installed languages, and value is version of satellite assembly of microsoft.sharepoint.intl.resources.dll in GAC. I added new string value named “3098” with value “12.0.0.0”. I even disassembled latin version of this dll and made cyrillic but I have what it seems unsolvable problem of impossibility to build that dll in Language version other than “Language neutral”, and I believe that is the key to enable localization of administration pages and parts of UI that is not localized.
Adding 3098 registry value enabled “Serbian Cyrillic” language in “New Web Site” SharePoint page, but to get templates for Team site, Blank, etc, it is necessary to make “3098” folder in C:Program FilesCommon FilesMicrosoft Sharedweb server extensions12TEMPLATE
I used 2074 folder as a template, and edited files in 2074/XML subfolder to get site templates in site creation wizard.
Newly created site was mostly localized – parts which are visible to users, but administrative pages are localized from satellite dll, and I did not succeed in building language specific version of dll to use it for this purpose. Also, this dll must be signed for SharePoint to use it, and to circumvent this I used delay sign, and then added exception for signature verification using gacutil.
This was very useful resource http://social.msdn.microsoft.com/Forums/en/sharepointdevelopmentprerelease/thread/023d1fb9-c415-405a-8944-c709c0cc8f01