Browse Source

i18n WIP with x/text.

Frederic G. MARAND 6 years ago
parent
commit
463dfa37b7

+ 1 - 1
.idea/runConfigurations/Generate.xml

@@ -1,6 +1,6 @@
 <component name="ProjectRunConfigurationManager">
   <configuration default="false" name="Generate" type="MAKEFILE_TARGET_RUN_CONFIGURATION" factoryName="Makefile">
-    <makefile filename="$PROJECT_DIR$/Makefile" target="generate -v cmd" workingDirectory="$PROJECT_DIR$" arguments="">
+    <makefile filename="$PROJECT_DIR$/Makefile" target="generate" workingDirectory="$PROJECT_DIR$" arguments="">
       <envs />
     </makefile>
     <method v="2" />

+ 1 - 1
Makefile

@@ -14,4 +14,4 @@ cmd/kurzd/kurzd: $(wildcard api/*.go) $(wildcard cmd/kurzd/*.go) $(wildcard doma
 	cd cmd/kurzd && go build
 
 generate:
-	go generate -v
+	go generate -v ./cmd/kurzd

+ 3 - 1
cmd/kurzd/kurzd.go

@@ -1,11 +1,13 @@
 // Package kurzd contains the Kurz daemon command.
 package main
 
-//go:generate gotext -srclang=en update -out=catalog.go -lang=fr,de,en
+//go:generate gotext -srclang=en update -out=catalog.go -lang=fr,en
 
 import (
 	"fmt"
 	"os"
+
+	_ "golang.org/x/text/message"
 )
 
 /**

+ 1 - 1
cmd/kurzd/serve.go

@@ -12,9 +12,9 @@ import (
 	"code.osinet.fr/fgm/kurz/web/ui"
 	"github.com/spf13/viper"
 
-	"code.osinet.fr/fgm/kurz/web/api"
 	"code.osinet.fr/fgm/kurz/domain"
 	"code.osinet.fr/fgm/kurz/infrastructure"
+	"code.osinet.fr/fgm/kurz/web/api"
 	"github.com/gorilla/mux"
 	"github.com/spf13/cobra"
 )

+ 2 - 0
domain/errors.go

@@ -3,6 +3,8 @@ package domain
 import (
 	"errors"
 	"fmt"
+
+	_ "golang.org/x/text/message"
 )
 
 type ErrorKind int

+ 3 - 0
go.mod

@@ -2,7 +2,9 @@ module code.osinet.fr/fgm/kurz
 
 require (
 	github.com/BurntSushi/toml v0.3.1 // indirect
+	github.com/davecgh/go-spew v1.1.1
 	github.com/go-sql-driver/mysql v1.4.0
+	github.com/gorilla/context v1.1.1
 	github.com/gorilla/mux v1.6.2
 	github.com/gorilla/sessions v1.1.3
 	github.com/inconshreveable/mousetrap v1.0.0 // indirect
@@ -12,6 +14,7 @@ require (
 	github.com/spf13/pflag v1.0.3 // indirect
 	github.com/spf13/viper v1.2.1
 	golang.org/x/text v0.3.0
+	golang.org/x/tools v0.0.0-20181213151202-c779628d65d9 // indirect
 	google.golang.org/appengine v1.3.0 // indirect
 	gopkg.in/yaml.v2 v2.2.1
 )

+ 2 - 0
go.sum

@@ -51,6 +51,8 @@ golang.org/x/sys v0.0.0-20180906133057-8cf3aee42992 h1:BH3eQWeGbwRU2+wxxuuPOdFBm
 golang.org/x/sys v0.0.0-20180906133057-8cf3aee42992/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/tools v0.0.0-20181213151202-c779628d65d9 h1:GvLrN6r8tl185vpz03h7B67JAKYm8iWKoMozjEabei8=
+golang.org/x/tools v0.0.0-20181213151202-c779628d65d9/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 google.golang.org/appengine v1.3.0 h1:FBSsiFRMz3LBeXIomRnVzrQwSDj4ibvcRexLG0LZGQk=
 google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=

+ 4 - 0
text/locales/en-US/out.gotext.json

@@ -0,0 +1,4 @@
+{
+    "language": "en-US",
+    "messages": null
+}

+ 1 - 0
text/locales/extracted.gotext.json

@@ -0,0 +1 @@
+null

+ 49 - 0
text/main.go

@@ -0,0 +1,49 @@
+package main
+
+import (
+	"errors"
+	"fmt"
+	"golang.org/x/text/message"
+
+	"golang.org/x/text/language"
+	_ "golang.org/x/text/message"
+)
+
+//go:generate gotext -srclang=en update -out=catalog.go -lang=fr,en
+
+type ErrorKind int
+
+const (
+	NoError ErrorKind = iota
+	Unimplemented
+)
+
+var Errors = map[ErrorKind]string{
+	NoError:       "No error",
+	Unimplemented: "Not yet implemented",
+}
+
+type Error struct {
+	error
+	Kind ErrorKind
+}
+
+func MakeError(kind ErrorKind, detail string) Error {
+	var message string
+	if len(detail) == 0 {
+		message = Errors[kind]
+	} else {
+		message = fmt.Sprintf("%s: %s", Errors[kind], detail)
+	}
+
+	return Error{
+		Kind:  kind,
+		error: errors.New(message),
+	}
+}
+
+func main() {
+	p := message.NewPrinter(language.French)
+	err := MakeError(NoError, "all is well")
+	p.Printf(err)
+}

+ 54 - 0
web/ui/catalog.go

@@ -0,0 +1,54 @@
+// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
+
+package ui
+
+import (
+	"golang.org/x/text/language"
+	"golang.org/x/text/message"
+	"golang.org/x/text/message/catalog"
+)
+
+type dictionary struct {
+	index []uint32
+	data  string
+}
+
+func (d *dictionary) Lookup(key string) (data string, ok bool) {
+	p := messageKeyToIndex[key]
+	start, end := d.index[p], d.index[p+1]
+	if start == end {
+		return "", false
+	}
+	return d.data[start:end], true
+}
+
+func init() {
+	dict := map[string]catalog.Dictionary{
+		"en": &dictionary{index: enIndex, data: enData},
+		"fr": &dictionary{index: frIndex, data: frData},
+	}
+	fallback := language.MustParse("en")
+	cat, err := catalog.NewFromMap(dict, catalog.Fallback(fallback))
+	if err != nil {
+		panic(err)
+	}
+	message.DefaultCatalog = cat
+}
+
+var messageKeyToIndex = map[string]int{
+	"On Post": 0,
+}
+
+var enIndex = []uint32{ // 2 elements
+	0x00000000, 0x00000008,
+} // Size: 32 bytes
+
+const enData string = "\x02On Post"
+
+var frIndex = []uint32{ // 2 elements
+	0x00000000, 0x00000000,
+} // Size: 32 bytes
+
+const frData string = ""
+
+// Total table size 72 bytes (0KiB); checksum: B4FE2088

+ 4 - 0
web/ui/locales/en/out.gotext.json

@@ -0,0 +1,4 @@
+{
+    "language": "en",
+    "messages": null
+}

+ 4 - 0
web/ui/locales/fr/out.gotext.json

@@ -0,0 +1,4 @@
+{
+    "language": "fr",
+    "messages": null
+}

+ 9 - 3
web/ui/post_target.go

@@ -1,5 +1,7 @@
 package ui
 
+//go:generate gotext -srclang=en update -out=catalog.go -lang=fr,en
+
 import (
 	"fmt"
 	"io"
@@ -7,10 +9,12 @@ import (
 	"net/http"
 	"strings"
 
-	"github.com/gorilla/sessions"
-
 	"code.osinet.fr/fgm/kurz/domain"
+	"code.osinet.fr/fgm/kurz/web/i18n"
 	"github.com/gorilla/mux"
+	"github.com/gorilla/sessions"
+
+	_ "golang.org/x/text/message"
 )
 
 // handlePostTarget handles form POST requests to /
@@ -26,10 +30,12 @@ func handlePostTarget(w http.ResponseWriter, r *http.Request, router *mux.Router
 
 	r.ParseForm()
 	defer r.Body.Close()
+
+	p := i18n.Printer(r)
 	rawTarget := r.PostForm.Get(rootInputName)
 	target, err := validateTarget(rawTarget)
 	if err != nil {
-		sess.AddFlash(err.Error())
+		sess.AddFlash(p.Sprintf(err.Error()))
 		sess.Save(r, w)
 		location, err := URLFromRoute(router, RouteGetRoot, nil)
 		if err != nil {

+ 1 - 1
web/ui/templates/home.gohtml

@@ -23,7 +23,7 @@
             <div id="form">
                 <div>
                     <label accesskey="U" for="form_url" class="required">L&#039;URL à transformer :</label>
-                    <input type="url" id="form_url" name="{{ .InputName }}" required="required" placeholder="http://www.osinet.fr" size="60" maxlength="240" />
+                    <input type="url" id="form_url" name="{{ .InputName }}" rzequired="required" placeholder="http://www.osinet.fr" size="60" maxlength="240" />
                 </div>
             </div>
             <input type="submit" name="{{ .SubmitName }}" value="Envoyer" />

+ 6 - 5
web/ui/web.go → web/ui/ui.go

@@ -8,6 +8,7 @@ a complete application.
 package ui
 
 import (
+	"code.osinet.fr/fgm/kurz/web/i18n"
 	"errors"
 	"fmt"
 	"html/template"
@@ -82,19 +83,19 @@ func setupAssetRoutes(configAssetsPath string, router *mux.Router) {
 func setupControllerRoutes(gmux *mux.Router) {
 	router = *gmux
 	// BUG(fgm): improve Accept header matchers once https://github.com/golang/go/issues/19307 is completed.
-	gmux.HandleFunc("/{short}", func(w http.ResponseWriter, r *http.Request) {
+	gmux.Handle("/{short}", i18n.WithPrinter(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 		handleGetShort(w, r, gmux)
-	}).
+	}))).
 		Methods("GET", "HEAD").
 		Name(RouteGetShort)
-	gmux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
+	gmux.Handle("/", i18n.WithPrinter(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 		handlePostTarget(w, r, gmux)
-	}).
+	}))).
 		HeadersRegexp("Accept", HtmlTypeRegex).
 		Headers("Content-Type", HtmlFormType).
 		Methods("POST").
 		Name(RoutePostTarget)
-	gmux.HandleFunc("/", handleGetRoot).
+	gmux.Handle("/", i18n.WithPrinter(http.HandlerFunc(handleGetRoot))).
 		Methods("GET", "HEAD").
 		Name(RouteGetRoot)
 }

+ 0 - 0
web/ui/web_test.go → web/ui/ui_test.go


+ 6 - 0
web/web.go

@@ -0,0 +1,6 @@
+// Package web is just a wrapper for the API and UI subpackages.
+package web
+
+import (
+	_ "golang.org/x/text/message"
+)