Files
build-web-application-with-…/en/eBook/10.1.md
2016-09-23 17:54:50 -03:00

7.3 KiB

10.1 Time zones

Finding out the locale

A locale is a set of descriptors for a particular geographical region, and can include specific language habits, text formatting, cultural idioms and a multitude of other settings. A locale's name is usually composed of three parts. First (and mandatory) is the locale's language abbreviation, such as "en" for English or "zh" for Chinese. The second part is an optional country specifier, and follows the first with an underscore. This specifier allows web applications to distinguish between different countries which speak the same language, such as "en_US" for U.S. English, and "en_UK" for British English. The last part is another optional specifier, and is added to the locale with a period. It specifies which character set to use, for instance "zh_CN.gb2312" specifies the gb2312 character set for Chinese.

Go defaults to the "UTF-8" encoding set, so i18n in Go applications do not need to consider the last parameter. Thus, in our examples, we'll only use the first two parts of locale descriptions as our standard i18n locale names.

On Linux and Solaris systems, you can use the locale -a command to get a list of all supported regional names. You can use this list as examples of some common locales. For BSD and other systems, there is no locale command, but the regional information is stored in /usr/share/locale.

Setting the locale

Now that we've defined what a locale is, we need to be able to set it according to visiting users' information (either from their personal settings, the visited domain name, etc.). Here are some methods we can use to set the user's locale:

Setting the locale by domain name

We can set a user's locale via the domain name itself when the application uses different domains for different regions. For example, we can use www.asta.com as our default English website, and the domain name www.asta.cn as its Chinese counterpart. By setting up separate domains for separate regions, you can detect and serve the requested locale. This type of setup has several advantages:

  • Identifying the locale via URL is distinctive and unambiguous
  • Users intuitively know which domain names to visit for their specific region or language
  • Implementing this scheme in a Go application very simple and convenient, and can be achieved through a map
  • Conducive to search engine crawlers which can improve the site's SEO

We can use the following code to implement a corresponding domain name locale:

if r.Host == "www.asta.com" {
	i18n.SetLocale("en")
} else if r.Host == "www.asta.cn" {
	i18n.SetLocale("zh-CN")
} else if r.Host == "www.asta.tw" {
	i18n.SetLocale("zh-TW")
}

Alternatively, we could have also set locales through the use of sub-domain such as "en.asta.com" for English sites and "cn.asta.com" for Chinese site. This scheme can be realized in code as follows:

prefix:= strings.Split(r.Host,".")

if prefix[0] == "en" {
	i18n.SetLocale("en")
} else if prefix[0] == "cn" {
	i18n.SetLocale("zh-CN")
} else if prefix[0] == "tw" {
	i18n.SetLocale("zh-TW")
}

Setting locales from the domain name as we've done above has its advantages, however l10n is generally not implemented in this way. First of all, the cost of domain names (although usually quite affordable individually) can quickly add up given that each locale will need its own domain name, and often the name of the domain will not necessarily fit in with the local context. Secondly, we don't want to have to individually configure each website for each locale. Rather, we should be able to do this programmatically, for instance by using URL parameters. Let's have a look at the following description.

Locale parameter settings from the domain name

The most common way of implementing l10n is to set the desired locale directly in the URL parameters, such www.asta.com/hello?locale=zh or www.asta.com/zh/hello. This way, we can set the region like so: i18n.SetLocale(params["locale"]).

This setup has almost all the advantages of prepending the locale in front of the domain and it's RESTful, so we don't need to add additional methods to implement it. The downside to this approach is that it requires a corresponding locale parameter inside each link, which can be quite cumbersome and may increase complexity. However, we can write a generic function that produces these locale-specific URLs so that all links are generated through it. This function should automatically add a locale parameter to each link so when users click them, we are able to parse their requests with ease: locale = params [" locale "].

Perhaps we want our URLs to look even more RESTful. For example, we could map each of our resources under a specific locale like www.asta.com/en/books for our English site and www.asta.com/zh/books for the Chinese one. This approach is not only more conducive to URL SEO, but is also more friendly for users. Anybody visiting the site should be able to access locale-specific website resources directly from the URL. Such URL addresses can then be passed through the application router in order to obtain the proper locale (refer to the REST section, which describes the router plug-in implementation):

mux.Get("/:locale/books", listbook)

From the client settings area

In some special cases, we require explicit client information in order to set the locale rather than obtaining it from the URL or URL parameters. This information may come directly from the client's browser settings, the user's IP address, or the location settings filled out by the user at the time of registration. This approach is more suitable for web-based applications.

  • Accept-Language

When a client requests information using an HTTP header set with the Accept-Language field, we can use the following Go code to parse the header and set the appropriate region code:

AL := r.Header.Get("Accept-Language")
if AL == "en" {
	i18n.SetLocale("en")
} else if AL == "zh-CN" {
	i18n.SetLocale("zh-CN")
} else if AL == "zh-TW" {
	i18n.SetLocale("zh-TW")
}

Of course, in real world applications, we may require more rigorous processes and rules for setting user regions

  • IP Address

Another way of setting a client's region is to look at the user's IP address. We can use the popular GeoIP GeoLite Country library to help us relate user IP addresses to their corresponding regional areas. Implementing this mechanism is very simple: we only need to look up the user's IP address inside our database and then return the country regions, according to the results returned by setting the corresponding regions.

  • User profile

Of course, you can also let users provide you with drop-down menus or whatever way set the appropriate locale, then we have the information entered by the user, it is saved to the account associated with the profile, when the user login again, this time to set up replicated to the locale setting, so that you can guarantee that every time the user accesses are based on their previously set locale to get the page.

Summary

Through the above description shows that you can set the Locale There are many ways that we should be selected according to the different needs of different settings Locale way to allow a user to its most familiar way to get the services we provide, improve application user friendliness.