add a 'Context.SetLanguage', similar to pp.I18n.ExtractFunc but it can be used per-handler

relative: https://github.com/kataras/iris/issues/1502#issuecomment-623553034

Former-commit-id: 7e2fadeb60149f43edbb9e220b0274ce1160881b
This commit is contained in:
Gerasimos (Makis) Maropoulos 2020-05-04 19:13:06 +03:00
parent 68fda360db
commit 20fcfb4110
6 changed files with 65 additions and 9 deletions

View File

@ -394,7 +394,8 @@ Other Improvements:
New Context Methods:
- `Context.ServeContentWithRate`, `ServeFileWithRate` and `SendFileWithRate` methods to throttle the "download" speed of the client.
- `Context.SetLanguage(langCode string)` force-sets a language code from inside a middleare, similar to the `app.I18n.ExtractFunc`
- `Context.ServeContentWithRate`, `ServeFileWithRate` and `SendFileWithRate` methods to throttle the "download" speed of the client
- `Context.IsHTTP2() bool` reports whether the protocol version for incoming request was HTTP/2
- `Context.IsGRPC() bool` reports whether the request came from a gRPC client
- `Context.UpsertCookie(*http.Cookie, cookieOptions ...context.CookieOption)` upserts a cookie, fixes [#1485](https://github.com/kataras/iris/issues/1485) too

View File

@ -23,6 +23,7 @@ func newApp() *iris.Application {
// Set to false to disallow path (local) redirects,
// see https://github.com/kataras/iris/issues/1369.
// app.I18n.PathRedirect = true
// See app.I18n.ExtractFunc to change the way a language is extracted from a request.
app.Get("/", func(ctx iris.Context) {
hi := ctx.Tr("hi", "iris")

View File

@ -845,7 +845,17 @@ type Configuration struct {
//
// Defaults to "iris.locale".
LocaleContextKey string `json:"localeContextKey,omitempty" yaml:"LocaleContextKey" toml:"LocaleContextKey"`
// LanguageContextKey is the context key which a language can be modified by a middleware.
// It has the highest priority over the rest and if it is empty then it is ignored,
// if it set to a static string of "default" or to the default language's code
// then the rest of the language extractors will not be called at all and
// the default language will be set instead.
//
// Use with `Context.SetLanguage("el-GR")`.
//
// See `i18n.ExtractFunc` for a more organised way of the same feature.
// Defaults to "iris.locale.language".
LanguageContextKey string `json:"languageContextKey,omitempty" yaml:"LanguageContextKey" toml:"LanguageContextKey"`
// GetViewLayoutContextKey is the key of the context's user values' key
// which is being used to set the template
// layout from a middleware or the main handler.
@ -998,6 +1008,12 @@ func (c Configuration) GetLocaleContextKey() string {
return c.LocaleContextKey
}
// GetLanguageContextKey returns the configuration's LanguageContextKey value,
// used for i18n.
func (c Configuration) GetLanguageContextKey() string {
return c.LanguageContextKey
}
// GetViewLayoutContextKey returns the key of the context's user values' key
// which is being used to set the template
// layout from a middleware or the main handler.
@ -1132,6 +1148,10 @@ func WithConfiguration(c Configuration) Configurator {
main.LocaleContextKey = v
}
if v := c.LanguageContextKey; v != "" {
main.LanguageContextKey = v
}
if v := c.ViewLayoutContextKey; v != "" {
main.ViewLayoutContextKey = v
}
@ -1185,6 +1205,7 @@ func DefaultConfiguration() Configuration {
// or `context#SetMaxRequestBodySize`.
PostMaxMemory: 32 << 20, // 32MB
LocaleContextKey: "iris.locale",
LanguageContextKey: "iris.locale.language",
ViewLayoutContextKey: "iris.viewLayout",
ViewDataContextKey: "iris.viewData",
RemoteAddrHeaders: make(map[string]bool),

View File

@ -78,6 +78,9 @@ type ConfigurationReadOnly interface {
// GetTranslateLanguageContextKey returns the configuration's LocaleContextKey value,
// used for i18n. Defaults to "iris.locale".
GetLocaleContextKey() string
// GetLanguageContextKey returns the configuration's LanguageContextKey value,
// used for i18n. Defaults to "iris.locale.language".
GetLanguageContextKey() string
// GetViewLayoutContextKey returns the key of the context's user values' key
// which is being used to set the template

View File

@ -409,6 +409,14 @@ type Context interface {
// in https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy
// or by the URL query parameter "referer".
GetReferrer() Referrer
// SetLanguage force-sets the language for i18n, can be used inside a middleare.
// It has the highest priority over the rest and if it is empty then it is ignored,
// if it set to a static string of "default" or to the default language's code
// then the rest of the language extractors will not be called at all and
// the default language will be set instead.
//
// See `app.I18n.ExtractFunc` for a more organised way of the same feature.
SetLanguage(langCode string)
// GetLocale returns the current request's `Locale` found by i18n middleware.
// See `Tr` too.
GetLocale() Locale
@ -1975,9 +1983,21 @@ func (ctx *context) GetReferrer() Referrer {
return emptyReferrer
}
// SetLanguage force-sets the language for i18n, can be used inside a middleare.
// It has the highest priority over the rest and if it is empty then it is ignored,
// if it set to a static string of "default" or to the default language's code
// then the rest of the language extractors will not be called at all and
// the default language will be set instead.
//
// See `i18n.ExtractFunc` for a more organised way of the same feature.
func (ctx *context) SetLanguage(langCode string) {
ctx.Values().Set(ctx.app.ConfigurationReadOnly().GetLanguageContextKey(), langCode)
}
// GetLocale returns the current request's `Locale` found by i18n middleware.
// See `Tr` too.
func (ctx *context) GetLocale() Locale {
// Cache the Locale itself for multiple calls of `Tr` method.
contextKey := ctx.app.ConfigurationReadOnly().GetLocaleContextKey()
if v := ctx.Values().Get(contextKey); v != nil {
if locale, ok := v.(Locale); ok {

View File

@ -320,21 +320,31 @@ const acceptLanguageHeaderKey = "Accept-Language"
// GetLocale returns the found locale of a request.
// It will return the first registered language if nothing else matched.
func (i *I18n) GetLocale(ctx context.Context) context.Locale {
// if v := ctx.Values().Get(ctx.Application().ConfigurationReadOnly().GetLocaleContextKey()); v != nil {
// if locale, ok := v.(context.Locale); ok {
// return locale
// }
// }
var (
index int
ok bool
)
if contextKey := ctx.Application().ConfigurationReadOnly().GetLanguageContextKey(); contextKey != "" {
if v := ctx.Values().GetString(contextKey); v != "" {
if v == "default" {
index = 0 // no need to call `TryMatchString` and spend time.
} else {
_, index, _ = i.TryMatchString(v)
}
locale := i.localizer.GetLocale(index)
if locale == nil {
return nil
}
return locale
}
}
if !ok && i.ExtractFunc != nil {
if v := i.ExtractFunc(ctx); v != "" {
_, index, ok = i.TryMatchString(v)
}
}