Comments (2)
@lordspinach I have zero experience doing i18n in Go. I've done it in Python programs in the past using gettext, but am not entirely sure where to start, so I'm open to discussion on this one. I think it would be nice:
- Use
Accept-Language
header to let clients request a language - Use existing content negotiation utilities to make this possible. This also means we probably need access to the request context in some new places in the code.
- Return a
Content-Language
response header when appropriate - Do not pull in a bunch of new dependencies. In fact I'd rather see code generation used if possible or vendoring some tiny lib to load strings instead of dependencies.
- We need to do this in a way that keeps memory allocations out of the hot path of request handling, e.g. precomputing/loading as much as possible on startup.
- We'll need some volunteers for initial translations.
Thanks!
from huma.
@danielgtaylor As an example solution i can suggest something like this from my current app:
//go:embed locales/*/data.yaml
var f embed.FS
// langMap is a map that contains supported locales in [en][validation][unexpected property] format
var langMap = make(map[string]map[string]map[string]string)
// LoadLocalesMap loads the language locales into the map variable by parsing the YAML data files.
func LoadLocalesMap() error {
err := parseLocalesToMap()
if err != nil {
return errors.Wrap(err, "failed to parse locales")
}
return nil
}
func T(ctx context.Context, path string, args ...any) string {
localeMap := ctx.Value("locale").(map[string]map[string]string)
p := strings.Split(path, ":")
category, key := p[0], p[1]
translation, ok := localeMap[category][key]
if !ok {
return ""
}
return fmt.Sprintf(translation, args...)
}
func GetSupportedLanguages() []string {
supportedLanguages := make([]string, 0, len(langMap))
for lang := range langMap {
supportedLanguages = append(supportedLanguages, lang)
}
return supportedLanguages
}
func GetLocaleMap(lang string) map[string]map[string]string {
return langMap[lang]
}
func parseLocalesToMap() error {
rootDir, err := f.ReadDir("locales")
if err != nil {
return gerro.Internal.Wrap(err, "can't read locales")
}
for _, locale := range rootDir {
file, err := f.ReadFile(fmt.Sprintf("locales/%s/data.yaml", locale.Name()))
if err != nil {
return errors.Wrap(err, fmt.Sprintf("can't read locales/%s/data.yaml", locale.Name()))
}
localeData := make(map[string]map[string]string)
err = yaml.Unmarshal(file, &localeData)
if err != nil {
return errors.Wrap(err, fmt.Sprintf("can't parse locales/%s/data.yaml", locale.Name()))
}
langMap[locale.Name()] = localeData
}
return nil
}
Here is an example of usage:
return huma.Error400BadRequest(i18n.T(ctx, "validation:Several validation errors occurred"), details...)
This implementation pretend to use ctx for load any of locale. As we load all locales into map at app start we keeps allocations on request at the same level. It allows us to get locale based on request's Accept-Language
and send corresponding Content-Language
. Also i think we should choose something else then embed fs for locales reading as it not support dynamic path change and it will make impossible to reassign locales in peoples apps.
I'm not in full dive into huma and not sure is it ok to send context to such a lot of a places and hope to get your thoughts on my suggestion
from huma.
Related Issues (20)
- Docs UI doesn't handle multiple cookies properly HOT 1
- Allow custom Transform for nested objects HOT 2
- Error thrown when setting cli name HOT 2
- Error return for huma.StreamResponse.Body HOT 1
- Schema(r huma.Registry) *huma.Schema not working on Pointer
- Question: Is there a way to add comments to fields? HOT 1
- Version Chi v4 Into Separate Release
- Removing schema reference in response HOT 2
- Multiline doc description for struct fields
- Bug: API doc hidden is not *real* hidden HOT 1
- Allow custom query param types.
- Required query parameter not going through validation when it is omitted HOT 1
- Generating Huma Code from OpenAPI Spec HOT 2
- Generating the openapi.json offline HOT 2
- Defining Servers Causes 404 from OpenAPI Endpoint HOT 1
- Unexported Fields in Schemas are Not Considered for Schema Generation HOT 2
- Any sample code to get http.Request.RemoteAddr in huma.context
- The validation of format:"email" is not perfect. HOT 3
- The default error response field value in openapi docs is "DEFAULT" HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from huma.