How does Wetalk use Beego for real-time localization?

Source: Internet
Author: User
Tags i18n
This is a creation in Article, where the information may have evolved or changed.

What is Wetalk?

Wetalk, as a popular light forum type program, is the most heavyweight open-source product developed so far using Beego. The product was created and maintained by Slene, a member of the Beego development team, so it can be said that Wetalk covers all the advanced uses of the present Beego and is a best example of learning to use Beego.

What is real-time localization?

localization, simply speaking, is that the program provides a multi-lingual user interface. So what is real-time localization? As the name implies, it is possible to switch the language of the user interface at any time, like many international sites to provide multi-language options and instant switching, instead of like some desktop software, you must download different versions for multiple languages separately.

Third-party Packages

Before you cut to the chase, let's introduce the localization package that is involved in this article: beego/i18n. The package is also created and maintained by the Beego development team, and the code is concise but functionally complete, supporting both code-level and template-level localization approaches. In addition, the code of the package itself is very concise because the goconfig is used to complete the operation of the INI format configuration file.

Localization files

BEEGO/I18N uses the INI configuration file as the format for localized files, and each language generally has a corresponding file. For example, Wetalk has two localized files to support both English and Simplified Chinese. As a naming habit, it is recommended to use locale_ .ini the file name as a localized file. One obvious benefit of this is that you can use a loop to complete loading of all localized files:

Setting/conf.go

func settingLocales() {    // load locales with locale_LANG.ini files    langs := "en-US|zh-CN"    for _, lang := range strings.Split(langs, "|") {        lang = strings.TrimSpace(lang)        files := []string{"conf/" + "locale_" + lang + ".ini"}        if fh, err := os.Open(files[0]); err == nil {            fh.Close()        } else {            files = nil        }        if err := i18n.SetMessage(lang, "conf/global/"+"locale_"+lang+".ini", files...); err != nil {            beego.Error("Fail to set message file: " + err.Error())            os.Exit(2)        }    }    Langs = i18n.ListLangs()}

Code-level localization

To use localization in a controller, you need to initialize the language of each request first. To do this, Wetalk adds an embedded structure for each controller i18n.Locale :

Base/base.go

// baseRouter implemented global settings for all other routers.type BaseRouter struct {    beego.Controller    i18n.Locale    User    models.User    IsLogin bool}

In this way, the user's preferred language and settings can be obtained at the first time the user request is accepted to use localized functionality in logic.

The following code shows how to set the language options for each request based on URL parameters, Cookies, browser preference language, and default language, respectively:

Base/base.go

Setlang Sets Site language Version.func (this *baserouter) Setlang () bool {isneedredir: = False Hascookie: = FAL SE//Get all lang names from i18n langs: = setting. Langs//1.    Check URL arguments. Lang: = this. GetString ("lang")//2.    Get language information from cookies. If len (lang) = = 0 {lang = this.  Ctx.getcookie ("lang") Hascookie = true} else {Isneedredir = true}//Check again in case someone    Modify by Purpose. If!i18n. Isexist (lang) {lang = "" Isneedredir = False Hascookie = false}//3. Check if IsLogin then use user setting if Len (lang) = = 0 && this. islogin {lang = i18n. Getlangbyindex (this. User.lang)}//4.    Get language information from ' Accept-language '. If len (lang) = = 0 {al: = this.            Ctx.Input.Header ("Accept-language") If Len (AL) > 4 {al = Al[:5]//Only compare first 5 letters. If i18n.                Isexist (AL) {lang = Al}}}//4.    Defaucurlang language is 中文版.    If len (lang) = = 0 {lang = "en-us" isneedredir = false}//Save language information in cookies.    If!hascookie {this.setlangcookie (lang)}//Set language properties. This. data["lang"] = lang this. data["langs"] = langs this. Lang = lang return isneedredir}

Where the isNeedRedir variable is used to indicate whether the user determines the language option through a URL designation, in order to keep the URL neat, Wetalk automatically sets the language option to the cookie and redirects it when it encounters this situation.

The code this.Data["Lang"] = curLang.Lang is to set the user language option to a Lang template variable named so that language issues can be handled in the template.

The following two lines:

this.Data["CurLang"] = curLang.Namethis.Data["RestLangs"] = restLangs

It is mainly used to implement the button display of user's free switching language.

Controller localization Processing

Since we have embedded a structure in the controller i18n.Locale , as long as we need to localize it, we can simply invoke i18n.Locale the Tr method:

func (l Locale) Tr(format string, args ...interface{}) string

The first parameter of the method accepts a formatted string, followed by the parameters needed for formatting, that is, you can use the following notation in the localized file:

seconds_ago = %d seconds ago

The following code shows how to localize in a controller method:

Base/base.go

if valid, ok := this.Data[errName].(*validation.Validation); ok {    valid.SetError(fieldName, this.Tr(errMsg))}

Template-Level localization

Template-level localization is more common than code-level, so beego/i18n also provides support for localized processing in templates, the Tr function:

func Tr(lang, format string, args ...interface{}) string

Unlike the previous method, the function also requires passing in a parameter lang to indicate the target language.

Of course, to use a custom function in a template, you must first register:

Modules/utils/template.go

beego.AddFuncMap("i18n", i18nHTML)

Here's i18nHTML actually the right i18n.Tr one package:

Modules/utils/template.go

// get HTML i18n stringfunc i18nHTML(lang, format string, args ...interface{}) template.HTML {    return template.HTML(i18n.Tr(lang, format, args...))}

This is done primarily for translation results that are not escaped by the Go language template engine. Of course, you will normally i18n.Tr register as a template function without problems.

Remember that variable in the Controller language option setting method Lang ? It's time to come in handy:

Views/article/show.html

{{i18n .Lang "post.post_author"}}

Processing localization in a template is as simple as that.

The same keywords for different pages

You should have noticed that the wording in the last section is a "post.post_author" bit strange, why is there one in the middle . ? This is actually a partitioning feature provided by Goconfig, which means that for different partitions, you can use different translation fields for the keywords you want to use.

The following syntax is used for the INI configuration file partition feature:

Conf/global/locale_en-us.ini

[topic]favorite_remove = Remove Favoritefavorite_add = Add Favoritefavorite_already = Favorited[post]post_new = New Postpost_edit = Edit Postset_best = Set Bestremove_best = Remove Best

Ambiguity processing

Because it . is a partition flag, when your key name appears in this symbol, ambiguity causes the language processing to fail. At this point, you only need to add an extra to the entire key name. can avoid ambiguity.

Assuming that your key name is about. , in order to avoid ambiguity, we need to use:

{{i18n .Lang ".about."}}

To get the correct localization results.

Existing deficiencies

    • You may have found that every time you call a function in a template i18n , you need to pass in the .Lang parameters. In fact, this is because Beego cannot dynamically specify the implementation of the template function, so the corresponding translation function must be beego.Run() set before. For frameworks that allow you to specify template functions in the Controller (xweb), you can omit the field directly from the set this.Tr as a template function .Lang .

Other instructions

    • If the corresponding value of the corresponding key is not found, the original string of the key is output. For example, if the key is hi not found in the localization file with the key named in the string, it will be hi returned directly to the caller as the result of the translation.
    • The i18n package provides a command-line tool to help simplify the development process.

Summarize

For a Web site, the ability to support real-time language switching is a very user friendly behavior. In addition, unlike command-line or other types of programs, the multilingual support of the Web site largely requires the I18N package to provide support for template-level localization, and the beego/i18n package completes the task very well.

Other cases

    • Go Walker
    • Beego Web
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.