Browse Source

Do not use shared variable to translate templates

Frédéric Guillot 8 years ago
parent
commit
ddd3af4b85

+ 1 - 2
daemon/routes.go

@@ -14,7 +14,6 @@ import (
 	"github.com/miniflux/miniflux/locale"
 	"github.com/miniflux/miniflux/middleware"
 	"github.com/miniflux/miniflux/reader/feed"
-	"github.com/miniflux/miniflux/reader/opml"
 	"github.com/miniflux/miniflux/scheduler"
 	"github.com/miniflux/miniflux/storage"
 	"github.com/miniflux/miniflux/template"
@@ -29,7 +28,7 @@ func routes(cfg *config.Config, store *storage.Storage, feedHandler *feed.Handle
 
 	apiController := api.NewController(store, feedHandler)
 	feverController := fever.NewController(store)
-	uiController := ui.NewController(cfg, store, pool, feedHandler, opml.NewHandler(store))
+	uiController := ui.NewController(cfg, store, pool, feedHandler)
 
 	apiHandler := handler.NewHandler(cfg, store, router, templateEngine, translator)
 	feverHandler := handler.NewHandler(cfg, store, router, templateEngine, translator)

+ 5 - 1
http/handler/context.go

@@ -85,7 +85,11 @@ func (c *Context) UserLanguage() string {
 		return user.Language
 	}
 
-	return c.getContextStringValue(middleware.UserLanguageContextKey)
+	language := c.getContextStringValue(middleware.UserLanguageContextKey)
+	if language == "" {
+		language = "en_US"
+	}
+	return language
 }
 
 // Translate translates a message in the current language.

+ 0 - 7
http/handler/handler.go

@@ -41,13 +41,6 @@ func (h *Handler) Use(f ControllerFunc) http.Handler {
 		ctx := NewContext(r, h.store, h.router, h.translator)
 		request := NewRequest(r)
 		response := NewResponse(h.cfg, w, r, h.template)
-		language := ctx.UserLanguage()
-
-		if language != "" {
-			h.template.SetLanguage(language)
-		} else {
-			h.template.SetLanguage("en_US")
-		}
 
 		f(ctx, request, response)
 	})

+ 2 - 2
http/handler/html_response.go

@@ -19,9 +19,9 @@ type HTMLResponse struct {
 }
 
 // Render execute a template and send to the client the generated HTML.
-func (h *HTMLResponse) Render(template string, args map[string]interface{}) {
+func (h *HTMLResponse) Render(template, language string, args map[string]interface{}) {
 	h.writer.Header().Set("Content-Type", "text/html; charset=utf-8")
-	h.template.Execute(h.writer, template, args)
+	h.template.Render(h.writer, template, language, args)
 }
 
 // ServerError sends a 500 error to the browser.

+ 29 - 8
template/engine.go

@@ -8,8 +8,10 @@ import (
 	"bytes"
 	"html/template"
 	"io"
+	"time"
 
 	"github.com/miniflux/miniflux/config"
+	"github.com/miniflux/miniflux/errors"
 	"github.com/miniflux/miniflux/locale"
 	"github.com/miniflux/miniflux/logger"
 
@@ -35,18 +37,37 @@ func (e *Engine) parseAll() {
 	}
 }
 
-// SetLanguage change the language for template processing.
-func (e *Engine) SetLanguage(language string) {
-	e.funcMap.Language = e.translator.GetLanguage(language)
-}
-
-// Execute process a template.
-func (e *Engine) Execute(w io.Writer, name string, data interface{}) {
+// Render process a template and write the ouput.
+func (e *Engine) Render(w io.Writer, name, language string, data interface{}) {
 	tpl, ok := e.templates[name]
 	if !ok {
 		logger.Fatal("[Template] The template %s does not exists", name)
 	}
 
+	lang := e.translator.GetLanguage(language)
+	tpl.Funcs(template.FuncMap{
+		"elapsed": func(timezone string, t time.Time) string {
+			return elapsedTime(lang, timezone, t)
+		},
+		"t": func(key interface{}, args ...interface{}) string {
+			switch key.(type) {
+			case string:
+				return lang.Get(key.(string), args...)
+			case errors.LocalizedError:
+				return key.(errors.LocalizedError).Localize(lang)
+			case *errors.LocalizedError:
+				return key.(*errors.LocalizedError).Localize(lang)
+			case error:
+				return key.(error).Error()
+			default:
+				return ""
+			}
+		},
+		"plural": func(key string, n int, args ...interface{}) string {
+			return lang.Plural(key, n, args...)
+		},
+	})
+
 	var b bytes.Buffer
 	err := tpl.ExecuteTemplate(&b, "base", data)
 	if err != nil {
@@ -61,7 +82,7 @@ func NewEngine(cfg *config.Config, router *mux.Router, translator *locale.Transl
 	tpl := &Engine{
 		templates:  make(map[string]*template.Template),
 		translator: translator,
-		funcMap:    newFuncMap(cfg, router, translator.GetLanguage("en_US")),
+		funcMap:    newFuncMap(cfg, router),
 	}
 
 	tpl.parseAll()

+ 10 - 22
template/functions.go

@@ -12,17 +12,14 @@ import (
 
 	"github.com/gorilla/mux"
 	"github.com/miniflux/miniflux/config"
-	"github.com/miniflux/miniflux/errors"
 	"github.com/miniflux/miniflux/filter"
 	"github.com/miniflux/miniflux/http/route"
-	"github.com/miniflux/miniflux/locale"
 	"github.com/miniflux/miniflux/url"
 )
 
 type funcMap struct {
-	cfg      *config.Config
-	router   *mux.Router
-	Language *locale.Language
+	cfg    *config.Config
+	router *mux.Router
 }
 
 func (f *funcMap) Map() template.FuncMap {
@@ -77,30 +74,21 @@ func (f *funcMap) Map() template.FuncMap {
 		"isodate": func(ts time.Time) string {
 			return ts.Format("2006-01-02 15:04:05")
 		},
+		"dict": dict,
+
+		// These functions are overrided at runtime after the parsing.
 		"elapsed": func(timezone string, t time.Time) string {
-			return elapsedTime(f.Language, timezone, t)
+			return ""
 		},
 		"t": func(key interface{}, args ...interface{}) string {
-			switch key.(type) {
-			case string:
-				return f.Language.Get(key.(string), args...)
-			case errors.LocalizedError:
-				return key.(errors.LocalizedError).Localize(f.Language)
-			case *errors.LocalizedError:
-				return key.(*errors.LocalizedError).Localize(f.Language)
-			case error:
-				return key.(error).Error()
-			default:
-				return ""
-			}
+			return ""
 		},
 		"plural": func(key string, n int, args ...interface{}) string {
-			return f.Language.Plural(key, n, args...)
+			return ""
 		},
-		"dict": dict,
 	}
 }
 
-func newFuncMap(cfg *config.Config, router *mux.Router, language *locale.Language) *funcMap {
-	return &funcMap{cfg, router, language}
+func newFuncMap(cfg *config.Config, router *mux.Router) *funcMap {
+	return &funcMap{cfg, router}
 }

+ 1 - 1
ui/about.go

@@ -17,7 +17,7 @@ func (c *Controller) AboutPage(ctx *handler.Context, request *handler.Request, r
 		return
 	}
 
-	response.HTML().Render("about", args.Merge(tplParams{
+	response.HTML().Render("about", ctx.UserLanguage(), args.Merge(tplParams{
 		"version":    version.Version,
 		"build_date": version.BuildDate,
 		"menu":       "settings",

+ 10 - 10
ui/category.go

@@ -28,7 +28,7 @@ func (c *Controller) ShowCategories(ctx *handler.Context, request *handler.Reque
 		return
 	}
 
-	response.HTML().Render("categories", args.Merge(tplParams{
+	response.HTML().Render("categories", ctx.UserLanguage(), args.Merge(tplParams{
 		"categories": categories,
 		"total":      len(categories),
 		"menu":       "categories",
@@ -71,7 +71,7 @@ func (c *Controller) ShowCategoryEntries(ctx *handler.Context, request *handler.
 		return
 	}
 
-	response.HTML().Render("category_entries", args.Merge(tplParams{
+	response.HTML().Render("category_entries", ctx.UserLanguage(), args.Merge(tplParams{
 		"category":   category,
 		"entries":    entries,
 		"total":      count,
@@ -88,7 +88,7 @@ func (c *Controller) CreateCategory(ctx *handler.Context, request *handler.Reque
 		return
 	}
 
-	response.HTML().Render("create_category", args.Merge(tplParams{
+	response.HTML().Render("create_category", ctx.UserLanguage(), args.Merge(tplParams{
 		"menu": "categories",
 	}))
 }
@@ -104,7 +104,7 @@ func (c *Controller) SaveCategory(ctx *handler.Context, request *handler.Request
 
 	categoryForm := form.NewCategoryForm(request.Request())
 	if err := categoryForm.Validate(); err != nil {
-		response.HTML().Render("create_category", args.Merge(tplParams{
+		response.HTML().Render("create_category", ctx.UserLanguage(), args.Merge(tplParams{
 			"errorMessage": err.Error(),
 		}))
 		return
@@ -117,7 +117,7 @@ func (c *Controller) SaveCategory(ctx *handler.Context, request *handler.Request
 	}
 
 	if duplicateCategory != nil {
-		response.HTML().Render("create_category", args.Merge(tplParams{
+		response.HTML().Render("create_category", ctx.UserLanguage(), args.Merge(tplParams{
 			"errorMessage": "This category already exists.",
 		}))
 		return
@@ -127,7 +127,7 @@ func (c *Controller) SaveCategory(ctx *handler.Context, request *handler.Request
 	err = c.store.CreateCategory(&category)
 	if err != nil {
 		logger.Info("[Controller:CreateCategory] %v", err)
-		response.HTML().Render("create_category", args.Merge(tplParams{
+		response.HTML().Render("create_category", ctx.UserLanguage(), args.Merge(tplParams{
 			"errorMessage": "Unable to create this category.",
 		}))
 		return
@@ -152,7 +152,7 @@ func (c *Controller) EditCategory(ctx *handler.Context, request *handler.Request
 		return
 	}
 
-	response.HTML().Render("edit_category", args)
+	response.HTML().Render("edit_category", ctx.UserLanguage(), args)
 }
 
 // UpdateCategory validate and update a category.
@@ -173,14 +173,14 @@ func (c *Controller) UpdateCategory(ctx *handler.Context, request *handler.Reque
 	}
 
 	if err := categoryForm.Validate(); err != nil {
-		response.HTML().Render("edit_category", args.Merge(tplParams{
+		response.HTML().Render("edit_category", ctx.UserLanguage(), args.Merge(tplParams{
 			"errorMessage": err.Error(),
 		}))
 		return
 	}
 
 	if c.store.AnotherCategoryExists(user.ID, category.ID, categoryForm.Title) {
-		response.HTML().Render("edit_category", args.Merge(tplParams{
+		response.HTML().Render("edit_category", ctx.UserLanguage(), args.Merge(tplParams{
 			"errorMessage": "This category already exists.",
 		}))
 		return
@@ -189,7 +189,7 @@ func (c *Controller) UpdateCategory(ctx *handler.Context, request *handler.Reque
 	err = c.store.UpdateCategory(categoryForm.Merge(category))
 	if err != nil {
 		logger.Error("[Controller:UpdateCategory] %v", err)
-		response.HTML().Render("edit_category", args.Merge(tplParams{
+		response.HTML().Render("edit_category", ctx.UserLanguage(), args.Merge(tplParams{
 			"errorMessage": "Unable to update this category.",
 		}))
 		return

+ 1 - 4
ui/controller.go

@@ -9,7 +9,6 @@ import (
 	"github.com/miniflux/miniflux/http/handler"
 	"github.com/miniflux/miniflux/model"
 	"github.com/miniflux/miniflux/reader/feed"
-	"github.com/miniflux/miniflux/reader/opml"
 	"github.com/miniflux/miniflux/scheduler"
 	"github.com/miniflux/miniflux/storage"
 )
@@ -30,7 +29,6 @@ type Controller struct {
 	store       *storage.Storage
 	pool        *scheduler.WorkerPool
 	feedHandler *feed.Handler
-	opmlHandler *opml.Handler
 }
 
 func (c *Controller) getCommonTemplateArgs(ctx *handler.Context) (tplParams, error) {
@@ -55,12 +53,11 @@ func (c *Controller) getCommonTemplateArgs(ctx *handler.Context) (tplParams, err
 }
 
 // NewController returns a new Controller.
-func NewController(cfg *config.Config, store *storage.Storage, pool *scheduler.WorkerPool, feedHandler *feed.Handler, opmlHandler *opml.Handler) *Controller {
+func NewController(cfg *config.Config, store *storage.Storage, pool *scheduler.WorkerPool, feedHandler *feed.Handler) *Controller {
 	return &Controller{
 		cfg:         cfg,
 		store:       store,
 		pool:        pool,
 		feedHandler: feedHandler,
-		opmlHandler: opmlHandler,
 	}
 }

+ 5 - 5
ui/entry.go

@@ -155,7 +155,7 @@ func (c *Controller) ShowFeedEntry(ctx *handler.Context, request *handler.Reques
 		prevEntryRoute = ctx.Route("feedEntry", "feedID", feedID, "entryID", prevEntry.ID)
 	}
 
-	response.HTML().Render("entry", args.Merge(tplParams{
+	response.HTML().Render("entry", ctx.UserLanguage(), args.Merge(tplParams{
 		"entry":          entry,
 		"prevEntry":      prevEntry,
 		"nextEntry":      nextEntry,
@@ -231,7 +231,7 @@ func (c *Controller) ShowCategoryEntry(ctx *handler.Context, request *handler.Re
 		prevEntryRoute = ctx.Route("categoryEntry", "categoryID", categoryID, "entryID", prevEntry.ID)
 	}
 
-	response.HTML().Render("entry", args.Merge(tplParams{
+	response.HTML().Render("entry", ctx.UserLanguage(), args.Merge(tplParams{
 		"entry":          entry,
 		"prevEntry":      prevEntry,
 		"nextEntry":      nextEntry,
@@ -302,7 +302,7 @@ func (c *Controller) ShowUnreadEntry(ctx *handler.Context, request *handler.Requ
 		return
 	}
 
-	response.HTML().Render("entry", args.Merge(tplParams{
+	response.HTML().Render("entry", ctx.UserLanguage(), args.Merge(tplParams{
 		"entry":          entry,
 		"prevEntry":      prevEntry,
 		"nextEntry":      nextEntry,
@@ -362,7 +362,7 @@ func (c *Controller) ShowReadEntry(ctx *handler.Context, request *handler.Reques
 		prevEntryRoute = ctx.Route("readEntry", "entryID", prevEntry.ID)
 	}
 
-	response.HTML().Render("entry", args.Merge(tplParams{
+	response.HTML().Render("entry", ctx.UserLanguage(), args.Merge(tplParams{
 		"entry":          entry,
 		"prevEntry":      prevEntry,
 		"nextEntry":      nextEntry,
@@ -431,7 +431,7 @@ func (c *Controller) ShowStarredEntry(ctx *handler.Context, request *handler.Req
 		prevEntryRoute = ctx.Route("starredEntry", "entryID", prevEntry.ID)
 	}
 
-	response.HTML().Render("entry", args.Merge(tplParams{
+	response.HTML().Render("entry", ctx.UserLanguage(), args.Merge(tplParams{
 		"entry":          entry,
 		"prevEntry":      prevEntry,
 		"nextEntry":      nextEntry,

+ 5 - 5
ui/feed.go

@@ -45,7 +45,7 @@ func (c *Controller) ShowFeedsPage(ctx *handler.Context, request *handler.Reques
 		return
 	}
 
-	response.HTML().Render("feeds", args.Merge(tplParams{
+	response.HTML().Render("feeds", ctx.UserLanguage(), args.Merge(tplParams{
 		"feeds": feeds,
 		"total": len(feeds),
 		"menu":  "feeds",
@@ -88,7 +88,7 @@ func (c *Controller) ShowFeedEntries(ctx *handler.Context, request *handler.Requ
 		return
 	}
 
-	response.HTML().Render("feed_entries", args.Merge(tplParams{
+	response.HTML().Render("feed_entries", ctx.UserLanguage(), args.Merge(tplParams{
 		"feed":       feed,
 		"entries":    entries,
 		"total":      count,
@@ -112,7 +112,7 @@ func (c *Controller) EditFeed(ctx *handler.Context, request *handler.Request, re
 		return
 	}
 
-	response.HTML().Render("edit_feed", args)
+	response.HTML().Render("edit_feed", ctx.UserLanguage(), args)
 }
 
 // UpdateFeed update a subscription and redirect to the feed entries page.
@@ -132,7 +132,7 @@ func (c *Controller) UpdateFeed(ctx *handler.Context, request *handler.Request,
 	}
 
 	if err := feedForm.ValidateModification(); err != nil {
-		response.HTML().Render("edit_feed", args.Merge(tplParams{
+		response.HTML().Render("edit_feed", ctx.UserLanguage(), args.Merge(tplParams{
 			"errorMessage": err.Error(),
 		}))
 		return
@@ -141,7 +141,7 @@ func (c *Controller) UpdateFeed(ctx *handler.Context, request *handler.Request,
 	err = c.store.UpdateFeed(feedForm.Merge(feed))
 	if err != nil {
 		logger.Error("[Controller:EditFeed] %v", err)
-		response.HTML().Render("edit_feed", args.Merge(tplParams{
+		response.HTML().Render("edit_feed", ctx.UserLanguage(), args.Merge(tplParams{
 			"errorMessage": "Unable to update this feed.",
 		}))
 		return

+ 1 - 1
ui/history.go

@@ -39,7 +39,7 @@ func (c *Controller) ShowHistoryPage(ctx *handler.Context, request *handler.Requ
 		return
 	}
 
-	response.HTML().Render("history", args.Merge(tplParams{
+	response.HTML().Render("history", ctx.UserLanguage(), args.Merge(tplParams{
 		"entries":    entries,
 		"total":      count,
 		"pagination": c.getPagination(ctx.Route("history"), count, offset),

+ 1 - 1
ui/integrations.go

@@ -27,7 +27,7 @@ func (c *Controller) ShowIntegrations(ctx *handler.Context, request *handler.Req
 		return
 	}
 
-	response.HTML().Render("integrations", args.Merge(tplParams{
+	response.HTML().Render("integrations", ctx.UserLanguage(), args.Merge(tplParams{
 		"menu": "settings",
 		"form": form.IntegrationForm{
 			PinboardEnabled:      integration.PinboardEnabled,

+ 3 - 3
ui/login.go

@@ -20,7 +20,7 @@ func (c *Controller) ShowLoginPage(ctx *handler.Context, request *handler.Reques
 		return
 	}
 
-	response.HTML().Render("login", tplParams{
+	response.HTML().Render("login", ctx.UserLanguage(), tplParams{
 		"csrf": ctx.CSRF(),
 	})
 }
@@ -36,13 +36,13 @@ func (c *Controller) CheckLogin(ctx *handler.Context, request *handler.Request,
 
 	if err := authForm.Validate(); err != nil {
 		logger.Error("[Controller:CheckLogin] %v", err)
-		response.HTML().Render("login", tplParams)
+		response.HTML().Render("login", ctx.UserLanguage(), tplParams)
 		return
 	}
 
 	if err := c.store.CheckPassword(authForm.Username, authForm.Password); err != nil {
 		logger.Error("[Controller:CheckLogin] %v", err)
-		response.HTML().Render("login", tplParams)
+		response.HTML().Render("login", ctx.UserLanguage(), tplParams)
 		return
 	}
 

+ 5 - 4
ui/opml.go

@@ -7,12 +7,13 @@ package ui
 import (
 	"github.com/miniflux/miniflux/http/handler"
 	"github.com/miniflux/miniflux/logger"
+	"github.com/miniflux/miniflux/reader/opml"
 )
 
 // Export generates the OPML file.
 func (c *Controller) Export(ctx *handler.Context, request *handler.Request, response *handler.Response) {
 	user := ctx.LoggedUser()
-	opml, err := c.opmlHandler.Export(user.ID)
+	opml, err := opml.NewHandler(c.store).Export(user.ID)
 	if err != nil {
 		response.HTML().ServerError(err)
 		return
@@ -29,7 +30,7 @@ func (c *Controller) Import(ctx *handler.Context, request *handler.Request, resp
 		return
 	}
 
-	response.HTML().Render("import", args.Merge(tplParams{
+	response.HTML().Render("import", ctx.UserLanguage(), args.Merge(tplParams{
 		"menu": "feeds",
 	}))
 }
@@ -52,14 +53,14 @@ func (c *Controller) UploadOPML(ctx *handler.Context, request *handler.Request,
 		fileHeader.Size,
 	)
 
-	if impErr := c.opmlHandler.Import(user.ID, file); impErr != nil {
+	if impErr := opml.NewHandler(c.store).Import(user.ID, file); impErr != nil {
 		args, err := c.getCommonTemplateArgs(ctx)
 		if err != nil {
 			response.HTML().ServerError(err)
 			return
 		}
 
-		response.HTML().Render("import", args.Merge(tplParams{
+		response.HTML().Render("import", ctx.UserLanguage(), args.Merge(tplParams{
 			"errorMessage": impErr,
 			"menu":         "feeds",
 		}))

+ 1 - 1
ui/session.go

@@ -25,7 +25,7 @@ func (c *Controller) ShowSessions(ctx *handler.Context, request *handler.Request
 	}
 
 	sessions.UseTimezone(user.Timezone)
-	response.HTML().Render("sessions", args.Merge(tplParams{
+	response.HTML().Render("sessions", ctx.UserLanguage(), args.Merge(tplParams{
 		"sessions":            sessions,
 		"currentSessionToken": ctx.UserSessionToken(),
 		"menu":                "settings",

+ 4 - 4
ui/settings.go

@@ -22,7 +22,7 @@ func (c *Controller) ShowSettings(ctx *handler.Context, request *handler.Request
 		return
 	}
 
-	response.HTML().Render("settings", args)
+	response.HTML().Render("settings", ctx.UserLanguage(), args)
 }
 
 // UpdateSettings update the settings.
@@ -37,7 +37,7 @@ func (c *Controller) UpdateSettings(ctx *handler.Context, request *handler.Reque
 	}
 
 	if err := settingsForm.Validate(); err != nil {
-		response.HTML().Render("settings", args.Merge(tplParams{
+		response.HTML().Render("settings", ctx.UserLanguage(), args.Merge(tplParams{
 			"form":         settingsForm,
 			"errorMessage": err.Error(),
 		}))
@@ -45,7 +45,7 @@ func (c *Controller) UpdateSettings(ctx *handler.Context, request *handler.Reque
 	}
 
 	if c.store.AnotherUserExists(user.ID, settingsForm.Username) {
-		response.HTML().Render("settings", args.Merge(tplParams{
+		response.HTML().Render("settings", ctx.UserLanguage(), args.Merge(tplParams{
 			"form":         settingsForm,
 			"errorMessage": "This user already exists.",
 		}))
@@ -55,7 +55,7 @@ func (c *Controller) UpdateSettings(ctx *handler.Context, request *handler.Reque
 	err = c.store.UpdateUser(settingsForm.Merge(user))
 	if err != nil {
 		logger.Error("[Controller:UpdateSettings] %v", err)
-		response.HTML().Render("settings", args.Merge(tplParams{
+		response.HTML().Render("settings", ctx.UserLanguage(), args.Merge(tplParams{
 			"form":         settingsForm,
 			"errorMessage": "Unable to update this user.",
 		}))

+ 1 - 1
ui/starred.go

@@ -41,7 +41,7 @@ func (c *Controller) ShowStarredPage(ctx *handler.Context, request *handler.Requ
 		return
 	}
 
-	response.HTML().Render("starred", args.Merge(tplParams{
+	response.HTML().Render("starred", ctx.UserLanguage(), args.Merge(tplParams{
 		"entries":    entries,
 		"total":      count,
 		"pagination": c.getPagination(ctx.Route("starred"), count, offset),

+ 9 - 9
ui/subscription.go

@@ -22,7 +22,7 @@ func (c *Controller) Bookmarklet(ctx *handler.Context, request *handler.Request,
 	}
 
 	bookmarkletURL := request.QueryStringParam("uri", "")
-	response.HTML().Render("add_subscription", args.Merge(tplParams{
+	response.HTML().Render("add_subscription", ctx.UserLanguage(), args.Merge(tplParams{
 		"form": &form.SubscriptionForm{URL: bookmarkletURL},
 	}))
 }
@@ -37,7 +37,7 @@ func (c *Controller) AddSubscription(ctx *handler.Context, request *handler.Requ
 		return
 	}
 
-	response.HTML().Render("add_subscription", args)
+	response.HTML().Render("add_subscription", ctx.UserLanguage(), args)
 }
 
 // SubmitSubscription try to find a feed from the URL provided by the user.
@@ -52,7 +52,7 @@ func (c *Controller) SubmitSubscription(ctx *handler.Context, request *handler.R
 
 	subscriptionForm := form.NewSubscriptionForm(request.Request())
 	if err := subscriptionForm.Validate(); err != nil {
-		response.HTML().Render("add_subscription", args.Merge(tplParams{
+		response.HTML().Render("add_subscription", ctx.UserLanguage(), args.Merge(tplParams{
 			"form":         subscriptionForm,
 			"errorMessage": err.Error(),
 		}))
@@ -62,7 +62,7 @@ func (c *Controller) SubmitSubscription(ctx *handler.Context, request *handler.R
 	subscriptions, err := subscription.FindSubscriptions(subscriptionForm.URL)
 	if err != nil {
 		logger.Error("[Controller:SubmitSubscription] %v", err)
-		response.HTML().Render("add_subscription", args.Merge(tplParams{
+		response.HTML().Render("add_subscription", ctx.UserLanguage(), args.Merge(tplParams{
 			"form":         subscriptionForm,
 			"errorMessage": err,
 		}))
@@ -74,14 +74,14 @@ func (c *Controller) SubmitSubscription(ctx *handler.Context, request *handler.R
 	n := len(subscriptions)
 	switch {
 	case n == 0:
-		response.HTML().Render("add_subscription", args.Merge(tplParams{
+		response.HTML().Render("add_subscription", ctx.UserLanguage(), args.Merge(tplParams{
 			"form":         subscriptionForm,
 			"errorMessage": "Unable to find any subscription.",
 		}))
 	case n == 1:
 		feed, err := c.feedHandler.CreateFeed(user.ID, subscriptionForm.CategoryID, subscriptions[0].URL, subscriptionForm.Crawler)
 		if err != nil {
-			response.HTML().Render("add_subscription", args.Merge(tplParams{
+			response.HTML().Render("add_subscription", ctx.UserLanguage(), args.Merge(tplParams{
 				"form":         subscriptionForm,
 				"errorMessage": err,
 			}))
@@ -90,7 +90,7 @@ func (c *Controller) SubmitSubscription(ctx *handler.Context, request *handler.R
 
 		response.Redirect(ctx.Route("feedEntries", "feedID", feed.ID))
 	case n > 1:
-		response.HTML().Render("choose_subscription", args.Merge(tplParams{
+		response.HTML().Render("choose_subscription", ctx.UserLanguage(), args.Merge(tplParams{
 			"categoryID":    subscriptionForm.CategoryID,
 			"subscriptions": subscriptions,
 		}))
@@ -109,7 +109,7 @@ func (c *Controller) ChooseSubscription(ctx *handler.Context, request *handler.R
 
 	subscriptionForm := form.NewSubscriptionForm(request.Request())
 	if err := subscriptionForm.Validate(); err != nil {
-		response.HTML().Render("add_subscription", args.Merge(tplParams{
+		response.HTML().Render("add_subscription", ctx.UserLanguage(), args.Merge(tplParams{
 			"form":         subscriptionForm,
 			"errorMessage": err.Error(),
 		}))
@@ -118,7 +118,7 @@ func (c *Controller) ChooseSubscription(ctx *handler.Context, request *handler.R
 
 	feed, err := c.feedHandler.CreateFeed(user.ID, subscriptionForm.CategoryID, subscriptionForm.URL, subscriptionForm.Crawler)
 	if err != nil {
-		response.HTML().Render("add_subscription", args.Merge(tplParams{
+		response.HTML().Render("add_subscription", ctx.UserLanguage(), args.Merge(tplParams{
 			"form":         subscriptionForm,
 			"errorMessage": err,
 		}))

+ 1 - 1
ui/unread.go

@@ -39,7 +39,7 @@ func (c *Controller) ShowUnreadPage(ctx *handler.Context, request *handler.Reque
 		return
 	}
 
-	response.HTML().Render("unread", tplParams{
+	response.HTML().Render("unread", ctx.UserLanguage(), tplParams{
 		"user":        user,
 		"countUnread": countUnread,
 		"entries":     entries,

+ 9 - 9
ui/user.go

@@ -35,7 +35,7 @@ func (c *Controller) ShowUsers(ctx *handler.Context, request *handler.Request, r
 	}
 
 	users.UseTimezone(user.Timezone)
-	response.HTML().Render("users", args.Merge(tplParams{
+	response.HTML().Render("users", ctx.UserLanguage(), args.Merge(tplParams{
 		"users": users,
 		"menu":  "settings",
 	}))
@@ -56,7 +56,7 @@ func (c *Controller) CreateUser(ctx *handler.Context, request *handler.Request,
 		return
 	}
 
-	response.HTML().Render("create_user", args.Merge(tplParams{
+	response.HTML().Render("create_user", ctx.UserLanguage(), args.Merge(tplParams{
 		"menu": "settings",
 		"form": &form.UserForm{},
 	}))
@@ -79,7 +79,7 @@ func (c *Controller) SaveUser(ctx *handler.Context, request *handler.Request, re
 
 	userForm := form.NewUserForm(request.Request())
 	if err := userForm.ValidateCreation(); err != nil {
-		response.HTML().Render("create_user", args.Merge(tplParams{
+		response.HTML().Render("create_user", ctx.UserLanguage(), args.Merge(tplParams{
 			"menu":         "settings",
 			"form":         userForm,
 			"errorMessage": err.Error(),
@@ -88,7 +88,7 @@ func (c *Controller) SaveUser(ctx *handler.Context, request *handler.Request, re
 	}
 
 	if c.store.UserExists(userForm.Username) {
-		response.HTML().Render("create_user", args.Merge(tplParams{
+		response.HTML().Render("create_user", ctx.UserLanguage(), args.Merge(tplParams{
 			"menu":         "settings",
 			"form":         userForm,
 			"errorMessage": "This user already exists.",
@@ -99,7 +99,7 @@ func (c *Controller) SaveUser(ctx *handler.Context, request *handler.Request, re
 	newUser := userForm.ToUser()
 	if err := c.store.CreateUser(newUser); err != nil {
 		logger.Error("[Controller:SaveUser] %v", err)
-		response.HTML().Render("edit_user", args.Merge(tplParams{
+		response.HTML().Render("edit_user", ctx.UserLanguage(), args.Merge(tplParams{
 			"menu":         "settings",
 			"form":         userForm,
 			"errorMessage": "Unable to create this user.",
@@ -130,7 +130,7 @@ func (c *Controller) EditUser(ctx *handler.Context, request *handler.Request, re
 		return
 	}
 
-	response.HTML().Render("edit_user", args.Merge(tplParams{
+	response.HTML().Render("edit_user", ctx.UserLanguage(), args.Merge(tplParams{
 		"menu":          "settings",
 		"selected_user": selectedUser,
 		"form": &form.UserForm{
@@ -162,7 +162,7 @@ func (c *Controller) UpdateUser(ctx *handler.Context, request *handler.Request,
 
 	userForm := form.NewUserForm(request.Request())
 	if err := userForm.ValidateModification(); err != nil {
-		response.HTML().Render("edit_user", args.Merge(tplParams{
+		response.HTML().Render("edit_user", ctx.UserLanguage(), args.Merge(tplParams{
 			"menu":          "settings",
 			"selected_user": selectedUser,
 			"form":          userForm,
@@ -172,7 +172,7 @@ func (c *Controller) UpdateUser(ctx *handler.Context, request *handler.Request,
 	}
 
 	if c.store.AnotherUserExists(selectedUser.ID, userForm.Username) {
-		response.HTML().Render("edit_user", args.Merge(tplParams{
+		response.HTML().Render("edit_user", ctx.UserLanguage(), args.Merge(tplParams{
 			"menu":          "settings",
 			"selected_user": selectedUser,
 			"form":          userForm,
@@ -184,7 +184,7 @@ func (c *Controller) UpdateUser(ctx *handler.Context, request *handler.Request,
 	userForm.Merge(selectedUser)
 	if err := c.store.UpdateUser(selectedUser); err != nil {
 		logger.Error("[Controller:UpdateUser] %v", err)
-		response.HTML().Render("edit_user", args.Merge(tplParams{
+		response.HTML().Render("edit_user", ctx.UserLanguage(), args.Merge(tplParams{
 			"menu":          "settings",
 			"selected_user": selectedUser,
 			"form":          userForm,