Chris
Chris

Reputation: 4485

ASP.NET MVC2 localization: How to format language/country dependend text?

I want to build an multi language ASP.NET MVC 2 website.

Let's say I have the following sentences:

MyStrings.resx:
TestString : "This is my test"

MyStrings.de.resx:
TestString : "Dies ist mein Test"

MyStrings.fr.resx:
TestString : "C'est mon test"

Now on my site I want to make the words my/mein/mon in an other color. For example I want to asssign an other span class. What is the best/standard practice to do that?

How can I do that?

Upvotes: 2

Views: 798

Answers (1)

Gideon
Gideon

Reputation: 18491

  1. You could mix HTML into your resource: "This is <span class="x">my</span> test"
  2. You could use string.Format: Resource: "This is {0}my{1} test" , use: string.Format(Resources.TestString, "<span class=\"x\">", "</span">).
  3. You could use some custom formatting scheme: For example resource: "This is --my-- test", and write some extension method accepting a string, and replacing all -- with the right tags.

UPDATE
4. You can use custom format method. See code below.

Your resource could look like Hello {firstname}, you still have {amount} {currency} in your bankaccount. You would "consume" this resource in the following way:

Resources.Bla.Bla.FormatWith(new { Firstname = SomeVariable, AMOUNT = 4, currency = "USD"  });

As you can see, it is case insensitive, and you can mix in constants and variables. I made a custom translation web app, where I check if the translator uses all of the "variables" that are present in the original English string. That is quite an important check according to me.
Let me do add that this way is a bit controversial, since it uses reflection, but I find that the pros weigh heavier than the cons.

public static string FormatWith(this string format, object source)
    {
        StringBuilder sbResult = new StringBuilder(format.Length);
        StringBuilder sbCurrentTerm = new StringBuilder();
        char[] formatChars = format.ToCharArray();
        bool inTerm = false;
        object currentPropValue = source;

        var sourceProps = source.GetType().GetProperties();

        for (int i = 0; i < format.Length; i++)
        {
            if (formatChars[i] == '{')
                inTerm = true;
            else if (formatChars[i] == '}')
            {
                PropertyInfo pi = sourceProps.First(sp=>sp.Name.Equals(sbCurrentTerm.ToString(), StringComparison.InvariantCultureIgnoreCase));
                sbResult.Append((string)(pi.PropertyType.GetMethod("ToString", new Type[] { }).Invoke(pi.GetValue(currentPropValue, null) ?? string.Empty, null)));
                sbCurrentTerm.Clear();
                inTerm = false;
                currentPropValue = source;
            }
            else if (inTerm)
            {
                if (formatChars[i] == '.')
                {
                    PropertyInfo pi = currentPropValue.GetType().GetProperty(sbCurrentTerm.ToString());
                    currentPropValue = pi.GetValue(source, null);
                    sbCurrentTerm.Clear();
                }
                else
                    sbCurrentTerm.Append(formatChars[i]);
            }
            else
                sbResult.Append(formatChars[i]);
        }
        return sbResult.ToString();
    } 

Upvotes: 4

Related Questions