set & use language cookie

This commit is contained in:
cblgh 2021-04-15 10:23:04 +02:00
parent 9863c6b166
commit f535aa8f9c
6 changed files with 103 additions and 41 deletions

View File

@ -124,35 +124,37 @@ func New(
}),
render.InjectTemplateFunc("listLanguages", func(r *http.Request) interface{} {
urlTo := web.NewURLTo(m)
route := urlTo(router.CompleteSetLanguage).String()
csrfElement := csrf.TemplateField(r)
urlTo := web.NewURLTo(m)
route := urlTo(router.CompleteSetLanguage).String()
// seem to get an error when changing languages on pages that already embed a csrf token
csrfElement := csrf.TemplateField(r)
createFormElement := func (tag, translation string) string {
return fmt.Sprintf(`
createFormElement := func(tag, translation string) string {
return fmt.Sprintf(`
<form
action="%s"
method="POST"
>
%s
<input type="hidden" name="lang" value="%s">
<input type="hidden" name="page" value="%s">
<input
type="submit"
value="%s"
class="text-gray-500 hover:underline"
class="text-gray-500 hover:underline cursor-pointer"
/>
</form>
`, route, csrfElement, tag, translation)
}
return func () template.HTML {
languages := locHelper.ListLanguages()
languageOptions := make([]string, len(languages))
for tag, translation := range languages {
languageOptions = append(languageOptions, createFormElement(tag, translation))
}
return (template.HTML)(strings.Join(languageOptions, "\n"))
}
}),
`, route, csrfElement, tag, r.RequestURI, translation)
}
return func() template.HTML {
languages := locHelper.ListLanguages()
languageOptions := make([]string, len(languages))
for tag, translation := range languages {
languageOptions = append(languageOptions, createFormElement(tag, translation))
}
return (template.HTML)(strings.Join(languageOptions, "\n"))
}
}),
render.InjectTemplateFunc("urlToNotice", func(r *http.Request) interface{} {
return func(name string) *url.URL {
@ -269,10 +271,29 @@ func New(
)
mainMux.Handle("/admin/", members.AuthenticateFromContext(r)(adminHandler))
// handle setting language
m.Get(router.CompleteSetLanguage).HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
fmt.Println("set das language jaaa")
})
// handle setting language
m.Get(router.CompleteSetLanguage).HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
lang := req.FormValue("lang")
previousRoute := req.FormValue("page")
fmt.Println(lang, previousRoute)
session, err := cookieStore.Get(req, i18n.LanguageCookieName)
if err != nil {
fmt.Printf("cookie error? %w\n", err)
return
}
prevCookie := session.Values["lang"]
fmt.Println("previous cookie", prevCookie)
session.Values["lang"] = lang
err = session.Save(req, w)
if err != nil {
fmt.Printf("we failed to save the language session cookie %w\n", err)
}
http.Redirect(w, req, previousRoute, http.StatusTemporaryRedirect)
})
// landing page
m.Get(router.CompleteIndex).Handler(r.HTML("landing/index.tmpl", func(w http.ResponseWriter, req *http.Request) (interface{}, error) {

View File

@ -1,5 +1,7 @@
# default localiztion file for english
MetaLanguage = "English"
# the name of this language, in its language. Used for language picking
LanguageName = "English"
# generic terms
GenericConfirm = "Yes"

View File

@ -14,22 +14,40 @@ import (
"strings"
"github.com/BurntSushi/toml"
"github.com/gorilla/sessions"
"github.com/nicksnyder/go-i18n/v2/i18n"
"github.com/ssb-ngi-pointer/go-ssb-room/web"
"go.mindeco.de/http/render"
"golang.org/x/text/language"
"github.com/ssb-ngi-pointer/go-ssb-room/internal/repo"
)
const LanguageCookieName = "gossbroom-language"
type Helper struct {
bundle *i18n.Bundle
languages map[string]string
bundle *i18n.Bundle
languages map[string]string
cookieStore *sessions.CookieStore
}
func New(r repo.Interface) (*Helper, error) {
bundle := i18n.NewBundle(language.English)
bundle.RegisterUnmarshalFunc("toml", toml.Unmarshal)
cookieCodec, err := web.LoadOrCreateCookieSecrets(r)
if err != nil {
return nil, err
}
cookieStore := &sessions.CookieStore{
Codecs: cookieCodec,
Options: &sessions.Options{
Path: "/",
MaxAge: 2 * 60 * 60, // two hours in seconds // TODO: configure
},
}
// parse toml files and add them to the bundle
walkFn := func(path string, info os.FileInfo, rs io.Reader, err error) error {
if err != nil {
@ -57,7 +75,7 @@ func New(r repo.Interface) (*Helper, error) {
}
// walk the embedded defaults
err := fs.WalkDir(Defaults, ".", func(path string, d fs.DirEntry, err error) error {
err = fs.WalkDir(Defaults, ".", func(path string, d fs.DirEntry, err error) error {
if err != nil {
return err
}
@ -116,7 +134,7 @@ func New(r repo.Interface) (*Helper, error) {
// create a mapping of language tags to the translated language names
langmap := listLanguages(bundle)
return &Helper{bundle: bundle, languages: langmap}, nil
return &Helper{bundle: bundle, languages: langmap, cookieStore: cookieStore}, nil
}
func listLanguages(bundle *i18n.Bundle) map[string]string {
@ -127,7 +145,7 @@ func listLanguages(bundle *i18n.Bundle) map[string]string {
l.loc = i18n.NewLocalizer(bundle, langTag.String())
msg, err := l.loc.Localize(&i18n.LocalizeConfig{
MessageID: "MetaLanguage",
MessageID: "LanguageName",
})
if err != nil {
msg = langTag.String()
@ -160,10 +178,22 @@ func (h Helper) newLocalizer(lang string, accept ...string) *Localizer {
// FromRequest returns a new Localizer for the passed helper,
// using form value 'lang' and Accept-Language http header from the passed request.
// TODO: user settings/cookie values?
// If a language cookie is detected, then it takes precedence over the form value & Accept-Lanuage header.
func (h Helper) FromRequest(r *http.Request) *Localizer {
lang := r.FormValue("lang")
accept := r.Header.Get("Accept-Language")
session, err := h.cookieStore.Get(r, LanguageCookieName)
if err != nil {
fmt.Printf("cookie error? %w\n", err)
return h.newLocalizer(lang, accept)
}
prevCookie := session.Values["lang"]
if prevCookie != nil {
return h.newLocalizer(prevCookie.(string), lang, accept)
}
return h.newLocalizer(lang, accept)
}

View File

@ -0,0 +1,20 @@
package i18ntesting
import (
"github.com/stretchr/testify/assert"
"path/filepath"
"testing"
"github.com/ssb-ngi-pointer/go-ssb-room/internal/repo"
"github.com/ssb-ngi-pointer/go-ssb-room/web/i18n"
)
func TestListAllLanguages(t *testing.T) {
r := repo.New(filepath.Join("testrun", t.Name()))
a := assert.New(t)
helper, err := i18n.New(r)
a.NoError(err)
t.Log(helper)
langmap := helper.ListLanguages()
a.Equal(langmap["en"], "English")
}

View File

@ -3,7 +3,6 @@ package i18ntesting
import (
"bytes"
"fmt"
"github.com/stretchr/testify/assert"
"io/ioutil"
"os"
"path/filepath"
@ -67,17 +66,7 @@ func justTheKeys(t *testing.T) []byte {
return buf.Bytes()
}
func TestListAllLanguages(t *testing.T) {
r := repo.New(filepath.Join("testrun", t.Name()))
a := assert.New(t)
helper, err := i18n.New(r)
a.NoError(err)
t.Log(helper)
langmap := helper.ListLanguages()
a.Equal(langmap["en"], "English")
}
func TestWriteReplacement(t *testing.T) {
func WriteReplacement(t *testing.T) {
r := repo.New(filepath.Join("testrun", t.Name()))
testOverride := filepath.Join(r.GetPath("i18n"), "active.en.toml")

View File

@ -14,7 +14,7 @@ const (
CompleteNoticeShow = "complete:notice:show"
CompleteNoticeList = "complete:notice:list"
CompleteSetLanguage = "complete:set-language"
CompleteSetLanguage = "complete:set-language"
CompleteAliasResolve = "complete:alias:resolve"