[add] page api and change api route

This commit is contained in:
Max 2023-09-29 12:20:20 +08:00
parent f0ccba6db4
commit 8a7903db1e
7 changed files with 264 additions and 38 deletions

View file

@ -25,47 +25,60 @@ var dsl = []byte(`
},
{
"path": "/:id/template/:template_id/locale",
"path": "/:id/locale/:template_id",
"method": "GET",
"process": "sui.Template.Locale.Get",
"process": "sui.Locale.Get",
"in": ["$param.id", "$param.template_id"],
"out": { "status": 200, "type": "application/json" }
},{
"path": "/:id/template/:template_id/theme",
"path": "/:id/theme/:template_id",
"method": "GET",
"process": "sui.Template.Theme.Get",
"process": "sui.Theme.Get",
"in": ["$param.id", "$param.template_id"],
"out": { "status": 200, "type": "application/json" }
},
{
"path": "/:id/template/:template_id/block",
"path": "/:id/block/:template_id",
"method": "GET",
"process": "sui.Template.Block.Get",
"process": "sui.Block.Get",
"in": ["$param.id", "$param.template_id"],
"out": { "status": 200, "type": "application/json" }
},{
"path": "/:id/template/:template_id/block/:block_id",
"path": "/:id/block/:template_id/:block_id",
"method": "GET",
"process": "sui.Template.Block.Find",
"process": "sui.Block.Find",
"in": ["$param.id", "$param.template_id", "$param.block_id"],
"out": { "status": 200, "type": "text/javascript" }
},
{
"path": "/:id/template/:template_id/component",
"path": "/:id/component/:template_id",
"method": "GET",
"process": "sui.Template.Component.Get",
"process": "sui.Component.Get",
"in": ["$param.id", "$param.template_id"],
"out": { "status": 200, "type": "application/json" }
},{
"path": "/:id/template/:template_id/component/:component_id",
"path": "/:id/component/:template_id/:component_id",
"method": "GET",
"process": "sui.Template.Component.Find",
"process": "sui.Component.Find",
"in": ["$param.id", "$param.template_id", "$param.component_id"],
"out": { "status": 200, "type": "text/javascript" }
},
{
"path": "/:id/page/:template_id/*route",
"method": "GET",
"process": "sui.Page.Get",
"in": ["$param.id", "$param.template_id", "$param.route"],
"out": { "status": 200, "type": "application/json" }
},{
"path": "/:id/page/tree/:template_id/*route",
"method": "GET",
"process": "sui.Page.Tree",
"in": ["$param.id", "$param.template_id", "$param.route"],
"out": { "status": 200, "type": "application/json" }
},
{
"path": "/:id/editor/render/:template_id/*route",

View file

@ -8,14 +8,20 @@ import (
func init() {
process.RegisterGroup("sui", map[string]process.Handler{
"template.get": TemplateGet,
"template.find": TemplateFind,
"template.locale.get": TemplateLocaleGet,
"template.theme.get": TemplateThemeGet,
"template.block.get": TemplateBlockGet,
"template.block.find": TemplateBlockFind,
"template.component.get": TemplateComponentGet,
"template.component.find": TemplateComponentFind,
"template.get": TemplateGet,
"template.find": TemplateFind,
"locale.get": LocaleGet,
"theme.get": ThemeGet,
"block.get": BlockGet,
"block.find": BlockFind,
"component.get": ComponentGet,
"component.find": ComponentFind,
"page.tree": PageTree,
"page.get": PageGet,
"editor.render": EditorRender,
"editor.source": EditorSource,
@ -48,8 +54,8 @@ func TemplateFind(process *process.Process) interface{} {
return template
}
// TemplateLocaleGet handle the find Template request
func TemplateLocaleGet(process *process.Process) interface{} {
// LocaleGet handle the find Template request
func LocaleGet(process *process.Process) interface{} {
process.ValidateArgNums(2)
sui := get(process)
@ -61,8 +67,8 @@ func TemplateLocaleGet(process *process.Process) interface{} {
return template.Locales()
}
// TemplateThemeGet handle the find Template request
func TemplateThemeGet(process *process.Process) interface{} {
// ThemeGet handle the find Template request
func ThemeGet(process *process.Process) interface{} {
process.ValidateArgNums(2)
sui := get(process)
@ -74,8 +80,8 @@ func TemplateThemeGet(process *process.Process) interface{} {
return template.Themes()
}
// TemplateBlockGet handle the find Template request
func TemplateBlockGet(process *process.Process) interface{} {
// BlockGet handle the find Template request
func BlockGet(process *process.Process) interface{} {
process.ValidateArgNums(2)
sui := get(process)
@ -93,8 +99,8 @@ func TemplateBlockGet(process *process.Process) interface{} {
return blocks
}
// TemplateBlockFind handle the find Template request
func TemplateBlockFind(process *process.Process) interface{} {
// BlockFind handle the find Template request
func BlockFind(process *process.Process) interface{} {
process.ValidateArgNums(3)
sui := get(process)
@ -114,8 +120,8 @@ func TemplateBlockFind(process *process.Process) interface{} {
return block.Source()
}
// TemplateComponentGet handle the find Template request
func TemplateComponentGet(process *process.Process) interface{} {
// ComponentGet handle the find Template request
func ComponentGet(process *process.Process) interface{} {
process.ValidateArgNums(2)
sui := get(process)
@ -133,8 +139,8 @@ func TemplateComponentGet(process *process.Process) interface{} {
return components
}
// TemplateComponentFind handle the find Template request
func TemplateComponentFind(process *process.Process) interface{} {
// ComponentFind handle the find Template request
func ComponentFind(process *process.Process) interface{} {
process.ValidateArgNums(3)
sui := get(process)
@ -153,6 +159,44 @@ func TemplateComponentFind(process *process.Process) interface{} {
return component.Source()
}
// PageTree handle the find Template request
func PageTree(process *process.Process) interface{} {
process.ValidateArgNums(2)
sui := get(process)
templateID := process.ArgsString(1)
tmpl, err := sui.GetTemplate(templateID)
if err != nil {
exception.New(err.Error(), 500).Throw()
}
tree, err := tmpl.PageTree()
if err != nil {
exception.New(err.Error(), 500).Throw()
}
return tree
}
// PageGet handle the find Template request
func PageGet(process *process.Process) interface{} {
process.ValidateArgNums(2)
sui := get(process)
templateID := process.ArgsString(1)
tmpl, err := sui.GetTemplate(templateID)
if err != nil {
exception.New(err.Error(), 500).Throw()
}
tree, err := tmpl.Pages()
if err != nil {
exception.New(err.Error(), 500).Throw()
}
return tree
}
// EditorRender handle the render page request
func EditorRender(process *process.Process) interface{} {
process.ValidateArgNums(3)

View file

@ -53,7 +53,7 @@ func TestTemplateLocaleGet(t *testing.T) {
defer clean()
// test demo
p, err := process.Of("sui.template.locale.get", "demo", "tech-blue")
p, err := process.Of("sui.locale.get", "demo", "tech-blue")
if err != nil {
t.Fatal(err)
}
@ -75,7 +75,7 @@ func TestTemplateThemeGet(t *testing.T) {
defer clean()
// test demo
p, err := process.Of("sui.template.theme.get", "demo", "tech-blue")
p, err := process.Of("sui.theme.get", "demo", "tech-blue")
if err != nil {
t.Fatal(err)
}
@ -96,7 +96,7 @@ func TestTemplateBlockGet(t *testing.T) {
defer clean()
// test demo
p, err := process.Of("sui.template.block.get", "demo", "tech-blue")
p, err := process.Of("sui.block.get", "demo", "tech-blue")
if err != nil {
t.Fatal(err)
}
@ -119,7 +119,7 @@ func TestTemplateBlockFind(t *testing.T) {
defer clean()
// test demo
p, err := process.Of("sui.template.block.find", "demo", "tech-blue", "ColumnsTwo")
p, err := process.Of("sui.block.find", "demo", "tech-blue", "ColumnsTwo")
if err != nil {
t.Fatal(err)
}
@ -138,7 +138,7 @@ func TestTemplateComponentGet(t *testing.T) {
defer clean()
// test demo
p, err := process.Of("sui.template.component.get", "demo", "tech-blue")
p, err := process.Of("sui.component.get", "demo", "tech-blue")
if err != nil {
t.Fatal(err)
}
@ -160,7 +160,7 @@ func TestTemplateComponentFind(t *testing.T) {
defer clean()
// test demo
p, err := process.Of("sui.template.component.find", "demo", "tech-blue", "Box")
p, err := process.Of("sui.component.find", "demo", "tech-blue", "Box")
if err != nil {
t.Fatal(err)
}
@ -174,6 +174,50 @@ func TestTemplateComponentFind(t *testing.T) {
assert.Contains(t, res.(string), "window.component__Box=")
}
func TestTemplatePageTree(t *testing.T) {
load(t)
defer clean()
// test demo
p, err := process.Of("sui.page.tree", "demo", "tech-blue")
if err != nil {
t.Fatal(err)
}
res, err := p.Exec()
if err != nil {
t.Fatal(err)
}
assert.IsType(t, []*core.PageTreeNode{}, res)
assert.Equal(t, 5, len(res.([]*core.PageTreeNode)))
assert.Equal(t, "error", res.([]*core.PageTreeNode)[0].Name)
assert.Equal(t, "index", res.([]*core.PageTreeNode)[1].Name)
}
func TestTemplatePageGet(t *testing.T) {
load(t)
defer clean()
// test demo
p, err := process.Of("sui.page.get", "demo", "tech-blue", "/index/[invite]")
if err != nil {
t.Fatal(err)
}
res, err := p.Exec()
if err != nil {
t.Fatal(err)
}
pages := res.([]core.IPage)
assert.IsType(t, []core.IPage{}, pages)
assert.Equal(t, 8, len(pages))
for _, page := range pages {
assert.IsType(t, &local.Page{}, page)
}
}
func TestEditorRender(t *testing.T) {
load(t)
defer clean()

View file

@ -13,6 +13,7 @@ type SUI interface {
// ITemplate is the interface for the ITemplate
type ITemplate interface {
Pages() ([]IPage, error)
PageTree() ([]*PageTreeNode, error)
Page(route string) (IPage, error)
Blocks() ([]IBlock, error)

View file

@ -17,6 +17,14 @@ type Page struct {
Document []byte `json:"-"`
}
// PageTreeNode is the struct for the page tree node
type PageTreeNode struct {
Name string `json:"name,omitempty"`
IsDir bool `json:"is_dir,omitempty"`
Children []*PageTreeNode `json:"children,omitempty"`
IPage IPage `json:"page,omitempty"`
}
// Component is the struct for the component
type Component struct {
ID string `json:"id"`

View file

@ -40,6 +40,90 @@ func (tmpl *Template) Pages() ([]core.IPage, error) {
return pages, nil
}
// PageTree gets the page tree.
func (tmpl *Template) PageTree() ([]*core.PageTreeNode, error) {
exts := []string{"*.sui", "*.html", "*.htm", "*.page"}
rootNode := &core.PageTreeNode{
Name: tmpl.Name,
IsDir: true,
Children: []*core.PageTreeNode{}, // 初始为空的切片
}
tmpl.local.fs.Walk(tmpl.Root, func(root, file string, isdir bool) error {
name := filepath.Base(file)
relPath := file
if isdir {
if strings.HasPrefix(name, "__") {
return filepath.SkipDir
}
// Create directory nodes in the tree structure.
currentDir := rootNode
dirs := strings.Split(relPath, string(filepath.Separator))
for _, dir := range dirs {
if dir == "" {
continue
}
// Check if the directory node already exists.
var found bool
for _, child := range currentDir.Children {
if child.Name == dir {
currentDir = child
found = true
break
}
}
// If not found, create a new directory node.
if !found {
newDir := &core.PageTreeNode{
Name: dir,
IsDir: true,
Children: []*core.PageTreeNode{},
}
currentDir.Children = append(currentDir.Children, newDir)
currentDir = newDir
}
}
return nil
}
if strings.HasPrefix(name, "__") {
return nil
}
page, err := tmpl.getPageFrom(file)
if err != nil {
log.Error("Get page error: %v", err)
return err
}
// Attach the page to the appropriate directory node.
dirs := strings.Split(relPath, string(filepath.Separator))
currentDir := rootNode
for _, dir := range dirs {
for _, child := range currentDir.Children {
if child.Name == dir {
currentDir = child
break
}
}
}
currentDir.Children = append(currentDir.Children, &core.PageTreeNode{
Name: tmpl.getPageBase(currentDir.Name),
IsDir: false,
IPage: page,
})
return nil
}, exts...)
return rootNode.Children, nil
}
// Page get the page
func (tmpl *Template) Page(route string) (core.IPage, error) {
path := tmpl.getPagePath(route)

View file

@ -44,6 +44,38 @@ func TestTemplatePages(t *testing.T) {
}
}
func TestTemplatePageTree(t *testing.T) {
tests := prepare(t)
defer clean()
tmpl, err := tests.Demo.GetTemplate("tech-blue")
if err != nil {
t.Fatalf("GetTemplate error: %v", err)
}
pages, err := tmpl.PageTree()
if err != nil {
t.Fatalf("Pages error: %v", err)
}
assert.Equal(t, 5, len(pages))
assert.Equal(t, "error", pages[0].Name)
assert.Equal(t, true, pages[0].IsDir)
assert.Equal(t, "error", pages[0].Children[0].Name)
assert.Equal(t, "/error", pages[0].Children[0].IPage.(*Page).Route)
assert.Equal(t, "error", pages[0].Children[0].IPage.(*Page).Name)
assert.Equal(t, "index", pages[1].Name)
assert.Equal(t, true, pages[1].IsDir)
assert.Equal(t, "[invite]", pages[1].Children[0].Name)
assert.Equal(t, true, pages[1].Children[0].IsDir)
assert.Equal(t, "/index/[invite]", pages[1].Children[0].Children[0].IPage.(*Page).Route)
assert.Equal(t, "[invite]", pages[1].Children[0].Children[0].IPage.(*Page).Name)
assert.Equal(t, "/index", pages[1].Children[1].IPage.(*Page).Route)
assert.Equal(t, "index", pages[1].Children[1].IPage.(*Page).Name)
}
func TestTemplatePageTS(t *testing.T) {
tests := prepare(t)