Refactor SUI core to load backend scripts for templates
This commit is contained in:
parent
8d375e2222
commit
9418133b32
5 changed files with 152 additions and 13 deletions
|
|
@ -4,6 +4,7 @@ import (
|
|||
"time"
|
||||
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
v8 "github.com/yaoapp/gou/runtime/v8"
|
||||
"github.com/yaoapp/gou/store"
|
||||
"github.com/yaoapp/kun/log"
|
||||
)
|
||||
|
|
@ -20,6 +21,7 @@ type Cache struct {
|
|||
CacheStore string
|
||||
CacheTime time.Duration
|
||||
DataCacheTime time.Duration
|
||||
Script *v8.Script // the backend script
|
||||
}
|
||||
|
||||
const (
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import (
|
|||
"regexp"
|
||||
|
||||
"github.com/PuerkitoBio/goquery"
|
||||
v8 "github.com/yaoapp/gou/runtime/v8"
|
||||
"golang.org/x/net/html"
|
||||
)
|
||||
|
||||
|
|
@ -38,6 +39,7 @@ type Page struct {
|
|||
Path string `json:"-"`
|
||||
Root string `json:"-"`
|
||||
Codes SourceCodes `json:"-"`
|
||||
Script *v8.Script `json:"-"` // The backend script name.backend.ts / name.backend.js
|
||||
Document []byte `json:"-"`
|
||||
GlobalData []byte `json:"-"`
|
||||
Attrs map[string]string `json:"-"`
|
||||
|
|
@ -166,17 +168,19 @@ type LayoutItem struct {
|
|||
|
||||
// Template is the struct for the template
|
||||
type Template struct {
|
||||
Version int `json:"version"` // Yao Builder version
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Descrption string `json:"description"`
|
||||
Screenshots []string `json:"screenshots"`
|
||||
Themes []SelectOption `json:"themes"`
|
||||
Locales []SelectOption `json:"locales"`
|
||||
Document []byte `json:"-"`
|
||||
GlobalData []byte `json:"-"`
|
||||
Scripts *TemplateScirpts `json:"scripts,omitempty"`
|
||||
Translator string `json:"translator,omitempty"`
|
||||
Version int `json:"version"` // Yao Builder version
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Descrption string `json:"description"`
|
||||
Screenshots []string `json:"screenshots"`
|
||||
Themes []SelectOption `json:"themes"`
|
||||
Locales []SelectOption `json:"locales"`
|
||||
Document []byte `json:"-"`
|
||||
GlobalData []byte `json:"-"`
|
||||
Scripts *TemplateScirpts `json:"scripts,omitempty"`
|
||||
Translator string `json:"translator,omitempty"`
|
||||
BuildScript *v8.Script `json:"-"` // __build.backend.ts / __build.backend.js
|
||||
GlobalScript *v8.Script `json:"-"` // __global.backend.ts / __global.backend.js
|
||||
}
|
||||
|
||||
// TemplateScirpts is the struct for the template scripts
|
||||
|
|
|
|||
|
|
@ -54,6 +54,12 @@ func (tmpl *Template) Build(option *core.BuildOption) ([]string, error) {
|
|||
option.AssetRoot = filepath.Join(root, "assets")
|
||||
}
|
||||
|
||||
// Write the global script
|
||||
err = tmpl.writeGlobalScript(option.Data)
|
||||
if err != nil {
|
||||
return warnings, err
|
||||
}
|
||||
|
||||
// Sync the assets
|
||||
if err = tmpl.SyncAssets(option); err != nil {
|
||||
return warnings, err
|
||||
|
|
@ -192,6 +198,31 @@ func (tmpl *Template) SyncAssetFile(file string, option *core.BuildOption) error
|
|||
return copy(sourceFile, targetFile)
|
||||
}
|
||||
|
||||
func (tmpl *Template) writeGlobalScript(data map[string]interface{}) error {
|
||||
file, source, err := tmpl.backendScriptSource("__global.backend")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if source == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
name := filepath.Base(file)
|
||||
ext := filepath.Ext(name)
|
||||
root, err := tmpl.local.DSL.PublicRoot(data)
|
||||
if err != nil {
|
||||
log.Error("WriteGlobalScript: Get the public root error: %s. use %s", err.Error(), tmpl.local.DSL.Public.Root)
|
||||
root = tmpl.local.DSL.Public.Root
|
||||
}
|
||||
target := filepath.Join(application.App.Root(), "public", root, fmt.Sprintf("__global%s", ext))
|
||||
dir := filepath.Dir(target)
|
||||
if exist, _ := os.Stat(dir); exist == nil {
|
||||
os.MkdirAll(dir, os.ModePerm)
|
||||
}
|
||||
return os.WriteFile(target, source, 0644)
|
||||
}
|
||||
|
||||
// SyncAssets sync the assets
|
||||
func (tmpl *Template) SyncAssets(option *core.BuildOption) error {
|
||||
|
||||
|
|
@ -333,6 +364,12 @@ func (page *Page) Build(globalCtx *core.GlobalBuildContext, option *core.BuildOp
|
|||
return warnings, fmt.Errorf("Write the page %s error: %s", page.Route, err.Error())
|
||||
}
|
||||
|
||||
// Save the backend script file
|
||||
err = page.writeBackendScript(option.Data)
|
||||
if err != nil {
|
||||
return warnings, fmt.Errorf("Write the backend script file error: %s", err.Error())
|
||||
}
|
||||
|
||||
// Save the locale files
|
||||
err = page.writeLocaleFiles(ctx, option.Data)
|
||||
if err != nil {
|
||||
|
|
@ -604,6 +641,51 @@ func (page *Page) writeLocaleFiles(ctx *core.BuildContext, data map[string]inter
|
|||
return nil
|
||||
}
|
||||
|
||||
func (page *Page) backendScriptSource() (string, []byte, error) {
|
||||
backendFile := filepath.Join(page.Path, fmt.Sprintf("%s.backend.ts", page.Name))
|
||||
if exist, _ := page.tmpl.local.fs.Exists(backendFile); !exist {
|
||||
backendFile = filepath.Join(page.Path, fmt.Sprintf("%s.backend.js", page.Name))
|
||||
}
|
||||
|
||||
if exist, _ := page.tmpl.local.fs.Exists(backendFile); !exist {
|
||||
return "", nil, nil
|
||||
}
|
||||
|
||||
source, err := page.tmpl.local.fs.ReadFile(backendFile)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
|
||||
return backendFile, source, nil
|
||||
}
|
||||
|
||||
func (page *Page) writeBackendScript(data map[string]interface{}) error {
|
||||
|
||||
file, source, err := page.backendScriptSource()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if source == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
ext := filepath.Ext(file)
|
||||
scriptFile := fmt.Sprintf("%s%s", page.publicFile(data), ext)
|
||||
scriptFileAbs := filepath.Join(application.App.Root(), scriptFile)
|
||||
dir := filepath.Dir(scriptFileAbs)
|
||||
if exist, _ := os.Stat(dir); exist == nil {
|
||||
os.MkdirAll(dir, os.ModePerm)
|
||||
}
|
||||
|
||||
err = os.WriteFile(scriptFileAbs, []byte(source), 0644)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
core.RemoveCache(scriptFile)
|
||||
return nil
|
||||
}
|
||||
|
||||
// writeHTMLTo write the html to file
|
||||
func (page *Page) writeHTML(html []byte, data map[string]interface{}) error {
|
||||
htmlFile := fmt.Sprintf("%s.sui", page.publicFile(data))
|
||||
|
|
@ -618,7 +700,6 @@ func (page *Page) writeHTML(html []byte, data map[string]interface{}) error {
|
|||
}
|
||||
|
||||
core.RemoveCache(htmlFile)
|
||||
log.Trace("The page %s is removed", htmlFile)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -635,6 +716,5 @@ func (page *Page) writeJitHTML(html []byte, data map[string]interface{}) error {
|
|||
return err
|
||||
}
|
||||
core.RemoveCache(htmlFile)
|
||||
log.Trace("The page %s is removed", htmlFile)
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import (
|
|||
"strings"
|
||||
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
"github.com/yaoapp/gou/application"
|
||||
"github.com/yaoapp/gou/fs"
|
||||
"github.com/yaoapp/kun/log"
|
||||
"github.com/yaoapp/yao/sui/core"
|
||||
|
|
@ -156,6 +157,12 @@ func (local *Local) getTemplate(id string, path string) (*Template, error) {
|
|||
tmpl.GlobalData = dataBytes
|
||||
}
|
||||
|
||||
// load the __build.backend.ts / __build.backend.js
|
||||
err := tmpl.loadBuildScript()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &tmpl, nil
|
||||
}
|
||||
|
||||
|
|
@ -163,3 +170,10 @@ func (local *Local) getTemplate(id string, path string) (*Template, error) {
|
|||
func (local *Local) getTemplateID(path string) string {
|
||||
return filepath.Base(path)
|
||||
}
|
||||
|
||||
// AppRoot get the app root
|
||||
func (local *Local) AppRoot() string {
|
||||
approot := application.App.Root()
|
||||
localroot := local.fs.Root()
|
||||
return strings.TrimPrefix(localroot, approot)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import (
|
|||
|
||||
"github.com/google/uuid"
|
||||
"github.com/yaoapp/gou/process"
|
||||
v8 "github.com/yaoapp/gou/runtime/v8"
|
||||
"github.com/yaoapp/yao/sui/core"
|
||||
"golang.org/x/text/language"
|
||||
)
|
||||
|
|
@ -85,6 +86,44 @@ func (tmpl *Template) Reload() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// LoadBuildScript load the build script
|
||||
func (tmpl *Template) loadBuildScript() error {
|
||||
file, source, err := tmpl.backendScriptSource("__build.backend")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if file == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
approot := tmpl.local.AppRoot()
|
||||
file = filepath.Join(approot, file)
|
||||
script, err := v8.MakeScript(source, file, 5*time.Second)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tmpl.BuildScript = script
|
||||
return nil
|
||||
}
|
||||
|
||||
func (tmpl *Template) backendScriptSource(name string) (string, []byte, error) {
|
||||
path := filepath.Join(tmpl.Root, fmt.Sprintf("%s.ts", name))
|
||||
if !tmpl.local.fs.IsFile(path) {
|
||||
path = filepath.Join(tmpl.Root, fmt.Sprintf("%s.js", name))
|
||||
}
|
||||
|
||||
if !tmpl.local.fs.IsFile(path) {
|
||||
return "", nil, nil
|
||||
}
|
||||
|
||||
content, err := tmpl.local.fs.ReadFile(path)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
return path, content, nil
|
||||
}
|
||||
|
||||
// ExecBuildCompleteScripts execute the build complete scripts
|
||||
func (tmpl *Template) ExecBuildCompleteScripts() []core.TemplateScirptResult {
|
||||
if tmpl.Scripts == nil || len(tmpl.Scripts.BuildComplete) == 0 {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue