I don’t know if You’ve ever heard about SharePoint’s SPUtility class, but it contains many static methods that can really make Your life easier. One of those methods is SPUtility.GetLocalizedString. With this method You can get a localized string from Your’s .resx file which should be located at 12\TEMPLATE\Resources\.

First thing You have to do is creating .resx file. You can do it by adding a new item to a project.

Add two(or more if You want) files. One with a standard name, in my case zavaz.SPUtilityTestProject.resx and a second with the same name, but extended with a language culture of the country You want to provide translation. I’ll make a transaltion for Poland, so my second file name will be zavaz.SPUtilityTestProject.pl-PL.resx

First file will be the default file with an english language. We will use it when we won’t have a resx file for the language of the user who entered our site. Second file will be used, when user who entered our site has a Polish language set in the browser. Now You have to fill the files with the phrases You want to have translations for. After doing it copy the files to the 12\TEMPLATE\Resources\ directory. Also sometimes it’s good to recycle application pool or run iisreset command after adding some new phrases to the files, because SharePoint can cache their content and You could not see the changes You’ve made.

Back to the SPUtility.GetLocalizedString method. It has three parameters:
1. string source – pattern for this parameter is “$Resources:NameOfThePhrase”
2. string defaultResourceName – name of the default .resx file, in my case it’s “zavaz.SPUtilityTestProject”
3. uint language – ID of the language You want Your phrase to be translated to. You can get it with a help of the below code:

CultureInfo ci = new CultureInfo("pl-PL");
uint LCID = (uint)ci.LCID;

Having this informaton we can build a simple LanguageManager class which will wrap the SPUtility.GetLocalizedString into more “user-friendly” version:

public class LanguageManager
 {
 public uint LCID { get; private set; }

 private const string ResourceFileName = "zavaz.SPUtilityTestProject";

 public LanguageManager(string culture)
 {
 CultureInfo ci = new CultureInfo(culture);
 LCID = (uint)ci.LCID;
 }

 //userLanguages is a table of string passed from the user's browser. If it's empty we pass "en-US" culture(we don't have a file for this culture, so the default .resx(zavaz.SPUtilityTestProject.resx) will be used. If userLanguages has some entries then we pass the first one(if it would be "pl-PL" then the "zavaz.SPUtilityTestProject.pl-PL.resx" would be used)
 public LanguageManager(string[] userLanguages) : this((userLanguages != null && userLanguages.Length > 0) ? userLanguages[0] : "en-US")
 {
 }

 public string GetLocalizedString(string key)
 {
 return SPUtility.GetLocalizedString("$Resources:" + key, ResourceFileName, LCID);
 }
 }

From the code we can call LanguageManager like this:

//Request.UserLanguages is a table from the user's browser
LanguageManager LANGManager = new LanguageManager(Request.UserLanguages);
string localizedWelcome = LANGManager.GetLocalizedString("Welcome");
string localizedPleaseWait = LANGManager.GetLocalizedString("Wait");

To check the results and switch IE language go to the Internet options and then Languages: