tree.go
// Package content provides page tree building, path lookup, slug validation, and collection events.
package content
import "github.com/readysite/readysite/website/models"
// TreeNode represents a page with its children for tree rendering.
type TreeNode struct {
Page *models.Page
Children []*TreeNode
}
// BuildTree builds a nested page tree structure from all pages.
// Uses single query and builds tree in memory to avoid N+1 queries.
func BuildTree() []*TreeNode {
// Fetch all pages in one query
allPages, err := models.Pages.Search("ORDER BY Position, CreatedAt")
if err != nil {
return nil
}
// Build map of parent ID -> children
childrenMap := make(map[string][]*models.Page)
for _, page := range allPages {
childrenMap[page.ParentID] = append(childrenMap[page.ParentID], page)
}
// Build tree recursively using the map
var buildFromMap func(parentID string) []*TreeNode
buildFromMap = func(parentID string) []*TreeNode {
children := childrenMap[parentID]
if len(children) == 0 {
return nil
}
nodes := make([]*TreeNode, len(children))
for i, page := range children {
nodes[i] = &TreeNode{
Page: page,
Children: buildFromMap(page.ID),
}
}
return nodes
}
return buildFromMap("")
}