builder.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. package l10n
  2. import (
  3. "context"
  4. "net/http"
  5. "path"
  6. "time"
  7. "github.com/qor5/admin/utils"
  8. )
  9. type Builder struct {
  10. supportLocaleCodes []string
  11. localesPaths map[string]string
  12. paths []string
  13. localesLabels map[string]string
  14. getSupportLocaleCodesFromRequestFunc func(R *http.Request) []string
  15. cookieName string
  16. queryName string
  17. }
  18. func New() *Builder {
  19. b := &Builder{
  20. supportLocaleCodes: []string{},
  21. localesPaths: make(map[string]string),
  22. paths: []string{},
  23. localesLabels: make(map[string]string),
  24. cookieName: "locale",
  25. queryName: "locale",
  26. }
  27. return b
  28. }
  29. func (b *Builder) IsTurnedOn() bool {
  30. return len(b.GetSupportLocaleCodes()) > 0
  31. }
  32. func (b *Builder) GetCookieName() string {
  33. return b.cookieName
  34. }
  35. func (b *Builder) GetQueryName() string {
  36. return b.queryName
  37. }
  38. func (b *Builder) RegisterLocales(localeCode, localePath, localeLabel string) (r *Builder) {
  39. b.supportLocaleCodes = append(b.supportLocaleCodes, localeCode)
  40. b.localesPaths[localeCode] = path.Join("/", localePath)
  41. if !utils.Contains(b.paths, localePath) {
  42. b.paths = append(b.paths, localePath)
  43. }
  44. b.localesLabels[localeCode] = localeLabel
  45. return b
  46. }
  47. func (b *Builder) GetLocalePath(localeCode string) string {
  48. p, exist := b.localesPaths[localeCode]
  49. if exist {
  50. return p
  51. }
  52. return ""
  53. }
  54. func (b *Builder) GetAllLocalePaths() []string {
  55. return b.paths
  56. }
  57. func (b *Builder) GetLocaleLabel(localeCode string) string {
  58. label, exist := b.localesLabels[localeCode]
  59. if exist {
  60. return label
  61. }
  62. return "Unkonw"
  63. }
  64. func (b *Builder) GetSupportLocaleCodes() []string {
  65. return b.supportLocaleCodes
  66. }
  67. func (b *Builder) GetSupportLocaleCodesFromRequest(R *http.Request) []string {
  68. if b.getSupportLocaleCodesFromRequestFunc != nil {
  69. return b.getSupportLocaleCodesFromRequestFunc(R)
  70. }
  71. return b.GetSupportLocaleCodes()
  72. }
  73. func (b *Builder) GetSupportLocaleCodesFromRequestFunc(v func(R *http.Request) []string) (r *Builder) {
  74. b.getSupportLocaleCodesFromRequestFunc = v
  75. return b
  76. }
  77. func (b *Builder) GetCurrentLocaleCodeFromCookie(r *http.Request) (localeCode string) {
  78. localeCookie, _ := r.Cookie(b.cookieName)
  79. if localeCookie != nil {
  80. localeCode = localeCookie.Value
  81. }
  82. return
  83. }
  84. func (b *Builder) GetCorrectLocaleCode(r *http.Request) string {
  85. localeCode := r.FormValue(b.queryName)
  86. if localeCode == "" {
  87. localeCode = b.GetCurrentLocaleCodeFromCookie(r)
  88. }
  89. supportLocaleCodes := b.GetSupportLocaleCodesFromRequest(r)
  90. for _, v := range supportLocaleCodes {
  91. if localeCode == v {
  92. return v
  93. }
  94. }
  95. return supportLocaleCodes[0]
  96. }
  97. type l10nContextKey int
  98. const LocaleCode l10nContextKey = iota
  99. func (b *Builder) EnsureLocale(in http.Handler) (out http.Handler) {
  100. return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  101. if len(b.GetSupportLocaleCodesFromRequest(r)) == 0 {
  102. in.ServeHTTP(w, r)
  103. return
  104. }
  105. var localeCode = b.GetCorrectLocaleCode(r)
  106. maxAge := 365 * 24 * 60 * 60
  107. http.SetCookie(w, &http.Cookie{
  108. Name: b.cookieName,
  109. Value: localeCode,
  110. Path: "/",
  111. MaxAge: maxAge,
  112. Expires: time.Now().Add(time.Duration(maxAge) * time.Second),
  113. })
  114. ctx := context.WithValue(r.Context(), LocaleCode, localeCode)
  115. in.ServeHTTP(w, r.WithContext(ctx))
  116. })
  117. }