From b3b891338bdf5a68bb3aa0a2e2f622f064b87f6b Mon Sep 17 00:00:00 2001 From: Liang Ding Date: Sat, 13 May 2023 21:50:32 +0800 Subject: [PATCH] :art: Add kernel API `/api/block/getChildBlocks` Fix https://github.com/siyuan-note/siyuan/issues/8249 --- API.md | 41 +++++++++++++++++++++++++++++++++- API_zh_CN.md | 39 ++++++++++++++++++++++++++++++++ kernel/api/block.go | 17 ++++++++++++++ kernel/api/router.go | 1 + kernel/model/block.go | 52 +++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 149 insertions(+), 1 deletion(-) diff --git a/API.md b/API.md index a059a4f38..d8f28fa8e 100644 --- a/API.md +++ b/API.md @@ -29,6 +29,7 @@ * [Delete a block](#Delete-a-block) * [Move a block](#Move-a-block) * [Get a block kramdown](#Get-a-block-kramdown) + * [Get child blocks](#get-child-blocks) * [Attributes](#Attributes) * [Set block attributes](#Set-block-attributes) * [Get block attributes](#Get-block-attributes) @@ -769,6 +770,44 @@ View API token in Settings - About, request header: `Authorization: T } ``` +### Get child blocks + +* `/api/block/getChildBlocks` +* Parameters + + ```json + { + "id": "20230506212712-vt9ajwj" + } + ``` + + * `id`: Parent block ID + * The blocks below a heading are also counted as child blocks +* Return value + + ```json + { + "code": 0, + "msg": "", + "data": [ + { + "id": "20230512083858-mjdwkbn", + "type": "h", + "subType": "h1" + }, + { + "id": "20230513213727-thswvfd", + "type": "s" + }, + { + "id": "20230513213633-9lsj4ew", + "type": "l", + "subType": "u" + } + ] + } + ``` + ## Attributes ### Set block attributes @@ -880,7 +919,7 @@ View API token in Settings - About, request header: `Authorization: T } ``` -### 渲染 Sprig +### Render Sprig * `/api/template/renderSprig` * Parameters diff --git a/API_zh_CN.md b/API_zh_CN.md index 971356882..2123c1ac7 100644 --- a/API_zh_CN.md +++ b/API_zh_CN.md @@ -29,6 +29,7 @@ * [删除块](#删除块) * [移动块](#移动块) * [获取块 kramdown 源码](#获取块-kramdown-源码) + * [获取子块](#获取子块) * [属性](#属性) * [设置块属性](#设置块属性) * [获取块属性](#获取块属性) @@ -762,6 +763,44 @@ } ``` +### 获取子块 + +* `/api/block/getChildBlocks` +* 参数 + + ```json + { + "id": "20230506212712-vt9ajwj" + } + ``` + + * `id`:父块 ID + * 标题下方块也算作子块 +* 返回值 + + ```json + { + "code": 0, + "msg": "", + "data": [ + { + "id": "20230512083858-mjdwkbn", + "type": "h", + "subType": "h1" + }, + { + "id": "20230513213727-thswvfd", + "type": "s" + }, + { + "id": "20230513213633-9lsj4ew", + "type": "l", + "subType": "u" + } + ] + } + ``` + ## 属性 ### 设置块属性 diff --git a/kernel/api/block.go b/kernel/api/block.go index 9570529b4..02cec7a92 100644 --- a/kernel/api/block.go +++ b/kernel/api/block.go @@ -481,3 +481,20 @@ func getBlockKramdown(c *gin.Context) { "kramdown": kramdown, } } + +func getChildBlocks(c *gin.Context) { + ret := gulu.Ret.NewResult() + defer c.JSON(http.StatusOK, ret) + + arg, ok := util.JsonArg(c, ret) + if !ok { + return + } + + id := arg["id"].(string) + if util.InvalidIDPattern(id, ret) { + return + } + + ret.Data = model.GetChildBlocks(id) +} diff --git a/kernel/api/router.go b/kernel/api/router.go index 0a0f22cc3..1520eecce 100644 --- a/kernel/api/router.go +++ b/kernel/api/router.go @@ -147,6 +147,7 @@ func ServeAPI(ginServer *gin.Engine) { ginServer.Handle("POST", "/api/block/getBlockInfo", model.CheckAuth, getBlockInfo) ginServer.Handle("POST", "/api/block/getBlockDOM", model.CheckAuth, getBlockDOM) ginServer.Handle("POST", "/api/block/getBlockKramdown", model.CheckAuth, getBlockKramdown) + ginServer.Handle("POST", "/api/block/getChildBlocks", model.CheckAuth, getChildBlocks) ginServer.Handle("POST", "/api/block/getBlockBreadcrumb", model.CheckAuth, getBlockBreadcrumb) ginServer.Handle("POST", "/api/block/getBlockIndex", model.CheckAuth, getBlockIndex) ginServer.Handle("POST", "/api/block/getRefIDs", model.CheckAuth, getRefIDs) diff --git a/kernel/model/block.go b/kernel/model/block.go index 60341b3c6..dd781023a 100644 --- a/kernel/model/block.go +++ b/kernel/model/block.go @@ -445,6 +445,58 @@ func GetBlockKramdown(id string) (ret string) { return } +type ChildBlock struct { + ID string `json:"id"` + Type string `json:"type"` + SubType string `json:"subType,omitempty"` +} + +func GetChildBlocks(id string) (ret []*ChildBlock) { + ret = []*ChildBlock{} + if "" == id { + return + } + + tree, err := loadTreeByBlockID(id) + if nil != err { + return + } + + node := treenode.GetNodeInTree(tree, id) + if nil == node { + return + } + + if ast.NodeHeading == node.Type { + children := treenode.HeadingChildren(node) + for _, c := range children { + ret = append(ret, &ChildBlock{ + ID: c.ID, + Type: treenode.TypeAbbr(c.Type.String()), + SubType: treenode.SubTypeAbbr(c), + }) + } + return + } + + if !node.IsContainerBlock() { + return + } + + for c := node.FirstChild; nil != c; c = c.Next { + if !c.IsBlock() { + continue + } + + ret = append(ret, &ChildBlock{ + ID: c.ID, + Type: treenode.TypeAbbr(c.Type.String()), + SubType: treenode.SubTypeAbbr(c), + }) + } + return +} + func GetBlock(id string, tree *parse.Tree) (ret *Block, err error) { ret, err = getBlock(id, tree) return