Merge pull request #632 from trheyi/main
[add] SUI language pack support (dev)
This commit is contained in:
commit
a63dc3f3ba
2 changed files with 133 additions and 10 deletions
|
|
@ -226,10 +226,12 @@ func (r *Request) Render() (string, int, error) {
|
||||||
|
|
||||||
// Set the page request data
|
// Set the page request data
|
||||||
option := core.ParserOption{
|
option := core.ParserOption{
|
||||||
Theme: r.Request.Theme,
|
Theme: r.Request.Theme,
|
||||||
Locale: r.Request.Locale,
|
Locale: r.Request.Locale,
|
||||||
Debug: r.Request.DebugMode(),
|
Debug: r.Request.DebugMode(),
|
||||||
Request: true,
|
DisableCache: r.Request.DisableCache(),
|
||||||
|
Route: r.Request.URL.Path,
|
||||||
|
Request: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse the template
|
// Parse the template
|
||||||
|
|
|
||||||
|
|
@ -2,12 +2,15 @@ package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/PuerkitoBio/goquery"
|
"github.com/PuerkitoBio/goquery"
|
||||||
jsoniter "github.com/json-iterator/go"
|
jsoniter "github.com/json-iterator/go"
|
||||||
|
"github.com/yaoapp/gou/application"
|
||||||
"github.com/yaoapp/kun/log"
|
"github.com/yaoapp/kun/log"
|
||||||
"golang.org/x/net/html"
|
"golang.org/x/net/html"
|
||||||
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TemplateParser parser for the template
|
// TemplateParser parser for the template
|
||||||
|
|
@ -18,6 +21,7 @@ type TemplateParser struct {
|
||||||
errors []error // errors
|
errors []error // errors
|
||||||
replace map[*goquery.Selection][]*html.Node // replace nodes
|
replace map[*goquery.Selection][]*html.Node // replace nodes
|
||||||
option *ParserOption // parser option
|
option *ParserOption // parser option
|
||||||
|
locale *Locale // locale
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mapping mapping for the template
|
// Mapping mapping for the template
|
||||||
|
|
@ -29,12 +33,14 @@ type Mapping struct {
|
||||||
|
|
||||||
// ParserOption parser option
|
// ParserOption parser option
|
||||||
type ParserOption struct {
|
type ParserOption struct {
|
||||||
Editor bool `json:"editor,omitempty"`
|
Editor bool `json:"editor,omitempty"`
|
||||||
Preview bool `json:"preview,omitempty"`
|
Preview bool `json:"preview,omitempty"`
|
||||||
Debug bool `json:"debug,omitempty"`
|
Debug bool `json:"debug,omitempty"`
|
||||||
Request bool `json:"request,omitempty"`
|
DisableCache bool `json:"disableCache,omitempty"`
|
||||||
Theme any `json:"theme,omitempty"`
|
Request bool `json:"request,omitempty"`
|
||||||
Locale any `json:"locale,omitempty"`
|
Route string `json:"route,omitempty"`
|
||||||
|
Theme any `json:"theme,omitempty"`
|
||||||
|
Locale any `json:"locale,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
var keepWords = map[string]bool{
|
var keepWords = map[string]bool{
|
||||||
|
|
@ -48,6 +54,94 @@ var keepWords = map[string]bool{
|
||||||
"s:bind": true,
|
"s:bind": true,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Locales the locales
|
||||||
|
var Locales = map[string]map[string]*Locale{}
|
||||||
|
|
||||||
|
type localeData struct {
|
||||||
|
name string
|
||||||
|
path string
|
||||||
|
locale *Locale
|
||||||
|
cmd uint8
|
||||||
|
}
|
||||||
|
|
||||||
|
var chLocale = make(chan *localeData, 1)
|
||||||
|
|
||||||
|
const (
|
||||||
|
saveLocale uint8 = iota
|
||||||
|
removeLocale
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
go localeWriter()
|
||||||
|
}
|
||||||
|
|
||||||
|
func localeWriter() {
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case data := <-chLocale:
|
||||||
|
switch data.cmd {
|
||||||
|
case saveLocale:
|
||||||
|
if _, ok := Locales[data.name]; !ok {
|
||||||
|
Locales[data.name] = map[string]*Locale{}
|
||||||
|
}
|
||||||
|
Locales[data.name][data.path] = data.locale
|
||||||
|
|
||||||
|
case removeLocale:
|
||||||
|
if _, ok := Locales[data.name]; ok {
|
||||||
|
delete(Locales[data.name], data.path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Locale get the locale
|
||||||
|
func (parser *TemplateParser) Locale() *Locale {
|
||||||
|
var locales map[string]*Locale = nil
|
||||||
|
name, ok := parser.option.Locale.(string)
|
||||||
|
if !ok {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
route := parser.option.Route
|
||||||
|
disableCache := parser.option.Preview || parser.option.Debug || parser.option.Editor || parser.option.DisableCache
|
||||||
|
|
||||||
|
locales, ok = Locales[name]
|
||||||
|
if !ok {
|
||||||
|
locales = map[string]*Locale{}
|
||||||
|
}
|
||||||
|
|
||||||
|
locale, ok := locales[route]
|
||||||
|
if ok && !disableCache {
|
||||||
|
return locale
|
||||||
|
}
|
||||||
|
|
||||||
|
path := filepath.Join("public", ".locales", name, route+".yml")
|
||||||
|
if exists, err := application.App.Exists(path); !exists {
|
||||||
|
if err != nil {
|
||||||
|
log.Error("[parser] %s Locale %s", route, err.Error())
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load the locale
|
||||||
|
locale = &Locale{}
|
||||||
|
raw, err := application.App.Read(path)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("[parser] %s Locale %s", route, err.Error())
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
err = yaml.Unmarshal(raw, locale)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("[parser] %s Locale %s", route, err.Error())
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
chLocale <- &localeData{name, route, locale, saveLocale}
|
||||||
|
return locale
|
||||||
|
}
|
||||||
|
|
||||||
// NewTemplateParser create a new template parser
|
// NewTemplateParser create a new template parser
|
||||||
func NewTemplateParser(data Data, option *ParserOption) *TemplateParser {
|
func NewTemplateParser(data Data, option *ParserOption) *TemplateParser {
|
||||||
if option == nil {
|
if option == nil {
|
||||||
|
|
@ -67,6 +161,9 @@ func NewTemplateParser(data Data, option *ParserOption) *TemplateParser {
|
||||||
// Render parses and renders the HTML template
|
// Render parses and renders the HTML template
|
||||||
func (parser *TemplateParser) Render(html string) (string, error) {
|
func (parser *TemplateParser) Render(html string) (string, error) {
|
||||||
|
|
||||||
|
// Set the locale
|
||||||
|
parser.locale = parser.Locale()
|
||||||
|
|
||||||
if !strings.Contains(html, "<html") {
|
if !strings.Contains(html, "<html") {
|
||||||
html = fmt.Sprintf(`<!DOCTYPE html><html lang="en-us">%s</html>`, html)
|
html = fmt.Sprintf(`<!DOCTYPE html><html lang="en-us">%s</html>`, html)
|
||||||
}
|
}
|
||||||
|
|
@ -178,6 +275,30 @@ func (parser *TemplateParser) parseElementNode(sel *goquery.Selection) {
|
||||||
|
|
||||||
// Parse the attributes
|
// Parse the attributes
|
||||||
parser.parseElementAttrs(sel)
|
parser.parseElementAttrs(sel)
|
||||||
|
|
||||||
|
// Translations
|
||||||
|
parser.transElementNode(sel)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (parser *TemplateParser) transElementNode(sel *goquery.Selection) {
|
||||||
|
if parser.locale == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, exist := sel.Attr("s:trans"); !exist {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
text := sel.Text()
|
||||||
|
message := strings.TrimSpace(text)
|
||||||
|
if message == "" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if lcMessage, has := parser.locale.Messages[message]; has {
|
||||||
|
sel.SetText(strings.Replace(text, message, lcMessage, 1))
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (parser *TemplateParser) setStatementNode(sel *goquery.Selection) {
|
func (parser *TemplateParser) setStatementNode(sel *goquery.Selection) {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue