add Localization and Sitemap sections (for v12.1.0+)

Gerasimos (Makis) Maropoulos 2019-12-13 21:08:58 +02:00
parent 06ac3b4352
commit e0d16ace31
No known key found for this signature in database
GPG Key ID: 5DBE766BD26A54E7
9 changed files with 1168 additions and 861 deletions

@ -40,6 +40,8 @@ This wiki is the main source of documentation for **developers** working with (o
* [[Websockets]]
* [[Dependency Injection|Dependency-Injection]]
* [[MVC]]
* [[Sitemap]]
* [[Localization]]
* [[Testing]]
* [➲ Examples](https://github.com/kataras/iris/tree/master/_examples)
* [[Starter Kits]]

@ -21,19 +21,19 @@ module your_project_name
go 1.13
require (
github.com/kataras/iris/v12 v12.0.1
github.com/kataras/iris/v12 v12.1.0
)
```
> `$ go build`
## How to update
<!-- ## How to update
Here is the go-get command to get the latest and greatest Iris version. Master branch is usually stable enough.
```bash
$ go get -u github.com/kataras/iris/v12@latest
```
$ go get -u github.com/kataras/iris/v12@master
``` -->
## Troubleshooting

283
Localization.md Normal file

@ -0,0 +1,283 @@
## Introduction
Localization features provide a convenient way to retrieve strings in various languages, allowing you to easily support multiple languages within your application. Language strings are stored in files within the `./locales` directory. Within this directory there should be a subdirectory for each language supported by the application:
```sh
│ main.go
└───locales
├───el-GR
│ home.yml
├───en-US
│ home.yml
└───zh-CN
home.yml
```
The default language for your application is the first registered language.
```go
app := iris.New()
// First parameter: Glob filpath patern,
// Second variadic parameter: Optional language tags,
// the first one is the default/fallback one.
app.I18n.Load("./locales/*/*", "en-US", "el-GR", "zh-CN")
```
Or if you load all languages by:
```go
app.I18n.Load("./locales/*/*")
```
Then set the default language using:
```go
app.I18n.SetDefault("en-US")
```
### Load embedded locales
You may want to embed locales with a go-bindata tool within your application executable.
1. install a go-bindata tool, e.g.
`$ go get -u github.com/go-bindata/go-bindata/...`
2. embed local files to your application
`$ go-bindata -o locales.go ./locales/...`
3. use the `LoadAssets` method to initialize and load the languages
^ The `AssetNames` and `Asset` functions are generated by `go-bindata`
```go
ap.I18n.LoadAssets(AssetNames, Asset, "en-US", "el-GR", "zh-CN")
```
## Defining Translations
Each file should contain keys with translated text or template values.
### Fmt Style
```yaml
hi: "Hi %s"
```
### Templates Style
```yaml
hi: "Hi {{ .Name }}"
# Template functions are supported too
# hi: "Hi {{sayHi .Name}}
```
### INI Sections
```ini
[cart]
checkout = ολοκλήρωση παραγγελίας - {{.Param}}
```
> YAML, TOML, JSON, INI files.
## Determining The Current Locale
You may use the `context.GetLocale` method to determine the current locale or check if the locale is a given value:
```go
func(ctx iris.Context) {
locale := ctx.GetLocale()
// [...]
}
```
The **Locale** interface looks like this.
```go
// Locale is the interface which returns from a `Localizer.GetLocale` metod.
// It serves the transltions based on "key" or format. See `GetMessage`.
type Locale interface {
// Index returns the current locale index from the languages list.
Index() int
// Tag returns the full language Tag attached tothis Locale,
// it should be uniue across different Locales.
Tag() *language.Tag
// Language should return the exact languagecode of this `Locale`
//that the user provided on `New` function.
//
// Same as `Tag().String()` but it's static.
Language() string
// GetMessage should return translated text based n the given "key".
GetMessage(key string, args ...interface{}) string
}
```
## Retrieving Translation
Use of `context.Tr` method as a shortcut to get a translated text for this request.
```go
func(ctx iris.Context) {
text := ctx.Tr("hi", "name")
// [...]
}
```
### INI Sections
INI Sections are separated by dot `"."`. The second optional value can be a `map` or a `struct` as the template value like the rest file formats.
```go
func(ctx iris.Context) {
text := ctx.Tr("cart.checkout", iris.Map{"Param": "a value"})
// [...]
}
```
## Inside Views
```go
func(ctx iris.Context) {
ctx.View("index.html", iris.Map{
"tr": ctx.Tr,
})
}
```
```html
{{ call .tr "hi" "John Doe" }}
```
## [Example](https://github.com/kataras/iris/tree/master/_examples/i18n)
```go
package main
import "github.com/kataras/iris/v12"
func newApp() *iris.Application {
app := iris.New()
// Configure i18n.
// First parameter: Glob filpath patern,
// Second variadic parameter: Optional language tags,
// the first one is the default/fallback one.
app.I18n.Load("./locales/*/*.ini", "en-US", "el-GR", "zh-CN")
// app.I18n.LoadAssets for go-bindata.
// Default values:
// app.I18n.URLParameter = "lang"
// app.I18n.Subdomain = true
//
// Set to false to disallow path (local) redirects,
// see https://github.com/kataras/iris/issues/1369.
// app.I18n.PathRedirect = true
app.Get("/", func(ctx iris.Context) {
hi := ctx.Tr("hi", "iris")
locale := ctx.GetLocale()
ctx.Writef("From the language %s translated output: %s", locale.Language(), hi)
})
app.Get("/some-path", func(ctx iris.Context) {
ctx.Writef("%s", ctx.Tr("hi", "iris"))
})
app.Get("/multi", func(ctx iris.Context) {
language := ctx.GetLocale().Language()
fromFirstFileValue := ctx.Tr("key1")
fromSecondFileValue := ctx.Tr("key2")
ctx.Writef("From the language: %s,
translated output:\n%s=%s\n%s=%s",
language, "key1", fromFirstFileValue,
"key2", fromSecondFileValue)
})
// using in inside your views:
view := iris.HTML("./views", ".html")
app.RegisterView(view)
app.Get("/templates", func(ctx iris.Context) {
ctx.View("index.html", iris.Map{
"tr": ctx.Tr, // word, arguments... {call .tr "hi" "iris"}}
})
// Note that,
// Iris automatically adds a "tr" global
// template function as well,
// the only differene is the way you call
// it inside your templates and
// that it accepts a language code as
// its first argument: {{ tr "el-GR" "hi" "iris"}}
})
//
return app
}
func main() {
app := newApp()
// go to http://localhost:8080/el-gr/some-path
// ^ (by path prefix)
//
// or http://el.mydomain.com8080/some-path
// ^ (by subdomain - test locally with the hosts file)
//
// or http://localhost:8080/zh-CN/templates
// ^ (by path prefix with uppercase)
//
// or http://localhost:8080/some-path?lang=el-GR
// ^ (by url parameter)
//
// or http://localhost:8080 (default is en-US)
// or http://localhost:8080/?lang=zh-CN
//
// go to http://localhost:8080/multi?lang=el-GR
// or http://localhost:8080/multi (default is en-US)
// or http://localhost:8080/multi?lang=en-US
//
// or use cookies to set the language.
app.Run(iris.Addr(":8080"), iris.WithSitemap("http://localhost:8080"))
}
```
## Sitemap
[[Sitemap]] translations are automatically set to each route by path prefix if `app.I18n.PathRedirect` is true or by subdomain if `app.I18n.Subdomain` is true or by URL query parameter if `app.I18n.URLParameter` is not empty.
Read more at: https://support.google.com/webmasters/answer/189077?hl=en
```sh
GET http://localhost:8080/sitemap.xml
```
```xml
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml">
<url>
<loc>http://localhost:8080/</loc>
<xhtml:link rel="alternate" hreflang="en-US" href="http://localhost:8080/"></xhtml:link>
<xhtml:link rel="alternate" hreflang="el-GR" href="http://localhost:8080/el-GR/"></xhtml:link>
<xhtml:link rel="alternate" hreflang="zh-CN" href="http://localhost:8080/zh-CN/"></xhtml:link>
</url>
<url>
<loc>http://localhost:8080/some-path</loc>
<xhtml:link rel="alternate" hreflang="en-US" href="http://localhost:8080/some-path"></xhtml:link>
<xhtml:link rel="alternate" hreflang="el-GR" href="http://localhost:8080/el-GR/some-path"></xhtml:link>
<xhtml:link rel="alternate" hreflang="zh-CN" href="http://localhost:8080/zh-CN/some-path"></xhtml:link>
</url>
<url>
<loc>http://localhost:8080/multi</loc>
<xhtml:link rel="alternate" hreflang="en-US" href="http://localhost:8080/multi"></xhtml:link>
<xhtml:link rel="alternate" hreflang="el-GR" href="http://localhost:8080/el-GR/multi"></xhtml:link>
<xhtml:link rel="alternate" hreflang="zh-CN" href="http://localhost:8080/zh-CN/multi"></xhtml:link>
</url>
<url>
<loc>http://localhost:8080/templates</loc>
<xhtml:link rel="alternate" hreflang="en-US" href="http://localhost:8080/templates"></xhtml:link>
<xhtml:link rel="alternate" hreflang="el-GR" href="http://localhost:8080/el-GR/templates"></xhtml:link>
<xhtml:link rel="alternate" hreflang="zh-CN" href="http://localhost:8080/zh-CN/templates"></xhtml:link>
</url>
</urlset>
```

@ -13,7 +13,6 @@ Prepare a cup of coffee or tea, whatever pleases you the most, and read some art
* [Iris Go Framework + MongoDB](https://bit.ly/2WDOsZF)
* [How to build a file upload form using DropzoneJS and Go](https://bit.ly/2ygMMqn)
* [How to display existing files on server using DropzoneJS and Go](https://bit.ly/2yjrckQ)
* [Iris, a modular web framework](https://bit.ly/2KHm6q0)
* [Go vs .NET Core in terms of HTTP performance](https://bit.ly/2Kh7ezl)
* [Iris Go vs .NET Core Kestrel in terms of HTTP performance](https://bit.ly/2yo2v6J)
* [How to Turn an Android Device into a Web Server](https://bit.ly/2Icl5EM)

File diff suppressed because it is too large Load Diff

@ -136,7 +136,6 @@ Here is a list of some handlers made specifically for Iris:
| Middleware | Example |
| -----------|-------------|
| [basic authentication](https://github.com/kataras/iris/tree/master/middleware/basicauth) | [iris/_examples/authentication/basicauth](https://github.com/kataras/iris/tree/master/_examples/authentication/basicauth) |
| [localization and internationalization](https://github.com/kataras/iris/tree/master/middleware/i18n) | [iris/_examples/miscellaneous/i81n](https://github.com/kataras/iris/tree/master/_examples/miscellaneous/i18n) |
| [request logger](https://github.com/kataras/iris/tree/master/middleware/logger) | [iris/_examples/http_request/request-logger](https://github.com/kataras/iris/tree/master/_examples/http_request/request-logger) |
| [HTTP method override](https://github.com/kataras/iris/tree/master/middleware/methodoverride) | [iris/middleware/methodoverride/methodoverride_test.go](https://github.com/kataras/iris/blob/master/middleware/methodoverride/methodoverride_test.go) |
| [profiling (pprof)](https://github.com/kataras/iris/tree/master/middleware/pprof) | [iris/_examples/miscellaneous/pprof](https://github.com/kataras/iris/tree/master/_examples/miscellaneous/pprof) |

24
Sitemap.md Normal file

@ -0,0 +1,24 @@
Iris provides extensive support for the Sitemap Protocol which automatically generates [sitemap index](https://www.sitemaps.org/protocol.html#index) "/sitemap.xml" too.
To enable sitemaps on your web application you should use the `iris.WithSitemap` Configurator. This function accepts the full scheme and domain of the exposed application.
```go
app := iris.New()
// [...]
app.Run(iris.Addr(":8080"), iris.WithSitemap("http://localhost:8080"))
```
The application will loop through registered _static_ routes and it will add each one of them to the sitemap file. By default only the `<loc>` XML element will be filled unless the route's fields `LastMod`, `ChangeFreq` or/and `Priority`[*](https://www.sitemaps.org/protocol.html) are set.
```go
app.Get("/home", handler).SetLastMod(time.Now()).SetChangeFreq("hourly").SetPriority(0.8)
```
> A static route is exposed on GET HTTP Method and its path does not contain a dynamic parameter. e.g. /home, /about but not /user/{id:uint64} and e.t.c.
See it in action, download and run the **example** from: https://github.com/kataras/iris/tree/master/_examples/sitemap
If the application **is localized** then `iris.WithSitemap` will add `xhtml:link` XML elements to the sitemap file for each translation language as recommended at: https://support.google.com/webmasters/answer/189077?hl=en. Read more about it at the [[Localization]] section.

@ -9,7 +9,7 @@ Let's see the list of the built-in view engines:
| Engine | Declaration | Underline Template Parser
| -----------|-------------|-------------|
| std template/html | `iris.HTML(...)` | [html/template](https://golang.org/pkg/html/template/) package |
| django | `iris.Django(...)` | [flosch/pongo2](https://github.com/flosch/pongo2) package |
| django | `iris.Django(...)` | [iris-contrib/pongo2](https://github.com/iris-contrib/pongo2) package |
| handlebars | `iris.Handlebars(...)` | [Joker/jade](https://github.com/Joker/jade) package |
| amber | `iris.Amber(...)` | [aymerick/raymond](https://github.com/aymerick/raymond) package |
| pug(jade) | `iris.Pug(...)` | [eknkc/amber](https://github.com/eknkc/amber) package |

@ -35,6 +35,8 @@
* [[Websockets]]
* [[Dependency Injection|Dependency-Injection]]
* [[MVC]]
* [[Sitemap]]
* [[Localization]]
* [[Testing]]
* [Examples](https://github.com/kataras/iris/tree/master/_examples)
* [[Starter Kits]]