Multiple language support without variations

My site uses variations to publish Arabic and English content. This works well for all pages except for the login page, which sits in the root site at “/pages/login.aspx” and uses forms authentication.

I have implemented a custom language switch which allows the culture to be switched dynamically. This is done by using a custom code-behind page for the layout.

First, I override the OnPreInit to set the culture manually:

   1: /// <summary>



   2: /// Override to set UI culture according to query string or client settings.



   3: /// </summary>



   4: /// <param name="e">An <see cref="T:System.EventArgs"/> that contains the event data.



   5: /// </param>



   6: protected override void OnPreInit(EventArgs e)



   7: {



   8:     Thread.CurrentThread.CurrentCulture = 



   9:         Thread.CurrentThread.CurrentUICulture = CurrentCulture;



  10: }






I then get culture by query string or by client settings as:





   1: /// <summary>



   2: /// Gets or sets the current culture by query string or client settings.



   3: /// </summary>



   4: /// <returns>The current <see cref="CultureInfo"/>.</returns>



   5: protected virtual CultureInfo CurrentCulture



   6: {



   7:     get



   8:     {



   9:         if (currentCulture == null)



  10:         {



  11:             currentCulture = !string.IsNullOrEmpty(Page.Request.QueryString["lang"])



  12:                                  ? new CultureInfo(Page.Request.QueryString["lang"])



  13:                                  : new CultureInfo(Page.Request.UserLanguages[0]);



  14:         }



  15:         return currentCulture;



  16:     }



  17:     set { currentCulture = value; }



  18: }




Finally, I populate my dropdown list of choices as:





   1: /// <summary>



   2: /// Gets the variations of the system.



   3: /// </summary>



   4: /// <value>The variations.</value>



   5: private static SPListItem[] Variations



   6: {



   7:     get



   8:     {



   9:         if (variations == null)



  10:         {



  11:             using (SPSite site = new SPSite(SPContext.Current.Site.ID))



  12:             {



  13:                 using (SPWeb web = site.OpenWeb(SPContext.Current.Site.RootWeb.ID))



  14:                 {



  15:                     SPList list = web.Lists[new Guid(web.AllProperties["_VarLabelsListId"].ToString())];



  16:                     List<SPListItem> items = new List<SPListItem>(list.ItemCount);



  17:                     for (int step = 0; step < list.ItemCount; step++)



  18:                     {



  19:                         items.Add(list.Items[step]);



  20:                     }



  21:                     variations = items.ToArray();



  22:                 }



  23:             }



  24:         }



  25:         return variations;



  26:     }



  27: }



  28:  



  29: /// <summary>



  30: /// Override to populate the variation selection drop down list.



  31: /// </summary>



  32: /// <param name="e">



  33: /// The <see cref="T:System.EventArgs"/> object that contains the event data. 



  34: /// </param>



  35: protected override void OnLoad(EventArgs e)



  36: {



  37:     base.OnLoad(e);



  38:     SPSecurity.RunWithElevatedPrivileges(() => BindVariations(ddlVariations));



  39:     ddlVariations.Attributes.Add("onchange", "window.location.href='?lang='+this.options[this.selectedIndex].value");



  40: }



  41:  



  42: /// <summary>



  43: /// Binds the variations from the language variations to a list control.



  44: /// </summary>



  45: /// <param name="list">The list.</param>



  46: private void BindVariations(ListControl list)



  47: {



  48:     bool selected = false;



  49:     foreach (SPListItem variation in Variations)



  50:     {



  51:         ListItem item = new ListItem(variation["ows_Description"].ToString(),



  52:                                      variation["ows_Language"].ToString().ToLowerInvariant());



  53:         if (string.Compare(variation["ows_Language"].ToString(),



  54:                            CurrentCulture.ToString(),



  55:                            true) == 0 &&



  56:             !selected)



  57:         {



  58:             item.Selected = true;



  59:             selected = true;



  60:         }



  61:         list.Items.Add(item);



  62:     }



  63:     if (!selected)



  64:     {



  65:         //Exact culture not found. Use language, not culture as "en-US" == "en-GB"



  66:         string language = CurrentCulture.TwoLetterISOLanguageName;



  67:         foreach (ListItem item in list.Items)



  68:         {



  69:             if (item.Value.StartsWith(language + "-"))



  70:             {



  71:                 item.Selected = true;



  72:                 break;



  73:             }



  74:         }



  75:     }



  76: }





In the end, I will move the OnPreInit code into the master page or a HTTP module and encapsulate the variations list into a control, but you get the point from the code above. The benefit of using this in a HTTP module would be translation of system pages without usage of variations, but that’s another story.

0 comments: