Skip to content

Commit

Permalink
feat: New Localization module (#350)
Browse files Browse the repository at this point in the history
* add localization feature

* add test cases for translator

* increase test coverage for file_loader

* add test cases for the remaining function of translator

* add test cases for the remaining function of translator

* add set method using http context

* chore: update mocks

* add SetLocale from http context

* chore: update mocks

* add assertion for http context in SetLocale

* re-order methods in translation contract

* fix linting

* fix formatting of error for translation

---------

Co-authored-by: kkumar-gcc <kkumar-gcc@users.noreply.github.com>
  • Loading branch information
kkumar-gcc and kkumar-gcc committed Nov 23, 2023
1 parent 8ad1862 commit a5bf78d
Show file tree
Hide file tree
Showing 21 changed files with 1,655 additions and 1 deletion.
12 changes: 12 additions & 0 deletions contracts/foundation/application.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package foundation

import (
"context"

"github.com/goravel/framework/contracts/console"
)

Expand All @@ -20,8 +22,18 @@ type Application interface {
DatabasePath(path string) string
// StoragePath get the path to the storage directory.
StoragePath(path string) string
// LangPath get the path to the language files.
LangPath(path string) string
// PublicPath get the path to the public directory.
PublicPath(path string) string
// Publishes register the given paths to be published by the "vendor:publish" command.
Publishes(packageName string, paths map[string]string, groups ...string)
// GetLocale get the current application locale.
GetLocale(ctx context.Context) string
// SetLocale set the current application locale.
SetLocale(ctx context.Context, locale string) context.Context
// Version gets the version number of the application.
Version() string
// IsLocale get the current application locale.
IsLocale(ctx context.Context, locale string) bool
}
5 changes: 5 additions & 0 deletions contracts/foundation/container.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package foundation

import (
"context"

"github.com/goravel/framework/contracts/auth"
"github.com/goravel/framework/contracts/auth/access"
"github.com/goravel/framework/contracts/cache"
Expand All @@ -20,6 +22,7 @@ import (
"github.com/goravel/framework/contracts/route"
"github.com/goravel/framework/contracts/schedule"
"github.com/goravel/framework/contracts/testing"
"github.com/goravel/framework/contracts/translation"
"github.com/goravel/framework/contracts/validation"
)

Expand Down Expand Up @@ -50,6 +53,8 @@ type Container interface {
MakeGrpc() grpc.Grpc
// MakeHash resolves the hash instance.
MakeHash() hash.Hash
// MakeLang resolves the lang instance.
MakeLang(ctx context.Context) translation.Translator
// MakeLog resolves the log instance.
MakeLog() log.Log
// MakeMail resolves the mail instance.
Expand Down
6 changes: 6 additions & 0 deletions contracts/translation/loader.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package translation

type Loader interface {
// Load the messages for the given locale.
Load(folder string, locale string) (map[string]map[string]string, error)
}
32 changes: 32 additions & 0 deletions contracts/translation/translator.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package translation

import (
"context"
)

type Translator interface {
// Choice gets a translation according to an integer value.
Choice(key string, number int, options ...Option) (string, error)
// Get the translation for the given key.
Get(key string, options ...Option) (string, error)
// GetFallback get the current application/context fallback locale.
GetFallback() string
// GetLocale get the current application/context locale.
GetLocale() string
// Has checks if a translation exists for a given key.
Has(key string, options ...Option) bool
// SetFallback set the current application/context fallback locale.
SetFallback(locale string) context.Context
// SetLocale set the current application/context locale.
SetLocale(locale string) context.Context
}

type Option struct {
Fallback *bool
Locale string
Replace map[string]string
}

func Bool(value bool) *bool {
return &value
}
11 changes: 11 additions & 0 deletions facades/lang.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package facades

import (
"context"

"github.com/goravel/framework/contracts/translation"
)

func Lang(ctx context.Context) translation.Translator {
return App().MakeLang(ctx)
}
23 changes: 22 additions & 1 deletion foundation/application.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package foundation

import (
"context"
"flag"
"os"
"path/filepath"
Expand Down Expand Up @@ -81,6 +82,10 @@ func (app *Application) StoragePath(path string) string {
return filepath.Join("storage", path)
}

func (app *Application) LangPath(path string) string {
return filepath.Join("lang", path)
}

func (app *Application) PublicPath(path string) string {
return filepath.Join("public", path)
}
Expand All @@ -97,6 +102,22 @@ func (app *Application) Publishes(packageName string, paths map[string]string, g
}
}

func (app *Application) Version() string {
return support.Version
}

func (app *Application) GetLocale(ctx context.Context) string {
return app.MakeLang(ctx).GetLocale()
}

func (app *Application) SetLocale(ctx context.Context, locale string) context.Context {
return app.MakeLang(ctx).SetLocale(locale)
}

func (app *Application) IsLocale(ctx context.Context, locale string) bool {
return app.GetLocale(ctx) == locale
}

func (app *Application) ensurePublishArrayInitialized(packageName string) {
if _, exist := app.publishes[packageName]; !exist {
app.publishes[packageName] = make(map[string]string)
Expand Down Expand Up @@ -219,7 +240,7 @@ func setEnv() {
func setRootPath() {
rootPath := getCurrentAbsolutePath()

// Hack air path
// Hack the air path
airPath := "/storage/temp"
if strings.HasSuffix(rootPath, airPath) {
rootPath = strings.ReplaceAll(rootPath, airPath, "")
Expand Down
18 changes: 18 additions & 0 deletions foundation/application_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import (
supportdocker "github.com/goravel/framework/support/docker"
"github.com/goravel/framework/support/env"
"github.com/goravel/framework/support/file"
frameworktranslation "github.com/goravel/framework/translation"
"github.com/goravel/framework/validation"
)

Expand Down Expand Up @@ -234,6 +235,23 @@ func (s *ApplicationTestSuite) TestMakeHash() {
mockConfig.AssertExpectations(s.T())
}

func (s *ApplicationTestSuite) TestMakeLang() {
mockConfig := &configmocks.Config{}
mockConfig.On("GetString", "app.locale").Return("en").Once()
mockConfig.On("GetString", "app.fallback_locale").Return("en").Once()

s.app.Singleton(frameworkconfig.Binding, func(app foundation.Application) (any, error) {
return mockConfig, nil
})

serviceProvider := &frameworktranslation.ServiceProvider{}
serviceProvider.Register(s.app)
ctx := http.Background()

s.NotNil(s.app.MakeLang(ctx))
mockConfig.AssertExpectations(s.T())
}

func (s *ApplicationTestSuite) TestMakeLog() {
serviceProvider := &frameworklog.ServiceProvider{}
serviceProvider.Register(s.app)
Expand Down
15 changes: 15 additions & 0 deletions foundation/container.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package foundation

import (
"context"
"fmt"
"sync"

Expand Down Expand Up @@ -30,6 +31,7 @@ import (
routecontract "github.com/goravel/framework/contracts/route"
schedulecontract "github.com/goravel/framework/contracts/schedule"
testingcontract "github.com/goravel/framework/contracts/testing"
translationcontract "github.com/goravel/framework/contracts/translation"
validationcontract "github.com/goravel/framework/contracts/validation"
"github.com/goravel/framework/crypt"
"github.com/goravel/framework/database"
Expand All @@ -44,6 +46,7 @@ import (
"github.com/goravel/framework/route"
"github.com/goravel/framework/schedule"
"github.com/goravel/framework/testing"
"github.com/goravel/framework/translation"
"github.com/goravel/framework/validation"
)

Expand Down Expand Up @@ -167,6 +170,18 @@ func (c *Container) MakeHash() hashcontract.Hash {
return instance.(hashcontract.Hash)
}

func (c *Container) MakeLang(ctx context.Context) translationcontract.Translator {
instance, err := c.MakeWith(translation.Binding, map[string]any{
"ctx": ctx,
})
if err != nil {
color.Redln(err)
return nil
}

return instance.(translationcontract.Translator)
}

func (c *Container) MakeLog() logcontract.Log {
instance, err := c.Make(goravellog.Binding)
if err != nil {
Expand Down
1 change: 1 addition & 0 deletions http/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,4 @@ func (r *Context) Request() http.ContextRequest {
func (r *Context) Response() http.ContextResponse {
return nil
}

92 changes: 92 additions & 0 deletions mocks/foundation/Application.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit a5bf78d

Please sign in to comment.