views:

5150

answers:

7

How can I transform a website to be able to handle multi language (example : english, french, spanish)?

I do not like the resource file because I feel limited and it's pretty long to build the list. Do you have any suggestion?

Update

For the moment the best way we found is to use an XML file and with some Xpath et get values.

+1  A: 

How late in the design process are you? If not too late, and if the budget allows, consider porting to a multi-lingual CMS like Ektron CMS300.net (which has built-in translation tools). If not, then you've got a huge task ahead of you.

Danimal
+1  A: 

Resource files are the way to go. We ship our product in 12 languages. We pull all strings out into resource files and ship them to a translation company. It's a pain at times, but that is the defacto way to do it.

It also gets fun when 4-letter English words get translated into 17-letter phrases and you have to tweak your UI.

Cory Foy
Resource files are the canonical way to do it in .net, but aren't they a bear to fit retroactively? I'd love to see you flesh out your response a bit on that topic...
Danimal
How will you deal with a language that shift the direction of page rendering? In my opinion you have to write some code to counter that. My vote is for Resource files for now as there is no other better way of doing it.
Syed Sajid Nizami
We do deal with Right-to-Left languages. We put all of our text inside controls so the controls don't have to shift
Cory Foy
@Danimal - Yes, they would be a bear. I was involved with a team where we had to do a large site many years ago and farmed it out to a translation service that did it on the fly. If you go to hillsboroughcounty.org and scroll to the bottom you can see that in effect.
Cory Foy
A: 

Another solution I am using is to create the language folders which contain the aspx pages containing all the required text in that particular language.

The only problem here is how can you inject as little code as possible into those replicating pages. I am using a controller pattern here to do this, and then a object data source to get the data and bind it to the controls in all pages.

In this way I have achieved the goal of getting rid of the resource files and I can keep the code behind in one place without replicating it (unless necessary).

Edit: I would recommend a good CMS framework as well.

Syed Sajid Nizami
+3  A: 

We store resources for multilingual sites in a database. We've created a couple of tools to make it easy to create and access these. There's a custom ExpressionBuilder that allows us to use this syntax:

 <asp:linkbutton runat='server' text='<%$ LanguageStrings:ClickMe%>' />

And a custom label that contains the default text, and adds a row to the database if there's not already one.

 <r:languagelabel runat="server" name="AboutUs">About Us</r:languagelabel>

The table containing the strings has one column per language. This makes it very easy to create the site in English (or whatever the default language is), then hand off the table (which populates itself) to a translator. It's also very easy to see what languages you need to have stuff translated for. With resources, every time you need to add a new string, you have to stop what you're doing, and then go to the resource file for each language and add the resource.

Here's the code for the language label:

''' <summary>
''' Retrieves a language-specific string.
''' </summary>
Public Class LanguageLabel
    Inherits Label

    Private _Name As String
    Public Property Name() As String
        Get
            Return _Name
        End Get
        Set(ByVal value As String)
            _Name = value
        End Set
    End Property

    Private Sub Populate()
        If Len(Me.Name) > 0 Then
            Dim LanguageString As String = GetLanguageString(Me.Name, Me.Text)
            If Len(LanguageString) > 0 Then Me.Text = LanguageString
        End If
    End Sub

    Private Sub LanguageLabel_PreRender(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.PreRender
        Populate()
    End Sub

    Protected Overrides Sub Render(ByVal writer As System.Web.UI.HtmlTextWriter)
        ' By default a label wraps the text in a <span>, which we don't want in some situations
        writer.Write(Me.Text)
    End Sub

End Class

and the utility function:

    Public Function GetLanguageString(ByVal Name As String, Optional ByVal DefaultText As String = "") As String
        Dim DefaultLanguage As Language = Languages.GetById(1)
        Name = StripPunctuation(Name).Trim.Replace(" ", "") ' Remove punctuation, spaces from name
        Dim SelectSql As String = String.Format("Select {0},{1} from LanguageStrings where Name=@Name", Languages.CurrentLanguage.Code, DefaultLanguage.Code)
        Dim LanguageStringTable As DataTable = ExecuteDataset(cs, CommandType.Text, SelectSql, New SqlParameter("@Name", Name)).Tables(0)
        If LanguageStringTable IsNot Nothing AndAlso LanguageStringTable.Rows.Count > 0 Then
            Dim LanguageText As String = LanguageStringTable.Rows(0)(Languages.CurrentLanguage.Code).ToString
            Dim DefaultLanguageText As String = LanguageStringTable.Rows(0)(DefaultLanguage.Code).ToString
            If Len(LanguageText) > 0 Then
                ' We have a string in this language
                Return LanguageText
            Else
                ' Nothing in this language - return default language value
                Return DefaultLanguageText
            End If
        Else
            ' No record with this name - create a dummy one
            If DefaultText = "" Then DefaultText = Name
            Dim InsertSql As String = String.Format("Insert into LanguageStrings (Name, {0}) values (@Name, @Text)", DefaultLanguage.Code)
            ExecuteNonQuery(cs, CommandType.Text, InsertSql, New SqlParameter("@Name", Name), New SqlParameter("@Text", DefaultText))
            Return Name
        End If
    End Function
Herb Caudill
+5  A: 

Implicit localization (on the Visual Studio - Tools menu - Generate Local Resources) is about as easy as it can be. Write your pages in your default language, pick the menu option, and your resource files are created and can be sent to someone to translate.

The resx file is just xml, so if the translation company wants you can transform it into (and out of) spreadsheets easily.

Using a databases instead of resx as your backing store is not difficult. Rick Strahl has a good explanation and example code for a database-driven localization provider here - there's a nice built in localization editor too with interface to Google translations and Babelfish.

martin
A: 

One of the web apps I develop has this NLS requirement too.

I found that there are at least 3 locations where you have localized texts:

  • user interface
  • database tables ("catalogs" or whatever you want to call them)
  • backend code (services etc)

My solution has one table for the pages, tables, etc ("Container"), one table for each item in that container (e.g. labels, buttons by ID, record identifiers), and one table for the translated items (plus language identifier).

A translation application helps me keep the translations up-to-date, and exports all translations in XML.

The product ships with translations, but customers can adjust the translations, changes taking effect immediately.

devio
A: 

can u send ur multi language coding