Guides
Localization
Translating your app is an effective way to make it understandable to the many people around the globe! Buffalo uses the go-i18n project to provide the i18n (adapting the software to make it translatable without code change) and l10n (providing translation strings and specific formats) of your app.
Markup the Translatable Strings
Translatable strings must use a specific markup to allow the l10n engine to get the translations.
In a plush template, you can use the t
helper:
<%= t("greetings") %>
Translation Context
You can use a context with the t
helper, to provide variables to the translation string:
<%= t("name-format", {name: "Mark"}) %>
Plural Handling
You can use this helper with a numeric second arg to handle singular/plural cases:
<%= t("messages-notification", notificationsLen) %>
Provide a context using a third arg:
<%= t("messages-notification", notificationsLen, ctx) %>
Provide Translations
Translations are stored in the locales
folder. By default, they are stored in a all.en-us.yaml
file for the American English strings.
You can provide translations for another language by providing a new file all.my-language-code.yaml
. If you want to split your strings into logical modules, you can even create multiples files, e.g. users.en-us.yaml
for the user-related stuff, and all.en-us.yaml
for the global stuff.
The localization format used by go-i18n is the following:
- id: greetings
translation: "Welcome to Buffalo (EN)"
- id: messages-notification
translation:
one: "You have {{.Count}} notification"
other: "You have {{.Count}} notifications"
Define the Default Language
To define the default language of your app, you need to edit the app.go
file in the actions
folder:
// Setup and use translations:
var err error
if T, err = i18n.New(packr.NewBox("../locales"), "en-US"); err != nil {
app.Stop(err)
}
app.Use(T.Middleware())
Changing "en-US"
to another language code will change the default language.
Localized Views
Sometimes, you have to translate a whole page, and marking every part of the page takes a lot of time. On some other cases, you’ll want to localize the page in a different way for a specific locale. Localized views is a complementary way to handle your translations.
Localized views are included in the i18n middleware, so you don’t need to setup anything else to use them.
Create suffixed versions of the templates
First, create a version for the default locale, without a lang suffix:
page.html:
<p>This is my default language page.</p>
Then, create a new suffixed version for each language you want to support:
page.en-us.html:
<p>This is my en-US version.</p>
page.fr-fr.html:
<p>This is my fr-FR version.</p>
The middleware will detect the user language and choose the right template for you! It also works with guest users, using the Accept-Language
HTTP header.
Use i18n in Actions
You’ll need to use the i18n features in actions, for instance, to translate flash messages. Here is the way to use it:
func Login(c buffalo.Context) error {
// [...]
// Set a translated flash message
c.Flash().Add("success", T.Translate(c, "users.login-success"))
return c.Redirect(303, "/users/signin")
}
T.Translate
takes the buffalo.Context
as first argument, then the following args are the same as the t
helper ones (t
calls T.Translate
with the context, behind the scene).
Refresh Translation Context
If you provide translated versions of your app, you’ll probably have a language switch function. This way, the users can choose the correct language. Buffalo can’t detect when you change the language in an action, since it will extract the user languages once per request. You’ll then have to redirect to another page to see the changes. But even with that trick, if you use a flash message inside the action, the language used will be the old one.
To solve that problem, you can use the T.Refresh
method and refresh the language used for translations, within an action.
func SwitchLanguage(c buffalo.Context) error {
f := struct {
Language string `form:"lang"`
URL string `form:"url"`
}{}
if err := c.Bind(&f); err != nil {
return errors.WithStack(err)
}
// Set new current language using a cookie, for instance
cookie := http.Cookie{
Name: "lang",
Value: f.Language,
MaxAge: int((time.Hour * 24 * 265).Seconds()),
Path: "/",
}
http.SetCookie(c.Response(), &cookie)
// Update language for the flash message
T.Refresh(c, f.Language)
c.Flash().Add("success", T.Translate(c, "users.language-changed", f))
return c.Redirect(302, f.URL)
}
Customize Generated Names
Many Buffalo generators use markbates/inflect to generate a normalized version of a name. For example, when you want to generate a new model, the name you give to the command line is normalized in plural, capitalized, and so on forms.
Sometimes, the rules used by inflect are not correct (in this case, feel free to open a PR on the repo!). Sometimes a rule is not correct for your use case, but it’s still correct in a general rule. In this case, you can provide custom rules using the inflections.json
file at the root of your project.
inflections.json:
{
"singular form": "plural form"
}
Related Resources
- Translating a Buffalo app - An article about using Buffalo i18n tools.