Files
herolib/lib/web/doctree/meta/model_category.v
2025-12-02 07:53:20 +01:00

111 lines
2.1 KiB
V

module meta
@[heap]
struct Category {
pub mut:
path string // e.g. Operations/Daily (means 2 levels deep, first level is Operations)
collapsible bool = true
collapsed bool
items []CategoryItem
}
//return the label of the category (last part of the path)
pub fn (mut c Category) label() !string {
if c.path.count('/') == 0 {
return c.path
}
return c.path.all_after_last('/')
}
type CategoryItem = Page | Link | Category
pub fn (mut self Category) up(path string) !&Category {
// Split the requested path into parts
path_parts := path.split('/')
// Start at current category
mut current := &self
// 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 {}
}
}
// 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 current
}
fn (mut self Category) page_get(src string)! &Page {
for item in self.items {
match item {
Page {
if item.src == src {
return it
}
}
else {}
}
}
return error('Page with src="${src}" not found in site.')
}
fn (mut self Category) link_get(href string)! &Link {
for item in self.items {
match item {
Link {
if item.href == href {
return it
}
}
else {}
}
}
return error('Link with href="${href}" not found in site.')
}
fn (mut self Category) category_get(path string)! &Category {
for item in self.items {
match item {
Category {
if item.path == path {
return it
}
}
else {}
}
}
return error('Category with path="${path}" not found in site.')
}