refactor: Update build process to include SUI CompileAsComponent support (dev)
This commit is contained in:
parent
4f3f83523a
commit
a4f28368d4
5 changed files with 214 additions and 83 deletions
|
|
@ -86,88 +86,16 @@ func (r *Request) Render() (string, int, error) {
|
|||
|
||||
if c == nil {
|
||||
|
||||
// The page is not cached
|
||||
message := fmt.Sprintf("[SUI] The page %s is not cached. file=%s DisableCache=%v", r.Request.URL.Path, r.File, r.Request.DisableCache())
|
||||
go fmt.Println(color.YellowString(message))
|
||||
go log.Warn(message)
|
||||
|
||||
// Read the file
|
||||
content, err := application.App.Read(r.File)
|
||||
var status int
|
||||
var err error
|
||||
c, status, err = r.MakeCache()
|
||||
if err != nil {
|
||||
return "", 404, err
|
||||
return "", status, err
|
||||
}
|
||||
|
||||
doc, err := core.NewDocument(content)
|
||||
if err != nil {
|
||||
return "", 500, err
|
||||
}
|
||||
|
||||
guard := ""
|
||||
guardRedirect := ""
|
||||
configText := ""
|
||||
cacheStore := ""
|
||||
cacheTime := 0
|
||||
dateCacheTime := 0
|
||||
|
||||
configSel := doc.Find("script[name=config]")
|
||||
if configSel != nil && configSel.Length() > 0 {
|
||||
configText = configSel.Text()
|
||||
configSel.Remove()
|
||||
|
||||
var conf core.PageConfig
|
||||
err := jsoniter.UnmarshalFromString(configText, &conf)
|
||||
if err != nil {
|
||||
return "", 500, fmt.Errorf("config error, please re-complie the page %s", err.Error())
|
||||
}
|
||||
|
||||
// Redirect the page (should refector before release)
|
||||
// guard=cookie-jwt:redirect-url redirect to the url if not authorized
|
||||
// guard=cookie-jwt return {code: 403, message: "Not Authorized"}
|
||||
guard = conf.Guard
|
||||
if strings.Contains(conf.Guard, ":") {
|
||||
parts := strings.Split(conf.Guard, ":")
|
||||
guard = parts[0]
|
||||
guardRedirect = parts[1]
|
||||
}
|
||||
|
||||
// Cache store
|
||||
cacheStore = conf.CacheStore
|
||||
cacheTime = conf.Cache
|
||||
dateCacheTime = conf.DataCache
|
||||
}
|
||||
|
||||
dataText := ""
|
||||
dataSel := doc.Find("script[name=data]")
|
||||
if dataSel != nil && dataSel.Length() > 0 {
|
||||
dataText = dataSel.Text()
|
||||
dataSel.Remove()
|
||||
}
|
||||
|
||||
globalDataText := ""
|
||||
globalDataSel := doc.Find("script[name=global]")
|
||||
if globalDataSel != nil && globalDataSel.Length() > 0 {
|
||||
globalDataText = globalDataSel.Text()
|
||||
globalDataSel.Remove()
|
||||
}
|
||||
|
||||
html, err := doc.Html()
|
||||
if err != nil {
|
||||
return "", 500, fmt.Errorf("parse error, please re-complie the page %s", err.Error())
|
||||
}
|
||||
|
||||
// Save to The Cache
|
||||
c = &core.Cache{
|
||||
Data: dataText,
|
||||
Global: globalDataText,
|
||||
HTML: html,
|
||||
Guard: guard,
|
||||
GuardRedirect: guardRedirect,
|
||||
Config: configText,
|
||||
CacheStore: cacheStore,
|
||||
CacheTime: time.Duration(cacheTime) * time.Second,
|
||||
DataCacheTime: time.Duration(dateCacheTime) * time.Second,
|
||||
}
|
||||
go core.SetCache(r.File, c)
|
||||
go log.Trace("[SUI] The page %s is cached file=%s", r.Request.URL.Path, r.File)
|
||||
}
|
||||
|
||||
|
|
@ -249,6 +177,90 @@ func (r *Request) Render() (string, int, error) {
|
|||
return html, 200, nil
|
||||
}
|
||||
|
||||
// MakeCache is the cache for the page API.
|
||||
func (r *Request) MakeCache() (*core.Cache, int, error) {
|
||||
|
||||
// Read the file
|
||||
content, err := application.App.Read(r.File)
|
||||
if err != nil {
|
||||
return nil, 404, err
|
||||
}
|
||||
|
||||
doc, err := core.NewDocument(content)
|
||||
if err != nil {
|
||||
return nil, 500, err
|
||||
}
|
||||
|
||||
guard := ""
|
||||
guardRedirect := ""
|
||||
configText := ""
|
||||
cacheStore := ""
|
||||
cacheTime := 0
|
||||
dateCacheTime := 0
|
||||
|
||||
configSel := doc.Find("script[name=config]")
|
||||
if configSel != nil && configSel.Length() > 0 {
|
||||
configText = configSel.Text()
|
||||
configSel.Remove()
|
||||
|
||||
var conf core.PageConfig
|
||||
err := jsoniter.UnmarshalFromString(configText, &conf)
|
||||
if err != nil {
|
||||
return nil, 500, fmt.Errorf("config error, please re-complie the page %s", err.Error())
|
||||
}
|
||||
|
||||
// Redirect the page (should refector before release)
|
||||
// guard=cookie-jwt:redirect-url redirect to the url if not authorized
|
||||
// guard=cookie-jwt return {code: 403, message: "Not Authorized"}
|
||||
guard = conf.Guard
|
||||
if strings.Contains(conf.Guard, ":") {
|
||||
parts := strings.Split(conf.Guard, ":")
|
||||
guard = parts[0]
|
||||
guardRedirect = parts[1]
|
||||
}
|
||||
|
||||
// Cache store
|
||||
cacheStore = conf.CacheStore
|
||||
cacheTime = conf.Cache
|
||||
dateCacheTime = conf.DataCache
|
||||
}
|
||||
|
||||
dataText := ""
|
||||
dataSel := doc.Find("script[name=data]")
|
||||
if dataSel != nil && dataSel.Length() > 0 {
|
||||
dataText = dataSel.Text()
|
||||
dataSel.Remove()
|
||||
}
|
||||
|
||||
globalDataText := ""
|
||||
globalDataSel := doc.Find("script[name=global]")
|
||||
if globalDataSel != nil && globalDataSel.Length() > 0 {
|
||||
globalDataText = globalDataSel.Text()
|
||||
globalDataSel.Remove()
|
||||
}
|
||||
|
||||
html, err := doc.Html()
|
||||
if err != nil {
|
||||
return nil, 500, fmt.Errorf("parse error, please re-complie the page %s", err.Error())
|
||||
}
|
||||
|
||||
// Save to The Cache
|
||||
cache := &core.Cache{
|
||||
Data: dataText,
|
||||
Global: globalDataText,
|
||||
HTML: html,
|
||||
Guard: guard,
|
||||
GuardRedirect: guardRedirect,
|
||||
Config: configText,
|
||||
CacheStore: cacheStore,
|
||||
CacheTime: time.Duration(cacheTime) * time.Second,
|
||||
DataCacheTime: time.Duration(dateCacheTime) * time.Second,
|
||||
}
|
||||
|
||||
go core.SetCache(r.File, cache)
|
||||
return cache, 200, nil
|
||||
}
|
||||
|
||||
// Guard the page
|
||||
func (r *Request) Guard(c *core.Cache) (int, error) {
|
||||
|
||||
|
|
|
|||
100
sui/api/request_test.go
Normal file
100
sui/api/request_test.go
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/yaoapp/yao/sui/core"
|
||||
)
|
||||
|
||||
func TestMakeCache(t *testing.T) {
|
||||
prepare(t)
|
||||
defer clean()
|
||||
r := makeRequest("/unit-test/index.sui", t)
|
||||
c, status, err := r.MakeCache()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
assert.Equal(t, http.StatusOK, status)
|
||||
assert.Contains(t, c.HTML, "The advanced test cases")
|
||||
}
|
||||
|
||||
func TestRender(t *testing.T) {
|
||||
prepare(t)
|
||||
defer clean()
|
||||
|
||||
parser, html, data := makeParser("/unit-test/index.sui", t)
|
||||
result, err := parser.Render(html)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
assert.Contains(t, result, "The advanced test cases")
|
||||
assert.NotNil(t, data["$global"])
|
||||
assert.NotNil(t, data["foo"])
|
||||
assert.NotNil(t, data["items"])
|
||||
|
||||
// fmt.Println(result)
|
||||
}
|
||||
|
||||
func makeParser(route string, t *testing.T) (*core.TemplateParser, string, core.Data) {
|
||||
r := makeRequest(route, t)
|
||||
c, _, err := r.MakeCache()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
data := r.Request.NewData()
|
||||
if c.Data != "" {
|
||||
err = r.Request.ExecStringMerge(data, c.Data)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
if c.Global != "" {
|
||||
global, err := r.Request.ExecString(c.Global)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
data["$global"] = global
|
||||
}
|
||||
|
||||
// Set the page request data
|
||||
option := core.ParserOption{
|
||||
Theme: r.Request.Theme,
|
||||
Locale: r.Request.Locale,
|
||||
Debug: r.Request.DebugMode(),
|
||||
DisableCache: r.Request.DisableCache(),
|
||||
Route: r.Request.URL.Path,
|
||||
Request: true,
|
||||
}
|
||||
|
||||
// Parse the template
|
||||
return core.NewTemplateParser(data, &option), c.HTML, data
|
||||
}
|
||||
|
||||
func makeRequest(path string, t *testing.T) *Request {
|
||||
req, err := http.NewRequest(http.MethodGet, path, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
c.Request = req
|
||||
|
||||
r, status, err := NewRequestContext(c)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if status != http.StatusOK {
|
||||
t.Fatalf("Status: %d", status)
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
|
@ -31,6 +31,16 @@ func prepare(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
advanced, err := core.SUIs["test"].GetTemplate("advanced")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = advanced.Build(&core.BuildOption{SSR: true})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func clean() {
|
||||
|
|
|
|||
|
|
@ -62,7 +62,11 @@ func (page *Page) Build(ctx *BuildContext, option *BuildOption) (*goquery.Docume
|
|||
doc.Selection.Find("body").AppendHtml("\n" + `<script src="` + script + `"></script>` + "\n")
|
||||
}
|
||||
}
|
||||
doc.Selection.Find("body").AppendHtml(fmt.Sprintf("\n"+`<script type="text/javascript">`+"\n%s\n"+`</script>`+"\n%s\n", strings.Join(ctx.scripts, "\n"), code))
|
||||
componentScripts := ""
|
||||
if len(ctx.scripts) > 0 {
|
||||
componentScripts = fmt.Sprintf("\n"+`<script type="text/javascript" name="components">`+"\n%s\n"+`</script>`+"\n", strings.Join(ctx.scripts, "\n"))
|
||||
}
|
||||
doc.Selection.Find("body").AppendHtml(fmt.Sprintf("\n%s\n%s\n", componentScripts, code))
|
||||
return doc, warnings, nil
|
||||
}
|
||||
|
||||
|
|
@ -373,7 +377,7 @@ func (page *Page) BuildScript(ctx *BuildContext, option *BuildOption, namespace
|
|||
// if the script is a component and not the first import
|
||||
if option.ComponentName != "" && ctx.components[option.ComponentName] {
|
||||
ctx.scripts = append(ctx.scripts, instanceCode)
|
||||
return fmt.Sprintf("<script type=\"text/javascript\">\n%s\n</script>\n", instanceCode), []string{}, nil
|
||||
return fmt.Sprintf("<script type=\"text/javascript\" name=\"%s\">\n%s\n</script>\n", option.ComponentName, instanceCode), []string{}, nil
|
||||
}
|
||||
|
||||
// TypeScript
|
||||
|
|
@ -402,12 +406,15 @@ func (page *Page) BuildScript(ctx *BuildContext, option *BuildOption, namespace
|
|||
}
|
||||
|
||||
if option.Namespace == "" {
|
||||
return fmt.Sprintf("<script type=\"text/javascript\">\n%s\n</script>\n", code), scripts, nil
|
||||
if strings.TrimSpace(string(code)) == "" {
|
||||
return "", scripts, nil
|
||||
}
|
||||
return fmt.Sprintf("<script type=\"text/javascript\" name=\"page\">\n%s\n</script>\n", code), scripts, nil
|
||||
}
|
||||
|
||||
componentCode := fmt.Sprintf("function %s(){\n%s\n}\n%s\n", option.ComponentName, addTabToEachLine(string(code)), instanceCode)
|
||||
ctx.scripts = append(ctx.scripts, componentCode)
|
||||
return fmt.Sprintf("<script type=\"text/javascript\">%s</script>\n", componentCode), scripts, nil
|
||||
return fmt.Sprintf("<script type=\"text/javascript\" name=\"%s\">%s</script>\n", option.ComponentName, componentCode), scripts, nil
|
||||
}
|
||||
|
||||
// JavaScript
|
||||
|
|
@ -434,12 +441,15 @@ func (page *Page) BuildScript(ctx *BuildContext, option *BuildOption, namespace
|
|||
}
|
||||
|
||||
if option.Namespace == "" {
|
||||
return fmt.Sprintf("<script type=\"text/javascript\">\n%s\n</script>\n", code), scripts, nil
|
||||
if strings.TrimSpace(string(code)) == "" {
|
||||
return "", scripts, nil
|
||||
}
|
||||
return fmt.Sprintf("<script type=\"text/javascript\" name=\"page\">\n%s\n</script>\n", code), scripts, nil
|
||||
}
|
||||
|
||||
componentCode := fmt.Sprintf("function %s(){\n%s\n}\n%s\n", option.ComponentName, addTabToEachLine(string(code)), instanceCode)
|
||||
ctx.scripts = append(ctx.scripts, componentCode)
|
||||
return fmt.Sprintf("<script type=\"text/javascript\">%s</script>\n", componentCode), scripts, nil
|
||||
return fmt.Sprintf("<script type=\"text/javascript\" name=\"%s\" >%s</script>\n", option.ComponentName, componentCode), scripts, nil
|
||||
}
|
||||
|
||||
func addTabToEachLine(input string, prefix ...string) string {
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
package core
|
||||
Loading…
Add table
Reference in a new issue