In-page localization using a webcontrol derived from the multiview control

Last post 02-23-2007 1:43 PM by himawari. 5 replies.

Sort Posts:

  • In-page localization using a webcontrol derived from the multiview control

    02-16-2007, 3:22 PM
    • Loading...
    • himawari
    • Joined on 07-19-2006, 3:26 PM
    • Vancouver, BC
    • Posts 63

    Hi All,

     

    I am fairly new to localization in ASP.NET 2.0 and I would like to get some feedback and recommendations from the experts regarding my current implementation.

     

    My company is in the process of migrating an existing, mostly static website to the ASP.NET 2.0 platform. The current site has three languages—English, Traditional Chinese and Simplified Chinese. The site has about 30 static pages for each language. The maintenance of the site is a nightmare as you could imagine—one copy of the same content for each language. The make thing worse, the previous developer did not employ a template solution (only SOME server-side includes, even the use of them are not very consistent), etc. I have designed to redo the site from ground up. I will be the only one updating the site (as the update is not overly frequent) and I want to make the site much more manageable for myself.  Instead of updating three files and uploading each of them whenever I have updates, I want to be able to update only one file; if I need to change the overall look and feel, I want to be able to modify only one file and the CSS to achieve that. SEO would be important to us as well. A full-blown, database driven CMS solution, however, may be a little overkill for this project.

     

    The first challenge I have is to create a template for the site. I am using the Master Page feature. For SEO purpose, I want the URL for each language page to be different. I have decided to pass the language code as a Query String and use UrlRewrite to create a SEO friendly URL. I won’t get into details regarding the set up of the UrlRewrite. I am using the UrlRewriting.net component and you can find more information about the project at 

     

    http://www.urlrewriting.net/

     

    I set up a rule so that

     

    http://www.blah-travelagency.com/zh-TW/contact-us.aspx

     

    will be rewritten as

     

    http://blah-travelagency.com/contact-us.aspx?lang=zh-TW

     

    I also have a Utility Method to ensure the specified culture is supported and well-formed.

     

    The supported cultures are stored as a comma separated string in the web.config AppSetting section. English would be the fall-back culture so I need to specify English (Canada), Traditional Chinese and Simplied Chinese as supported.

     

     

    <appSettings>
    <add key="supportedCultures" value="en-CA,zh-TW,zh-CN"/>
    </appSettings>
    
     

    The code to ensure the specified culture is supported is as follows:

     

    public static bool IsSupportedCulture(string cultureName)
    {
    	StringCollection sc = new StringCollection();
    	sc.AddRange(WebConfigurationManager.AppSettings["supportedCultures"].Split(','));
    	return sc.Contains(cultureName);
    }
    
      

     

    Within the PreRender Method of my masterpage code, I added the following code to assign the desired culture to the current thread:

     

      

    string culture = Request.QueryString["lang"];
    
    System.Globalization.CultureInfo lang;
    if (CultureUtilities.IsSupportedCulture(culture))
    {
    	lang = new System.Globalization.CultureInfo(culture);
    	System.Threading.Thread.CurrentThread.CurrentCulture = lang;
    	System.Threading.Thread.CurrentThread.CurrentUICulture = lang;
    }
     

     

    I then use explicit localization to assign Localized Menu Text, NavigateUrl, etc from the Global Resource.

     

    This approach allows me to auto detect the user’s preference when a language is not explicitly set, but also allows me to explicitly set the UI culture as necessary (by using a querystring / url rewrite).

     

    Unfortunately, the resource editor in VS 2005 doesn’t handle large amount of text very well. While I am planning to use a SQL server as the backend for the tours information, I think the overhead of creating a CMS for the relatively static pages such as visa information, contact us may be too much. True I can leave those pages as three separate versions but I am sure there are better ways than that.

     

    I looked at the list of WebControls panel and I felt the MultiView control might be a viable workaround for my problem.

     

    I want to be able create Views based on the localization and paste the localized text into the appropriate view. I also need the mechanism to auto detect the culture setting or set the culture setting explicitly as needed.

     

    The only logic we need to change is to activate the appropriate culture view. My solution is geared towards static html code so I disable the viewstate for this control. My implementation is as follows:

     

     

    1    using System;
    2    using System.Collections.Generic;
    3    using System.ComponentModel;
    4    using System.Text;
    5    using System.Web;
    6    using System.Web.UI;
    7    using System.Web.UI.WebControls;
    8    using System.Globalization;
    9    
    10   namespace Dtkh.CompanionHolidays.WebControls
    11   {
    12   	[ToolboxData(<{0}:LocalizedContent runat=server></{0}:LocalizedContent>")]
    13   	public class LocalizedContent : MultiView
    14   	{
    15   		/// <summary>
    16   		/// Default contructor; initialize the LocalizeContent class to its default values
    17   		/// </summary>
    18   		public LocalizedContent()
    19   		{
    20   			_cultureName = "";
    21   			_invariantCultureViewName = "default";
    22   			_autoCultureDetection = true;
    23   			this.EnableViewState = false;
    24   		}
    25   
    26   		/// <summary>
    27   		/// True if culture auto detection is enable. The _currentName will be set accordingly to CurrentUICulture of the current thread.
    28   		/// </summary>
    29   		protected bool _autoCultureDetection;
    30   		/// <summary>
    31   		/// Name of the region code;
    32   		/// </summary>
    33   		protected string _cultureName;
    34   		/// <summary>
    35   		/// the default, fallback view
    36   		/// </summary>
    37   		protected string _invariantCultureViewName;
    38   
    39   		public string InvariantCultureViewName
    40   		{
    41   			get
    42   			{
    43   				return _invariantCultureViewName;
    44   			}
    45   			set
    46   			{
    47   				_invariantCultureViewName = value;
    48   			}
    49   		}
    50   
    51   		public bool AutoCultureDetection
    52   		{
    53   			get
    54   			{
    55   				return _autoCultureDetection;
    56   			}
    57   			set
    58   			{
    59   				_autoCultureDetection = value;
    60   			}
    61   		}
    62   
    63   		public string CultureName
    64   		{
    65   			get
    66   			{
    67   				return _cultureName;
    68   			}
    69   			set
    70   			{
    71   				_cultureName = value;
    72   			}
    73   		}
    74   
    75   
    76   		/// <summary>
    77   		/// A utility method to set the active view by name instead of index
    78   		/// </summary>
    79   		/// <param name="viewName">Set the active view to the specified view by its name</param>
    80   		/// <returns>true when the view specified is found; false otherwise</returns>
    81   		protected bool SwitchToView(string viewName)
    82   		{
    83   			View view = this.FindControl(viewName) as View;
    84   			if (view != null)
    85   			{
    86   				this.SetActiveView(view);
    87   				return true;
    88   			}
    89   			else
    90   			{
    91   				return false;
    92   			}
    93   		}
    94   
    95   		/// <summary>
    96   		/// Set the active view by the _cultureName variable
    97   		/// </summary>
    98   		protected void SetViewByCulture()
    99   		{
    100  			if (_autoCultureDetection)
    101  			{
    102  				_cultureName = System.Threading.Thread.CurrentThread.CurrentUICulture.ToString();
    103  			}
    104  			if (!(SwitchToView(_cultureName.Replace('-','_')))) {
    105  				SwitchToView(_invariantCultureViewName);
    106  			}
    107  		}
    108  
    109  		protected override void Render(HtmlTextWriter output)
    110  		{
    111  			// set the view to the appropriate language
    112  			SetViewByCulture();
    113  			base.Render(output);
    114  		}
    115  	}
    116  }
    117  
    
     I then register the assembly with the page…

     

    <%@ Register Namespace="Dtkh.CompanionHolidays.WebControls" Assembly="Dtkh.CompanionHolidays" TagPrefix="DtkhCh" %>

     

    …and use the control much like the below example. Please note that I have to use an underscore instead of a dash for the id of the views as dashes are not valid characters for the id attribute.

     

          <DtkhCh:LocalizedContent ID="content" runat="server">

                <asp:View ID="default" runat="server">

                english

                </asp:View>

                <asp:View ID="zh_TW" runat="server">

                繁體中文

                </asp:View>

                <asp:View ID="zh_CN" runat="server">

                簡體

                </asp:View>

          </DtkhCh:LocalizedContent>

     

    By setting AutoCultureDetection or the CultureName, I am able to display localized the appropriate content to your users.

     

  • Re: In-page localization using a webcontrol derived from the multiview control

    02-19-2007, 10:28 AM
    Hi there
    -----------
    Matt Brooke
    Software & System Developer
    http://www.rocketscience.uk.com
    http://www.i-snapshot.com
  • Re: In-page localization using a webcontrol derived from the multiview control

    02-19-2007, 10:38 AM

    Apologies, I hit enter before finishing my post.

    You should be able to simplify things dramatically if you take advantage of LocalResources in .NET. In it's simplest form. Do a single language version of your page - i.e. use only one view instead of the 3 you have. Then whilst VS 2005 is in design mode, select Tools and Generate Local Resource. This will create a Local Resource file for the page selected. To create multilingual versions, copy the .resx file created and rename mypage.aspx.resx to mypage.aspx.en-GB.resx where en-GB is your selected new language.

    Edit the new file with your revised language strings and that should work.

    This does assume that the culture of the executing thread is set correctly however..

    -----------
    Matt Brooke
    Software & System Developer
    http://www.rocketscience.uk.com
    http://www.i-snapshot.com
  • Re: In-page localization using a webcontrol derived from the multiview control

    02-22-2007, 1:50 PM
    • Loading...
    • himawari
    • Joined on 07-19-2006, 3:26 PM
    • Vancouver, BC
    • Posts 63

    Thank you for your response. I tried turning my strings and content into Local Resources as recommeneded and the code indeed looks much cleaner.

    That said, there are some improvements that I would love to see from the next version of visual studio: (please let me know if the current version can do any of the follows)

    • New html resource type that allow html editing and intellisense in resource editor (I do hand-code html and I used to be using dreamweaver. The resource editor doesn't allow me to "tab" and offers no intellisense support... to save time I have to copy the content to dreamweaver and paste the content back to Visual Studio... which is not very efficient.)
    • Optionally shows selected languages as columns in resource editor so I can see all the languages in use at once, simplifying the localization process
    • Option to store all / part of resources in XML so the translations can be easily modified as needed after deployment (I guess I can write a custom resource provider for that but I would love to see Microsoft to include this by default to save us time.)
    • Allow localization to be done to a neutral culture-- en for English and zh for Chinese. Or, at least "Culture Redirection.(?)" For my example, someone from HK (zh-HK) will see the English version of my site as the translation is not done for zh-HK. True, I can copy & paste the resource file from zh-TW as they are both in Traditional Chinese. I would like to have the option to redirect zh-HK pages to use the zh-TW, etc.
  • Re: In-page localization using a webcontrol derived from the multiview control

    02-23-2007, 3:27 AM

    Hi there,

    Some of the things you mention are actually already possible. If you open the .resx files using notepad - you'll see that the resource is actually an XML doc already. To create whats called a default culture, simply leave the culturename out of the resource file name. For example in my primarily english web site i have an english resource named Mypage.resx and language specific ones called Mypage.nl-NL.resx.

    If i wanted to specify french for example. Instead of specifiying fr-FR i could use just fr as the culture. So this would make Mypage.fr.resx suitable for both french canadians and those living in france.

    Hope this helps,

    -----------
    Matt Brooke
    Software & System Developer
    http://www.rocketscience.uk.com
    http://www.i-snapshot.com
  • Re: In-page localization using a webcontrol derived from the multiview control

    02-23-2007, 1:43 PM
    • Loading...
    • himawari
    • Joined on 07-19-2006, 3:26 PM
    • Vancouver, BC
    • Posts 63

    Hi,

    Thank you for your response. I have one question though for updating the resx directly--to deploy do I simply upload the updated files to the web server or do I need to re-compile it before? Or does it depend on my deployment option? (publish site vs. copy site, etc?)

    As for the Chinese language itself it is a little bit more complicated as there are two commonly used variations: Traditional Chinese and Simplified Chinese; someone familiar with one does not necessarily understand the other. For example, most people in Taiwan and Hong Kong use Traditional Chinese and people in China and (I believe) Singapore and Macau will use simplifed Chinese. I can certainly copy the zh-TW file to zh-HK for every single resource file but it will be a maintenance nightmare. setting the resource as zh is not a very good option for the problem mentioned above.

     Anyway I thank you for taking the time to answer my questions and I am learning a lot from posts in this forum.

Page 1 of 1 (6 items)
Microsoft Communities
Page view counter