Skip to content

Commit

Permalink
New: i18n pluralization and variables support and more...
Browse files Browse the repository at this point in the history
fixes: #1649, #1648, #1641, #1650

relative to: #1597
  • Loading branch information
kataras committed Sep 29, 2020
1 parent f224ded commit 4065819
Show file tree
Hide file tree
Showing 63 changed files with 2,227 additions and 857 deletions.
953 changes: 480 additions & 473 deletions HISTORY.md

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions _examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -176,8 +176,9 @@
* [Client-Side](compression/client/main.go)
* [Client-Side (using Iris)](compress/client-using-iris/main.go)
* Localization and Internationalization
* [i18n](i18n)
* [i18n templates and functions](i18n/i18n-template)
* [Basic](i18n/basic)
* [Ttemplates and Functions](i18n/template)
* [Pluralization and Variables](i18n/plurals)
* Authentication, Authorization & Bot Detection
* [Basic Authentication](auth/basicauth/main.go)
* [CORS](auth/cors)
Expand Down
2 changes: 1 addition & 1 deletion _examples/auth/jwt/refresh-token/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ func generateTokenPair(accessJWT, refreshJWT *jwt.JWT) (TokenPair, error) {
refreshClaims := refreshJWT.Expiry(jwt.Claims{
ID: "refresh_kataras",
// For example, the User ID,
// this is nessecary to check against the database
// this is necessary to check against the database
// if the user still exist or has credentials to access our page.
Subject: "53afcf05-38a3-43c3-82af-8bbbe0e4a149",
})
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
key1: "αυτό είναι μια τιμή από το πρώτο αρχείο: locale_multi_first"
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
key1: "this is a value from the first file: locale_multi_first"
File renamed without changes.
File renamed without changes.
File renamed without changes.
2 changes: 0 additions & 2 deletions _examples/i18n/i18n-template/locales/el-GR/welcome.yml

This file was deleted.

2 changes: 0 additions & 2 deletions _examples/i18n/i18n-template/locales/en-US/welcome.yml

This file was deleted.

1 change: 0 additions & 1 deletion _examples/i18n/locales/el-GR/locale_multi_first_el-GR.ini

This file was deleted.

1 change: 0 additions & 1 deletion _examples/i18n/locales/en-US/locale_multi_first_en-US.ini

This file was deleted.

5 changes: 5 additions & 0 deletions _examples/i18n/plurals/locales/en-US/1648.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[message]
Encrypted = Encrypted
Message = Message
EncryptedMessage = {{tr "message.Encrypted"}} {{tr "message.Message"}}
HostResult = Store {{tr "message.EncryptedMessage"}} Online
89 changes: 89 additions & 0 deletions _examples/i18n/plurals/locales/en-US/welcome.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# Locale variables
#
# Unlike normal keys, the variables
# have limitations of: no ">x", "zero", "two" and template functions are supported.
# This is done to force developers to use small and easy to read variables for easier maintain process.
Vars:
- Minutes:
# possible keys:
# one
# "=x" - where x is a number
# "<x"
# other
# format - to customize the format, which defaults to %d .
one: "minute"
other: "minutes"
format: "%d" # defaults to that.
- Dogs:
"=5": "dogsssss"
one: "dog"
other: "dogs"
- Houses:
one: "house"
other: "houses"
- Gender:
"=1": "She" # 1 for female
"=2": "He" # 2 for male

# Using variables in raw string
YouLate: "You are %[1]d ${Minutes} late."
# Just a simple raw value
Classic: "classic"

# Pluralization, translate based on the plural count
# including the variables and their counts
FreeDay:
# possible keys:
# zero
# one
# two
# "=x"
# "<x"
# ">x"
# other
"=3": "You have three days and %[2]d ${Minutes} off." # "FreeDay" 3, 15 (plurals + variable pluralization)
one: "You have a day off" # "FreeDay", 1
other: "You have %[1]d free days" # "FreeDay", 5

# Sprintf-like raw translation
HeIsHome: "%s is home"

# Value without plural of its self but variables except pluralization
HouseCount: "${Gender} (%[3]s) has %[2]d ${Houses}"
# Same as above but with a template instead
VarTemplate: (${Gender}) {{tr "HeIsHome" .Name}}
# Template and non template with variables in the same plural key
VarTemplatePlural:
one: "${Gender} is awesome"
other: "other (${Gender}) has %[3]d ${Houses}"
"=5": "{{call .InlineJoin .Names}} are awesome"
TemplatePlural:
one: "{{.Name}} is unique"
"=5": "{{call .InlineJoin .Names}} are awesome"
# Same as above but it takes the variable counting through the map argument
TemplateVarTemplatePlural:
other: "These {{.PluralCount}} are wonderful, feeding {{.DogsCount}} ${Dogs} in total!"

# Local variables and section.
LocalVarsHouseCount:
Text: "${Gender} has %[2]d ${Houses}"
Vars:
- Gender:
"=3": "She"
"=4": "He"
- Houses:
one: "house"
other: "houses"

# Sections:
root:
user: Account

nav:
home: Home # nav.home
user: '{{tr "root.user"}}' # nav.user
more:
what: "this" # nav.more.what
even:
more: "yes" # nav.more.even.more
aplural: "You are %[1]d ${Minutes} late." # Tr("nav.more.even.aplural", 15)
175 changes: 175 additions & 0 deletions _examples/i18n/plurals/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
package main

import (
"strings"

"github.com/kataras/iris/v12"
)

const (
female = iota + 1
male
)

const tableStyle = `
<style>
a {
padding: 8px 8px;
text-decoration:none;
cursor:pointer;
color: #10a2ff;
}
table {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
height: 100%;
width: 100%;
border-collapse: collapse;
border-spacing: 0;
empty-cells: show;
border: 1px solid #cbcbcb;
}
table caption {
color: #000;
font: italic 85%/1 arial, sans-serif;
padding: 1em 0;
text-align: center;
}
table td,
table th {
border-left: 1px solid #cbcbcb;
border-width: 0 0 0 1px;
font-size: inherit;
margin: 0;
overflow: visible;
padding: 0.5em 1em;
}
table thead {
background-color: #10a2ff;
color: #fff;
text-align: left;
vertical-align: bottom;
}
table td {
background-color: transparent;
}
.table-odd td {
background-color: #f2f2f2;
}
.table-bordered td {
border-bottom: 1px solid #cbcbcb;
}
.table-bordered tbody > tr:last-child > td {
border-bottom-width: 0;
}
</style>
`

/*
$ go run .
Visit http://localhost:8080
*/
func main() {
app := iris.New()
err := app.I18n.Load("./locales/*/*", "en-US")
// ^ here we only use a single locale for the sake of the example,
// on a real app you can register as many languages as you want to support.
if err != nil {
panic(err)
}

app.Get("/", func(ctx iris.Context) {
ctx.HTML("<html><body>\n")
ctx.WriteString(tableStyle)
ctx.WriteString(`<table class="table-bordered table-odd">
<thead>
<tr>
<th>Key</th>
<th>Translation</th>
<th>Arguments</th>
</tr>
</thead><tbody>
`)
defer ctx.WriteString("</tbody></table></body></html>")

tr(ctx, "Classic")

tr(ctx, "YouLate", 1)
tr(ctx, "YouLate", 2)

tr(ctx, "FreeDay", 1)
tr(ctx, "FreeDay", 5)

tr(ctx, "FreeDay", 3, 15)

tr(ctx, "HeIsHome", "Peter")

tr(ctx, "HouseCount", female, 2, "Maria")
tr(ctx, "HouseCount", male, 1, "Peter")

tr(ctx, "nav.home")
tr(ctx, "nav.user")
tr(ctx, "nav.more.what")
tr(ctx, "nav.more.even.more")
tr(ctx, "nav.more.even.aplural", 1)
tr(ctx, "nav.more.even.aplural", 15)

tr(ctx, "VarTemplate", iris.Map{
"Name": "Peter",
"GenderCount": male,
})

tr(ctx, "VarTemplatePlural", 1, female)
tr(ctx, "VarTemplatePlural", 2, female, 1)
tr(ctx, "VarTemplatePlural", 2, female, 5)
tr(ctx, "VarTemplatePlural", 1, male)
tr(ctx, "VarTemplatePlural", 2, male, 1)
tr(ctx, "VarTemplatePlural", 2, male, 2)

tr(ctx, "VarTemplatePlural", iris.Map{
"PluralCount": 5,
"Names": []string{"Makis", "Peter"},
"InlineJoin": func(arr []string) string {
return strings.Join(arr, ", ")
},
})

tr(ctx, "TemplatePlural", iris.Map{
"PluralCount": 1,
"Name": "Peter",
})
tr(ctx, "TemplatePlural", iris.Map{
"PluralCount": 5,
"Names": []string{"Makis", "Peter"},
"InlineJoin": func(arr []string) string {
return strings.Join(arr, ", ")
},
})
tr(ctx, "VarTemplatePlural", 2, male, 4)

tr(ctx, "TemplateVarTemplatePlural", iris.Map{
"PluralCount": 3,
"DogsCount": 5,
})

tr(ctx, "message.HostResult")

tr(ctx, "LocalVarsHouseCount.Text", 3, 4)
})

app.Listen(":8080")
}

func tr(ctx iris.Context, key string, args ...interface{}) {
translation := ctx.Tr(key, args...)
ctx.Writef("<tr><td>%s</td><td>%s</td><td>%v</td></tr>\n", key, translation, args)
}
Loading

0 comments on commit 4065819

Please sign in to comment.