diff --git a/sui/api/api.go b/sui/api/api.go index 7bc64973..78c245c2 100644 --- a/sui/api/api.go +++ b/sui/api/api.go @@ -123,6 +123,12 @@ var dsl = []byte(` "process": "sui.Page.Create", "in": ["$param.id", "$param.template_id", "$param.route", ":context", ":payload"], "out": { "status": 200, "type": "application/json" } + },{ + "path": "/:id/page/duplicate/:template_id/*route", + "method": "POST", + "process": "sui.Page.Duplicate", + "in": ["$param.id", "$param.template_id", "$param.route", ":payload"], + "out": { "status": 200, "type": "application/json" } },{ "path": "/:id/page/exist/:template_id/*route", "method": "GET", diff --git a/sui/api/process.go b/sui/api/process.go index cb38898f..6d53cf3b 100644 --- a/sui/api/process.go +++ b/sui/api/process.go @@ -35,14 +35,15 @@ func init() { "component.get": ComponentGet, "component.find": ComponentFind, - "page.tree": PageTree, - "page.get": PageGet, - "page.save": PageSave, - "page.savetemp": PageSaveTemp, - "page.create": PageCreate, - "page.remove": PageRemove, - "page.exist": PageExist, - "page.asset": PageAsset, + "page.tree": PageTree, + "page.get": PageGet, + "page.save": PageSave, + "page.savetemp": PageSaveTemp, + "page.create": PageCreate, + "page.duplicate": PageDuplicate, + "page.remove": PageRemove, + "page.exist": PageExist, + "page.asset": PageAsset, "editor.render": EditorRender, "editor.source": EditorSource, @@ -573,6 +574,45 @@ func PageCreate(process *process.Process) interface{} { return nil } +// PageDuplicate handle the find Template request +func PageDuplicate(process *process.Process) interface{} { + process.ValidateArgNums(3) + sui := get(process) + templateID := process.ArgsString(1) + copyfrom := process.ArgsString(2) + payload := process.ArgsMap(3, map[string]interface{}{}) + + tmpl, err := sui.GetTemplate(templateID) + if err != nil { + exception.New(err.Error(), 500).Throw() + } + + page, err := tmpl.Page(copyfrom) + if err != nil { + exception.New(err.Error(), 500).Throw() + } + + // Get the route from payload + route, ok := payload["route"].(string) + if !ok { + exception.New("the route is required", 400).Throw() + } + + title := route + if v, ok := payload["title"].(string); ok { + title = v + } + + // Page Save as + setting := &core.PageSetting{Title: title} + _, err = page.SaveAs(route, setting) + if err != nil { + exception.New(err.Error(), 500).Throw() + } + + return nil +} + // PageRemove handle the find Template request func PageRemove(process *process.Process) interface{} { process.ValidateArgNums(3) diff --git a/sui/api/process_test.go b/sui/api/process_test.go index 44dedb98..d0489837 100644 --- a/sui/api/process_test.go +++ b/sui/api/process_test.go @@ -333,6 +333,30 @@ func TestPageCreate(t *testing.T) { assert.Nil(t, res) } +func TestPageDuplicate(t *testing.T) { + + load(t) + defer clean() + defer func() { + _, err := process.New("sui.page.remove", "demo", "tech-blue", "/unit-test").Exec() + if err != nil { + t.Fatal(err) + } + }() + + // test demo + p, err := process.Of("sui.page.duplicate", "demo", "tech-blue", "/page/[id]", map[string]interface{}{"title": "hello", "route": "/unit-test"}) + if err != nil { + t.Fatal(err) + } + + res, err := p.Exec() + if err != nil { + t.Fatal(err) + } + assert.Nil(t, res) +} + func TestPageCreateSaveThenRemove(t *testing.T) { load(t) diff --git a/sui/core/interfaces.go b/sui/core/interfaces.go index b7ddaf8f..7c285433 100644 --- a/sui/core/interfaces.go +++ b/sui/core/interfaces.go @@ -73,6 +73,7 @@ type IPage interface { Get() *Page GetConfig() *PageConfig + SaveAs(route string, setting *PageSetting) (IPage, error) Save(request *RequestSource) error SaveTemp(request *RequestSource) error Remove() error diff --git a/sui/storages/local/page.go b/sui/storages/local/page.go index 241a659f..c6b0e0c4 100644 --- a/sui/storages/local/page.go +++ b/sui/storages/local/page.go @@ -208,8 +208,15 @@ func (tmpl *Template) removeEmptyPath(path string) error { return err } - if len(dirs) == 0 { - err = tmpl.local.fs.Remove(path) + skipTempDirs := []string{} + for _, dir := range dirs { + if !strings.HasPrefix(dir, ".tmp") { + skipTempDirs = append(skipTempDirs, dir) + } + } + + if len(skipTempDirs) == 0 { + err = tmpl.local.fs.RemoveAll(path) if err != nil { return err } @@ -222,6 +229,43 @@ func (tmpl *Template) removeEmptyPath(path string) error { return nil } +// SaveAs save the page as +func (page *Page) SaveAs(route string, setting *core.PageSetting) (core.IPage, error) { + + if page.tmpl.PageExist(route) { + return nil, fmt.Errorf("Page %s already exist", route) + } + + root := page.tmpl.Root + target := filepath.Join(root, route) + targetBaseName := filepath.Base(target) + baseName := filepath.Base(page.Path) + patterns := []string{"*.js", "*.ts", "*.html", "*.css", "*.config", "*.json"} + err := page.tmpl.local.fs.Walk(page.Path, func(root, file string, isdir bool) error { + if isdir { + return nil + } + + if filepath.Base(filepath.Dir(file)) != baseName { + return nil + } + + fileName := filepath.Base(file) + targetFileName := strings.Replace(fileName, baseName, targetBaseName, 1) + targetFile := filepath.Join(target, targetFileName) + + // Copy the file + return page.tmpl.local.fs.Copy(file, targetFile) + + }, patterns...) + + if err != nil { + return nil, err + } + + return page.tmpl.Page(route) +} + // CreateEmptyPage create a new empty func (tmpl *Template) CreateEmptyPage(route string, setting *core.PageSetting) (core.IPage, error) { if tmpl.PageExist(route) {