readysite / website / internal / content / tree.go
1.2 KB
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("")
}
← Back