Merge pull request #629 from trheyi/main
[add] Generating language packs during SUI compilation
This commit is contained in:
commit
fe7e5bb886
7 changed files with 333 additions and 30 deletions
|
|
@ -10,10 +10,13 @@ import (
|
||||||
"github.com/PuerkitoBio/goquery"
|
"github.com/PuerkitoBio/goquery"
|
||||||
jsoniter "github.com/json-iterator/go"
|
jsoniter "github.com/json-iterator/go"
|
||||||
"github.com/yaoapp/kun/log"
|
"github.com/yaoapp/kun/log"
|
||||||
|
"golang.org/x/net/html"
|
||||||
)
|
)
|
||||||
|
|
||||||
var slotRe = regexp.MustCompile(`\[\{([^\}]+)\}\]`)
|
var slotRe = regexp.MustCompile(`\[\{([^\}]+)\}\]`)
|
||||||
var cssRe = regexp.MustCompile(`([\.a-z0-9A-Z-:# ]+)\{`)
|
var cssRe = regexp.MustCompile(`([\.a-z0-9A-Z-:# ]+)\{`)
|
||||||
|
var langFuncRe = regexp.MustCompile(`L\s*\(\s*["'](.*?)["']\s*\)`)
|
||||||
|
var langAttrRe = regexp.MustCompile(`'::(.*?)'`)
|
||||||
|
|
||||||
// Build is the struct for the public
|
// Build is the struct for the public
|
||||||
func (page *Page) Build(option *BuildOption) (*goquery.Document, []string, error) {
|
func (page *Page) Build(option *BuildOption) (*goquery.Document, []string, error) {
|
||||||
|
|
@ -44,7 +47,7 @@ func (page *Page) Build(option *BuildOption) (*goquery.Document, []string, error
|
||||||
doc.Selection.Find("head").AppendHtml(style)
|
doc.Selection.Find("head").AppendHtml(style)
|
||||||
|
|
||||||
// Add Script
|
// Add Script
|
||||||
code, scripts, err := page.BuildScript(option)
|
code, scripts, err := page.BuildScript(option, option.Namespace)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
warnings = append(warnings, err.Error())
|
warnings = append(warnings, err.Error())
|
||||||
}
|
}
|
||||||
|
|
@ -100,7 +103,7 @@ func (page *Page) BuildForImport(option *BuildOption, slots map[string]interface
|
||||||
warnings = append(warnings, err.Error())
|
warnings = append(warnings, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
code, _, err := page.BuildScript(option)
|
code, _, err := page.BuildScript(option, option.Namespace)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
warnings = append(warnings, err.Error())
|
warnings = append(warnings, err.Error())
|
||||||
}
|
}
|
||||||
|
|
@ -125,6 +128,12 @@ func (page *Page) BuildForImport(option *BuildOption, slots map[string]interface
|
||||||
func (page *Page) parse(doc *goquery.Document, option *BuildOption, warnings []string) error {
|
func (page *Page) parse(doc *goquery.Document, option *BuildOption, warnings []string) error {
|
||||||
|
|
||||||
pages := doc.Find("*").FilterFunction(func(i int, sel *goquery.Selection) bool {
|
pages := doc.Find("*").FilterFunction(func(i int, sel *goquery.Selection) bool {
|
||||||
|
|
||||||
|
// Get the translation
|
||||||
|
if translations := getNodeTranslation(sel, i, option.Namespace); len(translations) > 0 {
|
||||||
|
page.Translations = append(page.Translations, translations...)
|
||||||
|
}
|
||||||
|
|
||||||
tagName := sel.Get(0).Data
|
tagName := sel.Get(0).Data
|
||||||
if tagName == "page" {
|
if tagName == "page" {
|
||||||
return true
|
return true
|
||||||
|
|
@ -218,6 +227,9 @@ func (page *Page) parse(doc *goquery.Document, option *BuildOption, warnings []s
|
||||||
Namespace: namespace,
|
Namespace: namespace,
|
||||||
}, slots, attrs)
|
}, slots, attrs)
|
||||||
|
|
||||||
|
// append translations
|
||||||
|
page.Translations = append(page.Translations, p.Translations...)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
sel.ReplaceWith(fmt.Sprintf("<!-- %s -->", err.Error()))
|
sel.ReplaceWith(fmt.Sprintf("<!-- %s -->", err.Error()))
|
||||||
log.Warn("Page %s/%s/%s: %s", page.SuiID, page.TemplateID, page.Route, err.Error())
|
log.Warn("Page %s/%s/%s: %s", page.SuiID, page.TemplateID, page.Route, err.Error())
|
||||||
|
|
@ -313,7 +325,7 @@ func (page *Page) BuildStyle(option *BuildOption) (string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// BuildScript build the script
|
// BuildScript build the script
|
||||||
func (page *Page) BuildScript(option *BuildOption) (string, []string, error) {
|
func (page *Page) BuildScript(option *BuildOption, namespace string) (string, []string, error) {
|
||||||
|
|
||||||
if page.Codes.JS.Code == "" && page.Codes.TS.Code == "" {
|
if page.Codes.JS.Code == "" && page.Codes.TS.Code == "" {
|
||||||
return "", nil, nil
|
return "", nil, nil
|
||||||
|
|
@ -345,7 +357,7 @@ func (page *Page) BuildScript(option *BuildOption) (string, []string, error) {
|
||||||
return fmt.Sprintf("<script type=\"text/javascript\">\nfunction %s(){\n%s\n}\n</script>\n", option.Namespace, addTabToEachLine(string(code))), scripts, nil
|
return fmt.Sprintf("<script type=\"text/javascript\">\nfunction %s(){\n%s\n}\n</script>\n", option.Namespace, addTabToEachLine(string(code))), scripts, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
code, scripts, err := page.CompileJS([]byte(page.Codes.JS.Code), false)
|
code, scripts, err := page.CompileJS([]byte(page.Codes.JS.Code), true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", nil, err
|
return "", nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -367,6 +379,11 @@ func (page *Page) BuildScript(option *BuildOption) (string, []string, error) {
|
||||||
return fmt.Sprintf("<script type=\"text/javascript\">\n%s\n</script>\n", code), scripts, nil
|
return fmt.Sprintf("<script type=\"text/javascript\">\n%s\n</script>\n", code), scripts, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get the translation
|
||||||
|
if translations := getScriptTranslation(string(code), namespace); len(translations) > 0 {
|
||||||
|
page.Translations = append(page.Translations, translations...)
|
||||||
|
}
|
||||||
|
|
||||||
return fmt.Sprintf("<script type=\"text/javascript\">\nfunction %s(){\n%s\n}\n</script>\n", option.Namespace, addTabToEachLine(string(code))), scripts, nil
|
return fmt.Sprintf("<script type=\"text/javascript\">\nfunction %s(){\n%s\n}\n</script>\n", option.Namespace, addTabToEachLine(string(code))), scripts, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -387,3 +404,77 @@ func addTabToEachLine(input string, prefix ...string) string {
|
||||||
|
|
||||||
return strings.Join(lines, "\n")
|
return strings.Join(lines, "\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getScriptTranslation(code string, namespace string) []Translation {
|
||||||
|
translations := []Translation{}
|
||||||
|
matches := langFuncRe.FindAllStringSubmatch(code, -1)
|
||||||
|
for i, match := range matches {
|
||||||
|
translations = append(translations, Translation{
|
||||||
|
Key: fmt.Sprintf("%s_script_%d", namespace, i),
|
||||||
|
Message: match[1],
|
||||||
|
Type: "script",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return translations
|
||||||
|
}
|
||||||
|
|
||||||
|
func getNodeTranslation(sel *goquery.Selection, index int, namespace string) []Translation {
|
||||||
|
|
||||||
|
translations := []Translation{}
|
||||||
|
nodeType := sel.Get(0).Type
|
||||||
|
switch nodeType {
|
||||||
|
case html.ElementNode:
|
||||||
|
|
||||||
|
// Get the translation
|
||||||
|
if typ, has := sel.Attr("s:trans"); has {
|
||||||
|
typ = strings.TrimSpace(typ)
|
||||||
|
if typ == "" {
|
||||||
|
typ = "html"
|
||||||
|
}
|
||||||
|
translations = append(translations, Translation{
|
||||||
|
Key: fmt.Sprintf("%s_index_%d", namespace, index),
|
||||||
|
Message: strings.TrimSpace(sel.Text()),
|
||||||
|
Type: typ,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attributes
|
||||||
|
for i, attr := range sel.Get(0).Attr {
|
||||||
|
|
||||||
|
// value="::attr"
|
||||||
|
if strings.HasPrefix(attr.Val, "::") {
|
||||||
|
translations = append(translations, Translation{
|
||||||
|
Key: fmt.Sprintf("%s_index_attr_%d_%d", namespace, index, i),
|
||||||
|
Message: attr.Val[2:],
|
||||||
|
Name: attr.Key,
|
||||||
|
Type: "attr",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// value="{{ 'key': '::value' }}"
|
||||||
|
matches := langAttrRe.FindAllStringSubmatch(attr.Val, -1)
|
||||||
|
if len(matches) > 0 {
|
||||||
|
for j, match := range matches {
|
||||||
|
translations = append(translations, Translation{
|
||||||
|
Key: fmt.Sprintf("%s_index_attr_%d_%d_%d", namespace, index, i, j),
|
||||||
|
Message: match[1],
|
||||||
|
Name: attr.Key,
|
||||||
|
Type: "attr",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case html.TextNode:
|
||||||
|
if strings.HasPrefix(sel.Text(), "::") {
|
||||||
|
translations = append(translations, Translation{
|
||||||
|
Key: fmt.Sprintf("%s_index_%d", namespace, index),
|
||||||
|
Message: strings.TrimSpace(sel.Text()[2:]),
|
||||||
|
Type: "text",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return translations
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,7 @@ func (page *Page) CompileJS(source []byte, minify bool) ([]byte, []string, error
|
||||||
}
|
}
|
||||||
jsCode := importRe.ReplaceAllString(string(source), "")
|
jsCode := importRe.ReplaceAllString(string(source), "")
|
||||||
if minify {
|
if minify {
|
||||||
minified, err := transform.MinifyJS(jsCode)
|
minified, err := transform.MinifyJS(jsCode, api.ES2015)
|
||||||
return []byte(minified), scripts, err
|
return []byte(minified), scripts, err
|
||||||
}
|
}
|
||||||
return []byte(jsCode), scripts, nil
|
return []byte(jsCode), scripts, nil
|
||||||
|
|
@ -99,7 +99,7 @@ func (page *Page) CompileTS(source []byte, minify bool) ([]byte, []string, error
|
||||||
tsCode := importRe.ReplaceAllString(string(source), "")
|
tsCode := importRe.ReplaceAllString(string(source), "")
|
||||||
if minify {
|
if minify {
|
||||||
jsCode, err := transform.TypeScript(string(tsCode), api.TransformOptions{
|
jsCode, err := transform.TypeScript(string(tsCode), api.TransformOptions{
|
||||||
Target: api.ESNext,
|
Target: api.ES2015,
|
||||||
MinifyWhitespace: true,
|
MinifyWhitespace: true,
|
||||||
MinifyIdentifiers: true,
|
MinifyIdentifiers: true,
|
||||||
MinifySyntax: true,
|
MinifySyntax: true,
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,53 @@ type Page struct {
|
||||||
Document []byte `json:"-"`
|
Document []byte `json:"-"`
|
||||||
GlobalData []byte `json:"-"`
|
GlobalData []byte `json:"-"`
|
||||||
Attrs map[string]string `json:"-"`
|
Attrs map[string]string `json:"-"`
|
||||||
|
Translations []Translation `json:"-"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Translation is the struct for the translation
|
||||||
|
type Translation struct {
|
||||||
|
Key string `json:"key,omitempty"`
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
|
Message string `json:"message,omitempty"`
|
||||||
|
Type string `json:"type,omitempty"` // ENUM: 'text', 'html', 'attr', 'script'
|
||||||
|
}
|
||||||
|
|
||||||
|
// Locale is the struct for the locale
|
||||||
|
type Locale struct {
|
||||||
|
Keys map[string]string `json:"keys,omitempty"`
|
||||||
|
Messages map[string]string `json:"messages,omitempty"`
|
||||||
|
Date LocaleDate `json:"date,omitempty"`
|
||||||
|
Currency LocaleCurrency `json:"currency,omitempty"`
|
||||||
|
Number LocaleNumber `json:"number,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// LocaleDate the struct for the locale date format
|
||||||
|
type LocaleDate struct {
|
||||||
|
Short string `json:"short,omitempty"`
|
||||||
|
Long string `json:"long,omitempty"`
|
||||||
|
Full string `json:"full,omitempty"`
|
||||||
|
Month string `json:"month,omitempty"`
|
||||||
|
Week string `json:"week,omitempty"`
|
||||||
|
Year string `json:"year,omitempty"`
|
||||||
|
Day string `json:"day,omitempty"`
|
||||||
|
Human string `json:"human,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// LocaleCurrency the struct for the locale currency
|
||||||
|
type LocaleCurrency struct {
|
||||||
|
Format string `json:"format,omitempty"`
|
||||||
|
Unit string `json:"unit,omitempty"`
|
||||||
|
Separator string `json:"separator,omitempty"`
|
||||||
|
Delimiter string `json:"delimiter,omitempty"`
|
||||||
|
Precision int `json:"precision,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// LocaleNumber the struct for the locale number
|
||||||
|
type LocaleNumber struct {
|
||||||
|
Format string `json:"format,omitempty"`
|
||||||
|
Separator string `json:"separator,omitempty"`
|
||||||
|
Delimiter string `json:"delimiter,omitempty"`
|
||||||
|
Precision int `json:"precision,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// PageTreeNode is the struct for the page tree node
|
// PageTreeNode is the struct for the page tree node
|
||||||
|
|
@ -87,6 +134,7 @@ type Template struct {
|
||||||
Descrption string `json:"description"`
|
Descrption string `json:"description"`
|
||||||
Screenshots []string `json:"screenshots"`
|
Screenshots []string `json:"screenshots"`
|
||||||
Themes []SelectOption `json:"themes"`
|
Themes []SelectOption `json:"themes"`
|
||||||
|
Locales []SelectOption `json:"locales"`
|
||||||
Document []byte `json:"-"`
|
Document []byte `json:"-"`
|
||||||
GlobalData []byte `json:"-"`
|
GlobalData []byte `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ import (
|
||||||
"github.com/yaoapp/gou/application"
|
"github.com/yaoapp/gou/application"
|
||||||
"github.com/yaoapp/kun/log"
|
"github.com/yaoapp/kun/log"
|
||||||
"github.com/yaoapp/yao/sui/core"
|
"github.com/yaoapp/yao/sui/core"
|
||||||
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Build the template
|
// Build the template
|
||||||
|
|
@ -124,7 +125,13 @@ func (page *Page) Build(option *core.BuildOption) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save the html
|
// Save the html
|
||||||
return page.writeHTML([]byte(html), option.Data)
|
err = page.writeHTML([]byte(html), option.Data)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save the locale files
|
||||||
|
return page.writeLocaleFiles(option.Data)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (page *Page) publicFile(data map[string]interface{}) string {
|
func (page *Page) publicFile(data map[string]interface{}) string {
|
||||||
|
|
@ -136,6 +143,156 @@ func (page *Page) publicFile(data map[string]interface{}) string {
|
||||||
return filepath.Join("/", "public", root, page.Route)
|
return filepath.Join("/", "public", root, page.Route)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (page *Page) localeFiles(data map[string]interface{}) map[string]string {
|
||||||
|
root, err := page.tmpl.local.DSL.PublicRoot(data)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("publicFile: Get the public root error: %s. use %s", err.Error(), page.tmpl.local.DSL.Public.Root)
|
||||||
|
root = page.tmpl.local.DSL.Public.Root
|
||||||
|
}
|
||||||
|
|
||||||
|
roots := map[string]string{}
|
||||||
|
locales := page.tmpl.Locales()
|
||||||
|
for _, locale := range locales {
|
||||||
|
target := filepath.Join("/", "public", root, ".locales", locale.Value, fmt.Sprintf("%s.yml", page.Route))
|
||||||
|
roots[locale.Value] = target
|
||||||
|
}
|
||||||
|
return roots
|
||||||
|
}
|
||||||
|
|
||||||
|
func (page *Page) localeGlobal(name string) core.Locale {
|
||||||
|
global := core.Locale{
|
||||||
|
Keys: map[string]string{},
|
||||||
|
Messages: map[string]string{},
|
||||||
|
}
|
||||||
|
file := filepath.Join(page.tmpl.Root, "__locales", name, "__global.yml")
|
||||||
|
exist, err := page.tmpl.local.fs.Exists(file)
|
||||||
|
if err != nil {
|
||||||
|
log.Error(`[SUI] Check the global locale file error: %s`, err.Error())
|
||||||
|
return global
|
||||||
|
}
|
||||||
|
|
||||||
|
if !exist {
|
||||||
|
return global
|
||||||
|
}
|
||||||
|
|
||||||
|
raw, err := page.tmpl.local.fs.ReadFile(file)
|
||||||
|
if err != nil {
|
||||||
|
log.Error(`[SUI] Read the global locale file error: %s`, err.Error())
|
||||||
|
return global
|
||||||
|
}
|
||||||
|
|
||||||
|
err = yaml.Unmarshal(raw, &global)
|
||||||
|
if err != nil {
|
||||||
|
log.Error(`[SUI] Parse the global locale file error: %s`, err.Error())
|
||||||
|
return global
|
||||||
|
}
|
||||||
|
|
||||||
|
return global
|
||||||
|
}
|
||||||
|
|
||||||
|
func (page *Page) locale(name string) core.Locale {
|
||||||
|
file := filepath.Join(page.tmpl.Root, "__locales", name, fmt.Sprintf("%s.yml", page.Route))
|
||||||
|
global := page.localeGlobal(name)
|
||||||
|
|
||||||
|
// Check the locale file
|
||||||
|
exist, err := page.tmpl.local.fs.Exists(file)
|
||||||
|
if err != nil {
|
||||||
|
log.Error(`[SUI] Check the locale file error: %s`, err.Error())
|
||||||
|
return global
|
||||||
|
}
|
||||||
|
|
||||||
|
if !exist {
|
||||||
|
return global
|
||||||
|
}
|
||||||
|
|
||||||
|
locale := core.Locale{
|
||||||
|
Keys: map[string]string{},
|
||||||
|
Messages: map[string]string{},
|
||||||
|
Date: global.Date,
|
||||||
|
Currency: global.Currency,
|
||||||
|
Number: global.Number,
|
||||||
|
}
|
||||||
|
raw, err := page.tmpl.local.fs.ReadFile(file)
|
||||||
|
if err != nil {
|
||||||
|
log.Error(`[SUI] Read the locale file error: %s`, err.Error())
|
||||||
|
return global
|
||||||
|
}
|
||||||
|
|
||||||
|
err = yaml.Unmarshal(raw, &locale)
|
||||||
|
if err != nil {
|
||||||
|
log.Error(`[SUI] Parse the locale file error: %s`, err.Error())
|
||||||
|
return global
|
||||||
|
}
|
||||||
|
|
||||||
|
// Merge the global
|
||||||
|
for key, message := range global.Keys {
|
||||||
|
if _, ok := locale.Keys[key]; !ok {
|
||||||
|
locale.Keys[key] = message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for key, message := range global.Messages {
|
||||||
|
if _, ok := locale.Messages[key]; !ok {
|
||||||
|
locale.Messages[key] = message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return locale
|
||||||
|
}
|
||||||
|
|
||||||
|
func (page *Page) writeLocaleFiles(data map[string]interface{}) error {
|
||||||
|
|
||||||
|
// No translations
|
||||||
|
if len(page.Page.Translations) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
keys := map[string]string{}
|
||||||
|
messages := map[string]string{}
|
||||||
|
for _, t := range page.Page.Translations {
|
||||||
|
keys[t.Key] = t.Message
|
||||||
|
messages[t.Message] = t.Message
|
||||||
|
}
|
||||||
|
|
||||||
|
files := page.localeFiles(data)
|
||||||
|
for name, file := range files {
|
||||||
|
locale := page.locale(name)
|
||||||
|
for key := range keys {
|
||||||
|
if _, has := locale.Keys[key]; has {
|
||||||
|
keys[key] = locale.Keys[key]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for message := range messages {
|
||||||
|
if _, has := locale.Messages[message]; has {
|
||||||
|
messages[message] = locale.Messages[message]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
locale.Keys = keys
|
||||||
|
locale.Messages = messages
|
||||||
|
raw, err := yaml.Marshal(locale)
|
||||||
|
if err != nil {
|
||||||
|
log.Error(`[SUI] Marshal the locale file error: %s`, err.Error())
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
fileAbs := filepath.Join(application.App.Root(), file)
|
||||||
|
dir := filepath.Dir(fileAbs)
|
||||||
|
if exist, _ := os.Stat(dir); exist == nil {
|
||||||
|
os.MkdirAll(dir, os.ModePerm)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = os.WriteFile(fileAbs, raw, 0644)
|
||||||
|
if err != nil {
|
||||||
|
log.Error(`[SUI] Write the locale file error: %s`, err.Error())
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// writeHTMLTo write the html to file
|
// writeHTMLTo write the html to file
|
||||||
func (page *Page) writeHTML(html []byte, data map[string]interface{}) error {
|
func (page *Page) writeHTML(html []byte, data map[string]interface{}) error {
|
||||||
htmlFile := fmt.Sprintf("%s.sui", page.publicFile(data))
|
htmlFile := fmt.Sprintf("%s.sui", page.publicFile(data))
|
||||||
|
|
|
||||||
|
|
@ -284,6 +284,7 @@ func (tmpl *Template) CreateEmptyPage(route string, setting *core.PageSetting) (
|
||||||
SuiID: tmpl.local.ID,
|
SuiID: tmpl.local.ID,
|
||||||
Path: filepath.Join(tmpl.Root, route),
|
Path: filepath.Join(tmpl.Root, route),
|
||||||
Name: name,
|
Name: name,
|
||||||
|
Translations: []core.Translation{},
|
||||||
Codes: core.SourceCodes{
|
Codes: core.SourceCodes{
|
||||||
HTML: core.Source{File: fmt.Sprintf("%s.html", name)},
|
HTML: core.Source{File: fmt.Sprintf("%s.html", name)},
|
||||||
CSS: core.Source{File: fmt.Sprintf("%s.css", name)},
|
CSS: core.Source{File: fmt.Sprintf("%s.css", name)},
|
||||||
|
|
@ -354,6 +355,7 @@ func (tmpl *Template) getPage(route, file string) (core.IPage, error) {
|
||||||
Name: name,
|
Name: name,
|
||||||
TemplateID: tmpl.ID,
|
TemplateID: tmpl.ID,
|
||||||
SuiID: tmpl.local.ID,
|
SuiID: tmpl.local.ID,
|
||||||
|
Translations: []core.Translation{},
|
||||||
Codes: core.SourceCodes{
|
Codes: core.SourceCodes{
|
||||||
HTML: core.Source{File: fmt.Sprintf("%s%s", name, filepath.Ext(file))},
|
HTML: core.Source{File: fmt.Sprintf("%s%s", name, filepath.Ext(file))},
|
||||||
CSS: core.Source{File: fmt.Sprintf("%s.css", name)},
|
CSS: core.Source{File: fmt.Sprintf("%s.css", name)},
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,9 @@ func (tmpl *Template) GetRoot() string {
|
||||||
|
|
||||||
// Locales get the global locales
|
// Locales get the global locales
|
||||||
func (tmpl *Template) Locales() []core.SelectOption {
|
func (tmpl *Template) Locales() []core.SelectOption {
|
||||||
|
if tmpl.locales != nil {
|
||||||
|
return tmpl.locales
|
||||||
|
}
|
||||||
|
|
||||||
supportLocales := []core.SelectOption{}
|
supportLocales := []core.SelectOption{}
|
||||||
path := filepath.Join(tmpl.Root, "__locales")
|
path := filepath.Join(tmpl.Root, "__locales")
|
||||||
|
|
@ -47,7 +50,8 @@ func (tmpl *Template) Locales() []core.SelectOption {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return supportLocales
|
tmpl.locales = supportLocales
|
||||||
|
return tmpl.locales
|
||||||
}
|
}
|
||||||
|
|
||||||
// Themes get the global themes
|
// Themes get the global themes
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ type Local struct {
|
||||||
type Template struct {
|
type Template struct {
|
||||||
Root string `json:"-"`
|
Root string `json:"-"`
|
||||||
local *Local
|
local *Local
|
||||||
|
locales []core.SelectOption
|
||||||
*core.Template
|
*core.Template
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue