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