This commit is contained in:
2025-12-02 08:45:38 +01:00
parent e3aaa1b0f8
commit c3690f3d53
5 changed files with 95 additions and 105 deletions

View File

@@ -25,7 +25,7 @@ pub fn new(args FactoryArgs) !&Site {
config: SiteConfig{ config: SiteConfig{
name: name name: name
} }
root_category: Category{} root: Category{}
} }
sites_global[name] = &site sites_global[name] = &site
return get(name: name)! return get(name: name)!

View File

@@ -9,7 +9,7 @@ pub mut:
items []CategoryItem items []CategoryItem
} }
//return the label of the category (last part of the path) // return the label of the category (last part of the path)
pub fn (mut c Category) label() !string { pub fn (mut c Category) label() !string {
if c.path.count('/') == 0 { if c.path.count('/') == 0 {
return c.path return c.path
@@ -19,61 +19,29 @@ pub fn (mut c Category) label() !string {
type CategoryItem = Page | Link | Category type CategoryItem = Page | Link | Category
// return all items as CategoryItem references recursive
pub fn (mut self Category) items_get() ![]&CategoryItem {
pub fn (mut self Category) up(path string) !&Category { mut result := []&CategoryItem{}
// Split the requested path into parts for i in 0 .. self.items.len {
path_parts := path.split('/') mut c := self.items[i]
match mut c {
// Start at current category Category {
mut current := &self result << c.items_get()!
// Navigate through each part of the path
for part in path_parts {
// Skip empty parts (from leading/trailing slashes)
if part.len == 0 {
continue
}
// Check if this part already exists in current category's items
mut found := false
for item in current.items {
match item {
&Category {
item_label := item.label()!
if item_label == part {
current = item
found = true
break
}
}
else {}
} }
} else {
result << &c
// If not found, create a new category and add it
if !found {
mut new_category := Category{
path: part
collapsible: true
collapsed: true
items: []CategoryItem{}
} }
current.items << new_category
current = &new_category
} }
} }
return result
return current
} }
pub fn (mut self Category) page_get(src string) !&Page {
fn (mut self Category) page_get(src string)! &Page { for c in self.items_get()! {
for item in self.items { match c {
match item {
Page { Page {
if item.src == src { if c.src == src {
return it return &c
} }
} }
else {} else {}
@@ -82,12 +50,12 @@ fn (mut self Category) page_get(src string)! &Page {
return error('Page with src="${src}" not found in site.') return error('Page with src="${src}" not found in site.')
} }
fn (mut self Category) link_get(href string)! &Link { pub fn (mut self Category) link_get(href string) !&Link {
for item in self.items { for c in self.items_get()! {
match item { match c {
Link { Link {
if item.href == href { if c.href == href {
return it return &c
} }
} }
else {} else {}
@@ -96,16 +64,26 @@ fn (mut self Category) link_get(href string)! &Link {
return error('Link with href="${href}" not found in site.') return error('Link with href="${href}" not found in site.')
} }
fn (mut self Category) category_get(path string)! &Category { pub fn (mut self Category) category_get(path string) !&Category {
for item in self.items { for i in 0 .. self.items.len {
match item { mut c := self.items[i]
match mut c {
Category { Category {
if item.path == path { if c.path == path {
return it return &c
} }
} }
else {} else {}
} }
} }
return error('Category with path="${path}" not found in site.') mut new_category := Category{
} path: path
collapsible: true
collapsed: true
items: []CategoryItem{}
}
// Add the new category as a sum type variant
self.items << new_category
// Update current_category_ref to point to the newly added category in the slice
return &new_category
}

View File

@@ -15,14 +15,14 @@ pub fn (mut self Category) str() string {
prefix := if is_last { ' ' } else { ' ' } prefix := if is_last { ' ' } else { ' ' }
match item { match item {
NavDoc { Page {
result << '${prefix}📄 ${item.label}' result << '${prefix}📄 ${item.label}'
result << ' path: ${item.path}' result << ' src: ${item.src}'
} }
NavCat { Category {
// Category header // Category header
collapse_icon := if item.collapsed { ' ' } else { ' ' } collapse_icon := if item.collapsed { ' ' } else { ' ' }
result << '${prefix}${collapse_icon}📁 ${item.label}' result << '${prefix}${collapse_icon}📁 ${item.path}'
// Category metadata // Category metadata
if !item.collapsed { if !item.collapsed {
@@ -35,15 +35,15 @@ pub fn (mut self Category) str() string {
sub_prefix := if is_last_sub { ' ' } else { ' ' } sub_prefix := if is_last_sub { ' ' } else { ' ' }
match sub_item { match sub_item {
NavDoc { Page {
result << '${sub_prefix}📄 ${sub_item.label} [${sub_item.src_path}]' result << '${sub_prefix}📄 ${sub_item.label} [${sub_item.src}]'
} }
NavCat { Category {
// Nested categories // Nested categories
sub_collapse_icon := if sub_item.collapsed { ' ' } else { ' ' } sub_collapse_icon := if sub_item.collapsed { ' ' } else { ' ' }
result << '${sub_prefix}${sub_collapse_icon}📁 ${sub_item.label}' result << '${sub_prefix}${sub_collapse_icon}📁 ${sub_item.path}'
} }
NavLink { Link {
result << '${sub_prefix}🔗 ${sub_item.label}' result << '${sub_prefix}🔗 ${sub_item.label}'
if sub_item.description.len > 0 { if sub_item.description.len > 0 {
result << ' ${sub_item.description}' result << ' ${sub_item.description}'
@@ -53,7 +53,7 @@ pub fn (mut self Category) str() string {
} }
} }
} }
NavLink { Link {
result << '${prefix}🔗 ${item.label}' result << '${prefix}🔗 ${item.label}'
result << ' href: ${item.href}' result << ' href: ${item.href}'
if item.description.len > 0 { if item.description.len > 0 {

View File

@@ -3,30 +3,28 @@ module meta
@[heap] @[heap]
pub struct Site { pub struct Site {
pub mut: pub mut:
doctree_path string // path to the export of the doctree site doctree_path string // path to the export of the doctree site
config SiteConfig // Full site configuration config SiteConfig // Full site configuration
root // The root category containing all top-level items root Category // The root category containing all top-level items
announcements []Announcement // there can be more than 1 announcement announcements []Announcement // there can be more than 1 announcement
imports []ImportItem imports []ImportItem
build_dest []BuildDest // Production build destinations (from !!site.build_dest) build_dest []BuildDest // Production build destinations (from !!site.build_dest)
build_dest_dev []BuildDest // Development build destinations (from !!site.build_dest_dev) build_dest_dev []BuildDest // Development build destinations (from !!site.build_dest_dev)
} }
pub fn (mut self Site) page_get(src string) !&Page {
pub fn (mut self Site) page_get(src string)! &Page {
return self.root.page_get(src)! return self.root.page_get(src)!
} }
pub fn (mut self Site) link_get(href string)! &Link { pub fn (mut self Site) link_get(href string) !&Link {
return self.root.link_get(href)! return self.root.link_get(href)!
} }
pub fn (mut self Site) category_get(path string)! &Category { pub fn (mut self Site) category_get(path string) !&Category {
return self.root.category_get(path)! return self.root.category_get(path)!
} }
//sidebar returns the root category for building the sidebar navigation // sidebar returns the root category for building the sidebar navigation
pub fn (mut self Site) sidebar()! &Category { pub fn (mut self Site) sidebar() !&Category {
return self.root return &self.root
} }

View File

@@ -4,16 +4,15 @@ import incubaid.herolib.core.playbook { PlayBook }
import incubaid.herolib.web.doctree as doctreetools import incubaid.herolib.web.doctree as doctreetools
import incubaid.herolib.ui.console import incubaid.herolib.ui.console
//========================================================= // ============================================================
// PAGES: Process pages and build navigation structure // PAGES & CATEGORIES: Process pages and build navigation structure
// ============================================================ // ============================================================
fn play_pages(mut plbook PlayBook, mut website Site) ! { fn play_pages(mut plbook PlayBook, mut website Site) ! {
mut collection_current := '' mut collection_current := ''
mut category_current := &website.root // start at root category, this is basically the navigation tree root
mut category_current := &website.root_category // start at root category, this is basically the navigation tree root
// ============================================================ // ============================================================
// PASS 1: Process all page and category actions // PASS 1: Process all page_category and page actions
// ============================================================ // ============================================================
mut all_actions := plbook.find(filter: 'site.')! mut all_actions := plbook.find(filter: 'site.')!
@@ -22,23 +21,31 @@ fn play_pages(mut plbook PlayBook, mut website Site) ! {
continue continue
} }
// Skip actions that are not page or page_category
if action.name != 'page_category' && action.name != 'page' {
continue
}
// ========== PAGE CATEGORY ========== // ========== PAGE CATEGORY ==========
if action.name == 'page_category' { if action.name == 'page_category' {
mut p := action.params mut p := action.params
// label is empty when not specified (we support label & path for flexibility) category_path := p.get_default('path', '')!
mut category_path := p.get_default('path', '')! if category_path.len == 0 {
category_current = category_current.up(category_path)! return error('!!site.page_category: must specify "path"')
category_current.collapsible = p.get_default_true('collapsible') }
category_current.collapsed = p.get_default_true('collapsed')
// Navigate/create category structure
category_current = category_current.category_get(category_path)!
category_current.collapsible = p.get_default_true('collapsible')
category_current.collapsed = p.get_default_false('collapsed')
console.print_item('Created page category: "${category_current.path}"')
console.print_item('Created page category: "${category_current.path}" ')
action.done = true action.done = true
println(category_current) println(category_current)
website.categories << category_current // $dbg();
$dbg();
continue continue
} }
@@ -75,13 +82,15 @@ fn play_pages(mut plbook PlayBook, mut website Site) ! {
collection_current = page_collection collection_current = page_collection
// Get optional page metadata // Get optional page metadata
page_label := p.get_default('label', p.get_default('title', '')!)! // is what is shown in the sidebar mut page_label := p.get_default('label', '')! // CHANGED: added mut
page_title := p.get_default('title', '')! // is title shown on the page, if not from the page content, if empty then will be brought in from the content if page_label.len == 0 {
page_label = p.get_default('title', '')!
}
page_title := p.get_default('title', '')!
page_description := p.get_default('description', '')! page_description := p.get_default('description', '')!
// Create page object
// Create page
mut page := Page{ mut page := Page{
src: '${page_collection}:${page_name}' src: '${page_collection}:${page_name}'
label: page_label label: page_label
@@ -89,14 +98,19 @@ fn play_pages(mut plbook PlayBook, mut website Site) ! {
description: page_description description: page_description
draft: p.get_default_false('draft') draft: p.get_default_false('draft')
hide_title: p.get_default_false('hide_title') hide_title: p.get_default_false('hide_title')
category_id: category_current
hide: p.get_default_false('hide') hide: p.get_default_false('hide')
nav_path: category_current.path
} }
website.pages << page // Add page to current category
category_current.items << page
console.print_item('Added page: "${page.src}" (label: "${page.label}")')
action.done = true action.done = true
continue continue
} }
} }
console.print_green('Pages and categories processing complete')
} }