Skip to content

Commit c86f0c2

Browse files
committed
Initial commit
0 parents  commit c86f0c2

36 files changed

+792
-0
lines changed

Diff for: .gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
*.db3
2+
~*

Diff for: LICENSE

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
See MIT-LICENSE.txt

Diff for: MIT-LICENSE.txt

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
Copyright (c) 2017 Igor Afanasyev, https://github.com/iafan/go-l10n
2+
3+
Permission is hereby granted, free of charge, to any person obtaining
4+
a copy of this software and associated documentation files (the
5+
"Software"), to deal in the Software without restriction, including
6+
without limitation the rights to use, copy, modify, merge, publish,
7+
distribute, sublicense, and/or sell copies of the Software, and to
8+
permit persons to whom the Software is furnished to do so, subject to
9+
the following conditions:
10+
11+
The above copyright notice and this permission notice shall be
12+
included in all copies or substantial portions of the Software.
13+
14+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Diff for: README.md

+96
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
About go-l10n
2+
=============
3+
4+
Lightweight yet powerful continuous localization solution for Go, based on
5+
[Serge](https://serge.io/) and [Plurr](https://github.com/iafan/Plurr).
6+
7+
Advantages
8+
----------
9+
10+
1. Provides solution for both web-based and desktop applications.
11+
2. Can be used with different resource file formats, thanks to Serge.
12+
Currently offers the support for JSON resource files and
13+
string maps in the native .go format. Both formats support
14+
developer comments for translators to get extra context.
15+
3. Supports named placeholders, plurals and conditionals via
16+
Plurr-formatted strings (see the
17+
[interactive demo](http://iafan.github.io/plurr-demo/)).
18+
4. Support for translation and formatting functions in `html/template`
19+
and `text/template`.
20+
5. For web applications, an ability to auto-detect the best language
21+
from the browser, and to force the language using a cookie or
22+
a query string parameter.
23+
6. Comes with ready-to-use Serge configuration files to allow for
24+
seamless continuous localization process (see
25+
[examples](https://github.com/iafan/go-l10n/tree/master/examples/)).
26+
7. Supports pseudotranslations out of the box. Pseudotranslation is a way
27+
to "translate" your application by applying some algorithm to each
28+
source string; it is useful to test if your application looks good
29+
with other locales without waiting for actual translations.
30+
31+
7. The code is split into small packages to minimize external dependencies.
32+
33+
Example Code
34+
------------
35+
36+
There are two example projects that showcase approaches to localizing
37+
[web applications](https://github.com/iafan/go-l10n/tree/master/examples/web/) and
38+
[desktop applications](https://github.com/iafan/go-l10n/tree/master/examples/desktop/).
39+
Below is a condensed example to illustrate the typical usage.
40+
41+
`strings.go` (master resource file):
42+
```go
43+
package main
44+
45+
func init() {
46+
locpool.Resources["en"] = map[string]string{
47+
// Page title
48+
"Hello": "Hello!",
49+
50+
// {N} is the number of messages
51+
"YouHaveNMessages": "You have {N} {N_PLURAL:message|messages}",
52+
}
53+
}
54+
```
55+
56+
`strings-ru.go` (localized resource file):
57+
```go
58+
package main
59+
60+
func init() {
61+
locpool.Resources["ru"] = map[string]string{
62+
// Page title
63+
"Hello": "Здравствуйте!",
64+
65+
// {N} is the number of messages
66+
"YouHaveNMessages": "У вас {N} {N_PLURAL:сообщение|сообщения|сообщений}",
67+
}
68+
}
69+
```
70+
71+
Code:
72+
```go
73+
package main
74+
75+
import (
76+
"github.com/iafan/Plurr/go/plurr"
77+
"github.com/iafan/go-l10n/loc"
78+
)
79+
80+
// Create a global localization pool which will be populated
81+
// by resource files; use English as a default (fallback) language
82+
var locpool = loc.NewPool("en")
83+
84+
func main() {
85+
// Get Russian localization context
86+
lc := locpool.GetContext("ru")
87+
88+
// Get translation by key name:
89+
name := lc.Tr("Hello")
90+
91+
// get translation by key name, then format it using Plurr:
92+
hello := lc.Format("YouHaveNMessages", plurr.Params{"N": 5})
93+
94+
...
95+
}
96+
```

Diff for: examples/desktop/.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
desktop-app

Diff for: examples/desktop/.serge/README.md

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
This is a localization project for the example desktop application.
2+
3+
Prerequisites: [Serge](https://serge.io/) (you need to install
4+
the version from master)
5+
6+
The localization project automatically generates pseudotranslations
7+
mapped to `en-xa` language name. Pseudotranslation is a way
8+
to "translate" your application by applying some algorithm to each
9+
source string; it is useful to test if your application looks good
10+
with other locales without waiting for actual translations.
11+
12+
Localization Workflow
13+
---------------------
14+
15+
Once you have Serge installed, you can run `serge localize` command
16+
in the folder with the .serge configuration file anytime
17+
to bring everything in sync: update your localized resource files
18+
and translation (.po) files.
19+
20+
Here's the typical workflow:
21+
22+
1. Change the master `../strings/strings.json` file (e.g. change an
23+
existing string, or add a new localizable string).
24+
2. Run `serge localize` to update all .po files in the `po/` subdirectory.
25+
3. Change the translation in any of the .po files.
26+
4. Run `serge localize` to update corresponding `../strings/strings-xx.json`
27+
file.
28+
29+
### What to do with the generated .po files?
30+
31+
.po (Gettext) format is widely adopted across translation tools. You can:
32+
33+
1. Publish your .po files in e.g. Git (in the same repository as your
34+
main code, or some separate one) for offline translation and accept
35+
translations as pull requests;
36+
2. Translate these files using desktop tools like Poedit or Virtaal;
37+
3. Publish them for online translation on your own translation server
38+
(e.g. [Zing](https://github.com/evernote/zing)) or send to
39+
third-party translation services or localization vendors.
40+
41+
In all of the cases above, `serge localize` will take care of all
42+
merging and conflict resolution, so you are guaranteed to have clean
43+
and up-to-date localized resource files.

Diff for: examples/desktop/.serge/db/.dummy

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
This is a dummy file to have the directory created

Diff for: examples/desktop/.serge/localize.sh

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#!/bin/sh
2+
3+
serge localize

Diff for: examples/desktop/.serge/po/ru/strings.json.po

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
msgid ""
2+
msgstr ""
3+
"Content-Type: text/plain; charset=UTF-8\n"
4+
"Content-Transfer-Encoding: 8bit\n"
5+
"Language: ru\n"
6+
"Generated-By: Serge 1.2\n"
7+
8+
#: File: strings.json
9+
#: ID: 4b420ad7a2dddfa6aad26fd16010415f
10+
msgctxt "Hello"
11+
msgid "Hello!"
12+
msgstr "Здравствуйте!"
13+
14+
#. {N} is the number of messages
15+
#: File: strings.json
16+
#: ID: a55765c7209756dbb487fe20294bd92e
17+
msgctxt "YouHaveNMessages"
18+
msgid "You have {N:no messages|one message|{N} {N_PLURAL:message|messages}}"
19+
msgstr ""
20+
"У вас {N:сообщений нет|одно сообщение|{N} "
21+
"{N_PLURAL:сообщение|сообщения|сообщений}}"

Diff for: examples/desktop/.serge/translate.serge

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
jobs
2+
{
3+
:main
4+
{
5+
name Parse strings.json
6+
id main
7+
8+
source_language en
9+
destination_languages en-xa ru
10+
11+
source_dir ../strings
12+
source_match ^strings\.json$
13+
14+
db_source DBI:SQLite:dbname=db/translate.db3
15+
db_namespace desktop
16+
17+
ts_file_path po/%LOCALE%/%FILE%.po
18+
output_file_path ../strings/strings-%LANG%.json
19+
output_bom NO # Golang JSON Unmarshaller doesn't handle BOM
20+
21+
parser
22+
{
23+
plugin parse_chrome_json
24+
}
25+
26+
callback_plugins
27+
{
28+
:test_language
29+
{
30+
plugin test_language
31+
phase get_translation_pre
32+
33+
data
34+
{
35+
language en-xa
36+
transliterate NO
37+
expand_length YES
38+
}
39+
}
40+
}
41+
}
42+
}

Diff for: examples/desktop/README.md

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
This example application demonstrates the approach to localization
2+
of Go desktop (command-line) applications, with the following properties:
3+
4+
1. Display language is set manually
5+
2. Localization is stored in JSON files
6+
3. You can provide developer comments for each
7+
translatable entity
8+
4. Localization files are generated by
9+
[Serge](https://github.com/evernote/serge); generated .po files
10+
are used to provide translation (you can do a continuous
11+
localization of your project)
12+
5. Formatting (named placeholders, support for plurals/conditionals)
13+
is provided by [Plurr](https://github.com/iafan/Plurr) library
14+
6. Automatic generation of pseudotranslated resources for quick testing
15+
16+
See [.serge](.serge/) subfolder for an additional README on the localization workflow.
17+
18+
Running
19+
-------
20+
21+
Use `./build.sh` script to build the binary, then run `./desktop-app`.

Diff for: examples/desktop/build.sh

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#!/bin/sh
2+
3+
BINARY=desktop-app
4+
5+
if [ -f $BINARY ] ; then
6+
rm $BINARY
7+
fi
8+
9+
go build -o $BINARY *.go

Diff for: examples/desktop/main.go

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/iafan/Plurr/go/plurr"
7+
"github.com/iafan/go-l10n/loc"
8+
"github.com/iafan/go-l10n/locjson"
9+
)
10+
11+
func main() {
12+
// create localization pool with "en" as a default language
13+
// and load string resources
14+
lp := loc.NewPool("en")
15+
lp.Resources["en"] = locjson.Load("strings/strings.json")
16+
lp.Resources["ru"] = locjson.Load("strings/strings-ru.json")
17+
lp.Resources["en-xa"] = locjson.Load("strings/strings-en-xa.json")
18+
19+
// Print output in English
20+
printSomeMessages(lp.GetContext("en"))
21+
22+
// Print output in Russian
23+
printSomeMessages(lp.GetContext("ru"))
24+
25+
// Print pseudotranslated output
26+
printSomeMessages(lp.GetContext("en-xa"))
27+
}
28+
29+
func printSomeMessages(lc *loc.Context) {
30+
fmt.Println(lc.Tr("Hello"))
31+
32+
for n := 0; n <= 5; n++ {
33+
fmt.Println(lc.Format("YouHaveNMessages", plurr.Params{"N": n}))
34+
}
35+
36+
fmt.Println("---")
37+
}

Diff for: examples/desktop/strings/strings-en-xa.json

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"Hello" : {
3+
"message" : "[Hello! xxxxx]"
4+
},
5+
"YouHaveNMessages" : {
6+
"description" : "{N} is the number of messages",
7+
"message" : "[You have {N:no messages|one message|{N} {N_PLURAL:message|messages}} xxxxxxxxxx xxxxxxxxxx xxxxxxxxxx ]"
8+
}
9+
}

Diff for: examples/desktop/strings/strings-ru.json

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"Hello" : {
3+
"message" : "Здравствуйте!"
4+
},
5+
"YouHaveNMessages" : {
6+
"description" : "{N} is the number of messages",
7+
"message" : "У вас {N:сообщений нет|одно сообщение|{N} {N_PLURAL:сообщение|сообщения|сообщений}}"
8+
}
9+
}

Diff for: examples/desktop/strings/strings.json

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"Hello": {
3+
"message": "Hello!"
4+
},
5+
"YouHaveNMessages": {
6+
"message":
7+
"You have {N:no messages|one message|{N} {N_PLURAL:message|messages}}",
8+
"description": "{N} is the number of messages"
9+
}
10+
}

Diff for: examples/web/.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
server

Diff for: examples/web/.serge/README.md

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
This is a localization project for the example web application.
2+
3+
Prerequisites: [Serge](https://serge.io/) (you need to install
4+
the version from master)
5+
6+
The localization project automatically generates pseudotranslations
7+
mapped to `en-xa` language name. Pseudotranslation is a way
8+
to "translate" your application by applying some algorithm to each
9+
source string; it is useful to test if your application looks good
10+
with other locales without waiting for actual translations.
11+
12+
Localization Workflow
13+
---------------------
14+
15+
Once you have Serge installed, you can run `serge localize` command
16+
in the folder with the .serge configuration file anytime
17+
to bring everything in sync: update your localized resource files
18+
and translation (.po) files.
19+
20+
Here's the typical workflow:
21+
22+
1. Change the master `../strings.go` file (e.g. change an
23+
existing string, or add a new localizable string).
24+
2. Run `serge localize` to update all .po files in the `po/` subdirectory.
25+
3. Change the translation in any of the .po files.
26+
4. Run `serge localize` to update corresponding `../strings-xx.go` file.
27+
28+
### What to do with the generated .po files?
29+
30+
.po (Gettext) format is widely adopted across translation tools. You can:
31+
32+
1. Publish your .po files in e.g. Git (in the same repository as your
33+
main code, or some separate one) for offline translation and accept
34+
translations as pull requests;
35+
2. Translate these files using desktop tools like Poedit or Virtaal;
36+
3. Publish them for online translation on your own translation server
37+
(e.g. [Zing](https://github.com/evernote/zing)) or send to
38+
third-party translation services or localization vendors.
39+
40+
In all of the cases above, `serge localize` will take care of all
41+
merging and conflict resolution, so you are guaranteed to have clean
42+
and up-to-date localized resource files.

Diff for: examples/web/.serge/db/.dummy

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
This is a dummy file to have the directory created

0 commit comments

Comments
 (0)