...
This commit is contained in:
@@ -22,8 +22,7 @@ pub fn new(args FactoryArgs) !&Site {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mut site := Site{
|
mut site := Site{
|
||||||
nav: SideBar{}
|
config: SiteConfig{
|
||||||
siteconfig: SiteConfig{
|
|
||||||
name: name
|
name: name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -45,6 +44,10 @@ pub fn exists(args FactoryArgs) bool {
|
|||||||
return name in sites_global
|
return name in sites_global
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn reset() {
|
||||||
|
sites_global.clear()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn default() !&Site {
|
pub fn default() !&Site {
|
||||||
if sites_global.len == 0 {
|
if sites_global.len == 0 {
|
||||||
return new(name: 'default')!
|
return new(name: 'default')!
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ pub fn play(mut plbook PlayBook) ! {
|
|||||||
|
|
||||||
name := p.get_default('name', 'default')!
|
name := p.get_default('name', 'default')!
|
||||||
mut website := new(name: name)!
|
mut website := new(name: name)!
|
||||||
mut config := &website.siteconfig
|
mut config := &website.config
|
||||||
|
|
||||||
// Load core configuration
|
// Load core configuration
|
||||||
config.name = texttools.name_fix(name)
|
config.name = texttools.name_fix(name)
|
||||||
@@ -60,7 +60,7 @@ pub fn play(mut plbook PlayBook) ! {
|
|||||||
// STEP 3: Configure content imports
|
// STEP 3: Configure content imports
|
||||||
// ============================================================
|
// ============================================================
|
||||||
console.print_item('Step 3: Configuring content imports')
|
console.print_item('Step 3: Configuring content imports')
|
||||||
play_imports(mut plbook, mut config)!
|
play_imports(mut plbook, mut website)!
|
||||||
|
|
||||||
// ============================================================
|
// ============================================================
|
||||||
// STEP 4: Configure navigation menu
|
// STEP 4: Configure navigation menu
|
||||||
@@ -78,13 +78,13 @@ pub fn play(mut plbook PlayBook) ! {
|
|||||||
// STEP 6: Configure announcement bar (optional)
|
// STEP 6: Configure announcement bar (optional)
|
||||||
// ============================================================
|
// ============================================================
|
||||||
console.print_item('Step 6: Configuring announcement bar (if present)')
|
console.print_item('Step 6: Configuring announcement bar (if present)')
|
||||||
play_announcement(mut plbook, mut config)!
|
play_announcement(mut plbook, mut website)!
|
||||||
|
|
||||||
// ============================================================
|
// ============================================================
|
||||||
// STEP 7: Configure publish destinations
|
// STEP 7: Configure publish destinations
|
||||||
// ============================================================
|
// ============================================================
|
||||||
console.print_item('Step 7: Configuring publish destinations')
|
console.print_item('Step 7: Configuring publish destinations')
|
||||||
play_publishing(mut plbook, mut config)!
|
play_publishing(mut plbook, mut website)!
|
||||||
|
|
||||||
// ============================================================
|
// ============================================================
|
||||||
// STEP 8: Build pages and navigation structure
|
// STEP 8: Build pages and navigation structure
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import incubaid.herolib.ui.console
|
|||||||
// ============================================================
|
// ============================================================
|
||||||
// PUBLISHING: Configure build and publish destinations
|
// PUBLISHING: Configure build and publish destinations
|
||||||
// ============================================================
|
// ============================================================
|
||||||
fn play_publishing(mut plbook PlayBook, mut config SiteConfig) ! {
|
fn play_publishing(mut plbook PlayBook, mut website Site) ! {
|
||||||
// Production publish destinations
|
// Production publish destinations
|
||||||
mut build_dest_actions := plbook.find(filter: 'site.publish')!
|
mut build_dest_actions := plbook.find(filter: 'site.publish')!
|
||||||
for mut action in build_dest_actions {
|
for mut action in build_dest_actions {
|
||||||
@@ -23,7 +23,7 @@ fn play_publishing(mut plbook PlayBook, mut config SiteConfig) ! {
|
|||||||
path: path
|
path: path
|
||||||
ssh_name: p.get_default('ssh_name', '')!
|
ssh_name: p.get_default('ssh_name', '')!
|
||||||
}
|
}
|
||||||
config.build_dest << dest
|
website.build_dest << dest
|
||||||
action.done = true
|
action.done = true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,7 +40,7 @@ fn play_publishing(mut plbook PlayBook, mut config SiteConfig) ! {
|
|||||||
path: path
|
path: path
|
||||||
ssh_name: p.get_default('ssh_name', '')!
|
ssh_name: p.get_default('ssh_name', '')!
|
||||||
}
|
}
|
||||||
config.build_dest_dev << dest
|
website.build_dest_dev << dest
|
||||||
action.done = true
|
action.done = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
The Site module provides a structured way to define website configurations, navigation menus, pages, and sections using HeroScript. It's designed to work with static site generators like Docusaurus.
|
The Site module provides a structured way to define website configurations, navigation menus, pages, and sections using HeroScript. It's designed to work with static site generators like Docusaurus.
|
||||||
|
|
||||||
|
|
||||||
## Quick Start
|
## Quick Start
|
||||||
|
|
||||||
### Minimal HeroScript Example
|
### Minimal HeroScript Example
|
||||||
@@ -13,33 +12,33 @@ The Site module provides a structured way to define website configurations, navi
|
|||||||
title: "My Documentation"
|
title: "My Documentation"
|
||||||
|
|
||||||
!!site.page src: "docs:introduction"
|
!!site.page src: "docs:introduction"
|
||||||
|
label: "Getting Started"
|
||||||
title: "Getting Started"
|
title: "Getting Started"
|
||||||
|
|
||||||
!!site.page src: "setup"
|
!!site.page src: "setup"
|
||||||
|
label: "Installation"
|
||||||
title: "Installation"
|
title: "Installation"
|
||||||
```
|
```
|
||||||
|
|
||||||
### Processing with V Code
|
### Processing with V Code
|
||||||
|
|
||||||
```v
|
```v
|
||||||
#!/usr/bin/env -S v -n -w -gc none -cg -cc tcc -d use_openssl -enable-globals run
|
|
||||||
|
|
||||||
import incubaid.herolib.core.playbook
|
import incubaid.herolib.core.playbook
|
||||||
import incubaid.herolib.web.site
|
import incubaid.herolib.web.doctree.meta as site_module
|
||||||
import incubaid.herolib.ui.console
|
import incubaid.herolib.ui.console
|
||||||
|
|
||||||
// Process HeroScript file
|
// Process HeroScript file
|
||||||
mut plbook := playbook.new(path: './site_config.heroscript')!
|
mut plbook := playbook.new(path: './site_config.heroscript')!
|
||||||
|
|
||||||
// Execute site configuration
|
// Execute site configuration
|
||||||
site.play(mut plbook)!
|
site_module.play(mut plbook)!
|
||||||
|
|
||||||
// Access the configured site
|
// Access the configured site
|
||||||
mut mysite := site.get(name: 'my_docs')!
|
mut mysite := site_module.get(name: 'my_docs')!
|
||||||
|
|
||||||
// Print available pages
|
// Print available pages
|
||||||
for page_id, page in mysite.pages {
|
for page in mysite.pages {
|
||||||
console.print_item('Page: ${page_id} - "${page.title}"')
|
console.print_item('Page: "${page.src}" - "${page.title}"')
|
||||||
}
|
}
|
||||||
|
|
||||||
println('Site has ${mysite.pages.len} pages')
|
println('Site has ${mysite.pages.len} pages')
|
||||||
@@ -55,31 +54,38 @@ Factory functions to create and retrieve site instances:
|
|||||||
|
|
||||||
```v
|
```v
|
||||||
// Create a new site
|
// Create a new site
|
||||||
mut mysite := site.new(name: 'my_docs')!
|
mut mysite := site_module.new(name: 'my_docs')!
|
||||||
|
|
||||||
// Get existing site
|
// Get existing site
|
||||||
mut mysite := site.get(name: 'my_docs')!
|
mut mysite := site_module.get(name: 'my_docs')!
|
||||||
|
|
||||||
// Check if site exists
|
// Check if site exists
|
||||||
if site.exists(name: 'my_docs') {
|
if site_module.exists(name: 'my_docs') {
|
||||||
println('Site exists')
|
println('Site exists')
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get all site names
|
// Get all site names
|
||||||
site_names := site.list() // Returns []string
|
site_names := site_module.list() // Returns []string
|
||||||
|
|
||||||
// Get default site (creates if needed)
|
// Get default site (creates if needed)
|
||||||
mut default := site.default()!
|
mut default := site_module.default()!
|
||||||
```
|
```
|
||||||
|
|
||||||
### Site Object Structure
|
### Site Object Structure
|
||||||
|
|
||||||
```v
|
```v
|
||||||
|
@[heap]
|
||||||
pub struct Site {
|
pub struct Site {
|
||||||
pub mut:
|
pub mut:
|
||||||
pages map[string]Page // key: "collection:page_name"
|
doctree_path string // path to the export of the doctree site
|
||||||
nav NavConfig // Navigation sidebar
|
config SiteConfig // Full site configuration
|
||||||
siteconfig SiteConfig // Full configuration
|
pages []Page // Array of pages
|
||||||
|
links []Link // Array of links
|
||||||
|
categories []Category // Array of categories
|
||||||
|
announcements []Announcement // Array of announcements (can be multiple)
|
||||||
|
imports []ImportItem // Array of imports
|
||||||
|
build_dest []BuildDest // Production build destinations
|
||||||
|
build_dest_dev []BuildDest // Development build destinations
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -87,44 +93,60 @@ pub mut:
|
|||||||
|
|
||||||
```v
|
```v
|
||||||
// Access all pages
|
// Access all pages
|
||||||
pages := mysite.pages // map[string]Page
|
pages := mysite.pages // []Page
|
||||||
|
|
||||||
// Get specific page
|
// Access specific page by index
|
||||||
page := mysite.pages['docs:introduction']
|
page := mysite.pages[0]
|
||||||
|
|
||||||
// Page structure
|
// Page structure
|
||||||
pub struct Page {
|
pub struct Page {
|
||||||
pub mut:
|
pub mut:
|
||||||
id string // "collection:page_name"
|
src string // "collection:page_name" format (unique identifier)
|
||||||
title string // Display title
|
label string // Display label in navigation
|
||||||
|
title string // Display title on page (extracted from markdown if empty)
|
||||||
description string // SEO metadata
|
description string // SEO metadata
|
||||||
draft bool // Hidden if true
|
draft bool // Hide from navigation if true
|
||||||
hide_title bool // Don't show title in rendering
|
hide_title bool // Don't show title on page
|
||||||
src string // Source reference
|
hide bool // Hide page completely
|
||||||
|
category_id int // Optional category ID (0 = root level)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Navigation Structure
|
### Categories and Navigation
|
||||||
|
|
||||||
```v
|
```v
|
||||||
// Access sidebar navigation
|
// Access all categories
|
||||||
sidebar := mysite.nav.my_sidebar // []NavItem
|
categories := mysite.categories // []Category
|
||||||
|
|
||||||
|
// Category structure
|
||||||
|
pub struct Category {
|
||||||
|
pub mut:
|
||||||
|
path string // e.g., "Getting Started" or "Operations/Daily"
|
||||||
|
collapsible bool = true
|
||||||
|
collapsed bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate sidebar navigation
|
||||||
|
sidebar := mysite.sidebar() // Returns SideBar
|
||||||
|
|
||||||
|
// Sidebar structure
|
||||||
|
pub struct SideBar {
|
||||||
|
pub mut:
|
||||||
|
my_sidebar []NavItem
|
||||||
|
}
|
||||||
|
|
||||||
// NavItem is a sum type (can be one of three types):
|
|
||||||
pub type NavItem = NavDoc | NavCat | NavLink
|
pub type NavItem = NavDoc | NavCat | NavLink
|
||||||
|
|
||||||
// Navigation items:
|
|
||||||
|
|
||||||
pub struct NavDoc {
|
pub struct NavDoc {
|
||||||
pub:
|
pub:
|
||||||
id string // page id
|
path string // path is $collection/$name without .md
|
||||||
label string // display name
|
label string
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct NavCat {
|
pub struct NavCat {
|
||||||
pub mut:
|
pub mut:
|
||||||
label string
|
label string
|
||||||
collapsible bool
|
collapsible bool = true
|
||||||
collapsed bool
|
collapsed bool
|
||||||
items []NavItem // nested NavDoc/NavCat/NavLink
|
items []NavItem // nested NavDoc/NavCat/NavLink
|
||||||
}
|
}
|
||||||
@@ -137,10 +159,11 @@ pub:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Example: iterate navigation
|
// Example: iterate navigation
|
||||||
for item in mysite.nav.my_sidebar {
|
sidebar := mysite.sidebar()
|
||||||
|
for item in sidebar.my_sidebar {
|
||||||
match item {
|
match item {
|
||||||
NavDoc {
|
NavDoc {
|
||||||
println('Page: ${item.label} (${item.id})')
|
println('Page: ${item.label} (${item.path})')
|
||||||
}
|
}
|
||||||
NavCat {
|
NavCat {
|
||||||
println('Category: ${item.label} (${item.items.len} items)')
|
println('Category: ${item.label} (${item.items.len} items)')
|
||||||
@@ -150,11 +173,15 @@ for item in mysite.nav.my_sidebar {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Print formatted sidebar
|
||||||
|
println(mysite.sidebar_str())
|
||||||
```
|
```
|
||||||
|
|
||||||
### Site Configuration
|
### Site Configuration
|
||||||
|
|
||||||
```v
|
```v
|
||||||
|
@[heap]
|
||||||
pub struct SiteConfig {
|
pub struct SiteConfig {
|
||||||
pub mut:
|
pub mut:
|
||||||
// Core
|
// Core
|
||||||
@@ -175,15 +202,14 @@ pub mut:
|
|||||||
meta_title string // SEO title override
|
meta_title string // SEO title override
|
||||||
meta_image string // OG image override
|
meta_image string // OG image override
|
||||||
|
|
||||||
|
// Navigation & Footer
|
||||||
|
footer Footer
|
||||||
|
menu Menu
|
||||||
|
|
||||||
// Publishing
|
// Publishing
|
||||||
build_dest []BuildDest // Production destinations
|
build_dest []BuildDest // Production destinations
|
||||||
build_dest_dev []BuildDest // Development destinations
|
build_dest_dev []BuildDest // Development destinations
|
||||||
|
|
||||||
// Navigation & Footer
|
|
||||||
footer Footer
|
|
||||||
menu Menu
|
|
||||||
announcement AnnouncementBar
|
|
||||||
|
|
||||||
// Imports
|
// Imports
|
||||||
imports []ImportItem
|
imports []ImportItem
|
||||||
}
|
}
|
||||||
@@ -193,6 +219,59 @@ pub mut:
|
|||||||
path string
|
path string
|
||||||
ssh_name string
|
ssh_name string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct Menu {
|
||||||
|
pub mut:
|
||||||
|
title string
|
||||||
|
items []MenuItem
|
||||||
|
logo_alt string
|
||||||
|
logo_src string
|
||||||
|
logo_src_dark string
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct MenuItem {
|
||||||
|
pub mut:
|
||||||
|
href string
|
||||||
|
to string
|
||||||
|
label string
|
||||||
|
position string // "left" or "right"
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Footer {
|
||||||
|
pub mut:
|
||||||
|
style string // e.g., "dark" or "light"
|
||||||
|
links []FooterLink
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct FooterLink {
|
||||||
|
pub mut:
|
||||||
|
title string
|
||||||
|
items []FooterItem
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct FooterItem {
|
||||||
|
pub mut:
|
||||||
|
label string
|
||||||
|
to string
|
||||||
|
href string
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Announcement {
|
||||||
|
pub mut:
|
||||||
|
content string
|
||||||
|
background_color string
|
||||||
|
text_color string
|
||||||
|
is_closeable bool
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ImportItem {
|
||||||
|
pub mut:
|
||||||
|
url string // http or git url
|
||||||
|
path string
|
||||||
|
dest string // location in docs folder
|
||||||
|
replace map[string]string
|
||||||
|
visible bool = true
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -200,20 +279,32 @@ pub mut:
|
|||||||
## Core Concepts
|
## Core Concepts
|
||||||
|
|
||||||
### Site
|
### Site
|
||||||
A website configuration that contains pages, navigation structure, and metadata.
|
A website configuration that contains pages, navigation structure, and metadata. Each site is registered globally and can be retrieved by name.
|
||||||
|
|
||||||
### Page
|
### Page
|
||||||
A single page with:
|
A single documentation page with:
|
||||||
- **ID**: `collection:page_name` format
|
- **src**: `collection:page_name` format (unique identifier)
|
||||||
- **Title**: Display name (optional - extracted from markdown if not provided)
|
- **label**: Display name in sidebar
|
||||||
- **Description**: SEO metadata
|
- **title**: Display name on page (extracted from markdown if empty)
|
||||||
- **Draft**: Hidden from navigation if true
|
- **description**: SEO metadata
|
||||||
|
- **draft**: Hidden from navigation if true
|
||||||
|
- **category_id**: Links page to a category (0 = root level)
|
||||||
|
|
||||||
### Category (Section)
|
### Category (Section)
|
||||||
Groups related pages together in the navigation sidebar. Automatically collapsed/expandable.
|
Groups related pages together in the navigation sidebar. Categories can be nested and are automatically collapsed/expandable.
|
||||||
|
|
||||||
|
```heroscript
|
||||||
|
!!site.page_category
|
||||||
|
path: "Getting Started"
|
||||||
|
collapsible: true
|
||||||
|
collapsed: false
|
||||||
|
|
||||||
|
!!site.page src: "tech:intro"
|
||||||
|
category_id: 1 // Links to the category above
|
||||||
|
```
|
||||||
|
|
||||||
### Collection
|
### Collection
|
||||||
A logical group of pages. Pages reuse the collection once specified.
|
A logical group of pages. Pages reuse the collection once specified:
|
||||||
|
|
||||||
```heroscript
|
```heroscript
|
||||||
!!site.page src: "tech:intro" # Specifies collection "tech"
|
!!site.page src: "tech:intro" # Specifies collection "tech"
|
||||||
@@ -326,6 +417,8 @@ Overrides specific metadata for SEO without changing core config.
|
|||||||
|
|
||||||
### 5. Announcement Bar (Optional)
|
### 5. Announcement Bar (Optional)
|
||||||
|
|
||||||
|
Multiple announcements are supported and stored in an array:
|
||||||
|
|
||||||
```heroscript
|
```heroscript
|
||||||
!!site.announcement
|
!!site.announcement
|
||||||
content: "🎉 Version 2.0 is now available!"
|
content: "🎉 Version 2.0 is now available!"
|
||||||
@@ -334,61 +427,71 @@ Overrides specific metadata for SEO without changing core config.
|
|||||||
is_closeable: true
|
is_closeable: true
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**Note:** Each `!!site.announcement` block adds to the `announcements[]` array. Only the first is typically displayed, but all are stored.
|
||||||
|
|
||||||
### 6. Pages and Categories
|
### 6. Pages and Categories
|
||||||
|
|
||||||
#### Simple: Pages Without Categories
|
#### Simple: Pages Without Categories
|
||||||
|
|
||||||
```heroscript
|
```heroscript
|
||||||
!!site.page src: "guides:introduction"
|
!!site.page src: "guides:introduction"
|
||||||
|
label: "Getting Started"
|
||||||
title: "Getting Started"
|
title: "Getting Started"
|
||||||
description: "Introduction to the platform"
|
description: "Introduction to the platform"
|
||||||
|
|
||||||
!!site.page src: "installation"
|
!!site.page src: "installation"
|
||||||
|
label: "Installation"
|
||||||
title: "Installation"
|
title: "Installation"
|
||||||
|
|
||||||
!!site.page src: "configuration"
|
|
||||||
title: "Configuration"
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Advanced: Pages With Categories
|
#### Advanced: Pages With Categories
|
||||||
|
|
||||||
```heroscript
|
```heroscript
|
||||||
!!site.page_category
|
!!site.page_category
|
||||||
name: "basics"
|
path: "Getting Started"
|
||||||
label: "Getting Started"
|
collapsible: true
|
||||||
|
collapsed: false
|
||||||
|
|
||||||
!!site.page src: "guides:introduction"
|
!!site.page src: "guides:introduction"
|
||||||
|
label: "Introduction"
|
||||||
title: "Introduction"
|
title: "Introduction"
|
||||||
description: "Learn the basics"
|
description: "Learn the basics"
|
||||||
|
|
||||||
!!site.page src: "installation"
|
!!site.page src: "installation"
|
||||||
|
label: "Installation"
|
||||||
title: "Installation"
|
title: "Installation"
|
||||||
|
|
||||||
!!site.page src: "configuration"
|
!!site.page src: "configuration"
|
||||||
|
label: "Configuration"
|
||||||
title: "Configuration"
|
title: "Configuration"
|
||||||
|
|
||||||
!!site.page_category
|
!!site.page_category
|
||||||
name: "advanced"
|
path: "Advanced Topics"
|
||||||
label: "Advanced Topics"
|
collapsible: true
|
||||||
|
collapsed: false
|
||||||
|
|
||||||
!!site.page src: "advanced:performance"
|
!!site.page src: "advanced:performance"
|
||||||
|
label: "Performance Tuning"
|
||||||
title: "Performance Tuning"
|
title: "Performance Tuning"
|
||||||
|
|
||||||
!!site.page src: "scaling"
|
!!site.page src: "scaling"
|
||||||
|
label: "Scaling Guide"
|
||||||
title: "Scaling Guide"
|
title: "Scaling Guide"
|
||||||
```
|
```
|
||||||
|
|
||||||
**Page Parameters:**
|
**Page Parameters:**
|
||||||
- `src` - Source as `collection:page` (first page) or just `page_name` (reuse collection)
|
- `src` - Source as `collection:page_name` (first page) or just `page_name` (reuse collection)
|
||||||
|
- `label` - Display label in sidebar (required)
|
||||||
- `title` - Page title (optional, extracted from markdown if not provided)
|
- `title` - Page title (optional, extracted from markdown if not provided)
|
||||||
- `description` - Page description
|
- `description` - Page description
|
||||||
- `draft` - Hide from navigation (default: false)
|
- `draft` - Hide from navigation (default: false)
|
||||||
- `hide_title` - Don't show title in page (default: false)
|
- `hide_title` - Don't show title in page (default: false)
|
||||||
|
- `hide` - Hide page completely (default: false)
|
||||||
|
|
||||||
**Category Parameters:**
|
**Category Parameters:**
|
||||||
- `name` - Category identifier (required)
|
- `path` - Category path/label (required)
|
||||||
- `label` - Display label (auto-generated from name if omitted)
|
- `collapsible` - Allow collapsing (default: true)
|
||||||
- `position` - Sort order (auto-incremented if omitted)
|
- `collapsed` - Initially collapsed (default: false)
|
||||||
|
|
||||||
### 7. Content Imports
|
### 7. Content Imports
|
||||||
|
|
||||||
@@ -424,33 +527,42 @@ Overrides specific metadata for SEO without changing core config.
|
|||||||
title: "Technical Documentation"
|
title: "Technical Documentation"
|
||||||
|
|
||||||
!!site.page_category
|
!!site.page_category
|
||||||
name: "getting_started"
|
path: "Getting Started"
|
||||||
label: "Getting Started"
|
collapsible: true
|
||||||
|
collapsed: false
|
||||||
|
|
||||||
!!site.page src: "docs:intro"
|
!!site.page src: "docs:intro"
|
||||||
|
label: "Introduction"
|
||||||
title: "Introduction"
|
title: "Introduction"
|
||||||
|
|
||||||
!!site.page src: "installation"
|
!!site.page src: "installation"
|
||||||
|
label: "Installation"
|
||||||
title: "Installation"
|
title: "Installation"
|
||||||
|
|
||||||
!!site.page_category
|
!!site.page_category
|
||||||
name: "concepts"
|
path: "Core Concepts"
|
||||||
label: "Core Concepts"
|
collapsible: true
|
||||||
|
collapsed: false
|
||||||
|
|
||||||
!!site.page src: "concepts:architecture"
|
!!site.page src: "concepts:architecture"
|
||||||
|
label: "Architecture"
|
||||||
title: "Architecture"
|
title: "Architecture"
|
||||||
|
|
||||||
!!site.page src: "components"
|
!!site.page src: "components"
|
||||||
|
label: "Components"
|
||||||
title: "Components"
|
title: "Components"
|
||||||
|
|
||||||
!!site.page_category
|
!!site.page_category
|
||||||
name: "api"
|
path: "API Reference"
|
||||||
label: "API Reference"
|
collapsible: true
|
||||||
|
collapsed: false
|
||||||
|
|
||||||
!!site.page src: "api:rest"
|
!!site.page src: "api:rest"
|
||||||
|
label: "REST API"
|
||||||
title: "REST API"
|
title: "REST API"
|
||||||
|
|
||||||
!!site.page src: "graphql"
|
!!site.page src: "graphql"
|
||||||
|
label: "GraphQL"
|
||||||
title: "GraphQL"
|
title: "GraphQL"
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -462,12 +574,15 @@ Overrides specific metadata for SEO without changing core config.
|
|||||||
title: "Knowledge Base"
|
title: "Knowledge Base"
|
||||||
|
|
||||||
!!site.page src: "articles:first_post"
|
!!site.page src: "articles:first_post"
|
||||||
|
label: "Welcome to Our Blog"
|
||||||
title: "Welcome to Our Blog"
|
title: "Welcome to Our Blog"
|
||||||
|
|
||||||
!!site.page src: "second_post"
|
!!site.page src: "second_post"
|
||||||
|
label: "Understanding the Basics"
|
||||||
title: "Understanding the Basics"
|
title: "Understanding the Basics"
|
||||||
|
|
||||||
!!site.page src: "third_post"
|
!!site.page src: "third_post"
|
||||||
|
label: "Advanced Techniques"
|
||||||
title: "Advanced Techniques"
|
title: "Advanced Techniques"
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -484,20 +599,25 @@ Overrides specific metadata for SEO without changing core config.
|
|||||||
visible: true
|
visible: true
|
||||||
|
|
||||||
!!site.page_category
|
!!site.page_category
|
||||||
name: "product"
|
path: "Product Guide"
|
||||||
label: "Product Guide"
|
collapsible: true
|
||||||
|
collapsed: false
|
||||||
|
|
||||||
!!site.page src: "docs:overview"
|
!!site.page src: "docs:overview"
|
||||||
|
label: "Overview"
|
||||||
title: "Overview"
|
title: "Overview"
|
||||||
|
|
||||||
!!site.page src: "features"
|
!!site.page src: "features"
|
||||||
|
label: "Features"
|
||||||
title: "Features"
|
title: "Features"
|
||||||
|
|
||||||
!!site.page_category
|
!!site.page_category
|
||||||
name: "resources"
|
path: "Shared Resources"
|
||||||
label: "Shared Resources"
|
collapsible: true
|
||||||
|
collapsed: false
|
||||||
|
|
||||||
!!site.page src: "shared:common"
|
!!site.page src: "shared:common"
|
||||||
|
label: "Common Patterns"
|
||||||
title: "Common Patterns"
|
title: "Common Patterns"
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -554,4 +674,3 @@ hero docs -d -p /path/to/my_ebook
|
|||||||
# Build for production
|
# Build for production
|
||||||
hero docs -p /path/to/my_ebook
|
hero docs -p /path/to/my_ebook
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ module meta
|
|||||||
|
|
||||||
import incubaid.herolib.core.playbook
|
import incubaid.herolib.core.playbook
|
||||||
import incubaid.herolib.ui.console
|
import incubaid.herolib.ui.console
|
||||||
import os
|
|
||||||
|
|
||||||
// Big comprehensive HeroScript for testing
|
// Big comprehensive HeroScript for testing
|
||||||
const test_heroscript = '
|
const test_heroscript = '
|
||||||
@@ -94,74 +93,86 @@ const test_heroscript = '
|
|||||||
is_closeable: true
|
is_closeable: true
|
||||||
|
|
||||||
!!site.page_category
|
!!site.page_category
|
||||||
name: "getting_started"
|
path: "Getting Started"
|
||||||
label: "Getting Started"
|
collapsible: true
|
||||||
position: 10
|
collapsed: false
|
||||||
|
|
||||||
!!site.page src: "guides:introduction"
|
!!site.page src: "guides:introduction"
|
||||||
|
label: "Introduction to Test Docs"
|
||||||
title: "Introduction to Test Docs"
|
title: "Introduction to Test Docs"
|
||||||
description: "Learn what this project is about"
|
description: "Learn what this project is about"
|
||||||
|
|
||||||
!!site.page src: "installation"
|
!!site.page src: "installation"
|
||||||
|
label: "Installation Guide"
|
||||||
title: "Installation Guide"
|
title: "Installation Guide"
|
||||||
description: "How to install and setup"
|
description: "How to install and setup"
|
||||||
|
|
||||||
!!site.page src: "quick_start"
|
!!site.page src: "quick_start"
|
||||||
|
label: "Quick Start"
|
||||||
title: "Quick Start"
|
title: "Quick Start"
|
||||||
description: "5 minute quick start guide"
|
description: "5 minute quick start guide"
|
||||||
|
|
||||||
!!site.page_category
|
!!site.page_category
|
||||||
name: "concepts"
|
path: "Core Concepts"
|
||||||
label: "Core Concepts"
|
collapsible: true
|
||||||
position: 20
|
collapsed: false
|
||||||
|
|
||||||
!!site.page src: "concepts:architecture"
|
!!site.page src: "concepts:architecture"
|
||||||
|
label: "Architecture Overview"
|
||||||
title: "Architecture Overview"
|
title: "Architecture Overview"
|
||||||
description: "Understanding the system architecture"
|
description: "Understanding the system architecture"
|
||||||
|
|
||||||
!!site.page src: "components"
|
!!site.page src: "components"
|
||||||
|
label: "Key Components"
|
||||||
title: "Key Components"
|
title: "Key Components"
|
||||||
description: "Learn about the main components"
|
description: "Learn about the main components"
|
||||||
|
|
||||||
!!site.page src: "workflow"
|
!!site.page src: "workflow"
|
||||||
|
label: "Typical Workflow"
|
||||||
title: "Typical Workflow"
|
title: "Typical Workflow"
|
||||||
description: "How to use the system"
|
description: "How to use the system"
|
||||||
|
|
||||||
!!site.page_category
|
!!site.page_category
|
||||||
name: "api"
|
path: "API Reference"
|
||||||
label: "API Reference"
|
collapsible: true
|
||||||
position: 30
|
collapsed: false
|
||||||
|
|
||||||
!!site.page src: "api:rest"
|
!!site.page src: "api:rest"
|
||||||
|
label: "REST API"
|
||||||
title: "REST API"
|
title: "REST API"
|
||||||
description: "Complete REST API reference"
|
description: "Complete REST API reference"
|
||||||
|
|
||||||
!!site.page src: "graphql"
|
!!site.page src: "graphql"
|
||||||
|
label: "GraphQL API"
|
||||||
title: "GraphQL API"
|
title: "GraphQL API"
|
||||||
description: "GraphQL API documentation"
|
description: "GraphQL API documentation"
|
||||||
|
|
||||||
!!site.page src: "webhooks"
|
!!site.page src: "webhooks"
|
||||||
|
label: "Webhooks"
|
||||||
title: "Webhooks"
|
title: "Webhooks"
|
||||||
description: "Webhook configuration and examples"
|
description: "Webhook configuration and examples"
|
||||||
|
|
||||||
!!site.page_category
|
!!site.page_category
|
||||||
name: "advanced"
|
path: "Advanced Topics"
|
||||||
label: "Advanced Topics"
|
collapsible: true
|
||||||
position: 40
|
collapsed: false
|
||||||
|
|
||||||
!!site.page src: "advanced:performance"
|
!!site.page src: "advanced:performance"
|
||||||
|
label: "Performance Optimization"
|
||||||
title: "Performance Optimization"
|
title: "Performance Optimization"
|
||||||
description: "Tips for optimal performance"
|
description: "Tips for optimal performance"
|
||||||
|
|
||||||
!!site.page src: "scaling"
|
!!site.page src: "scaling"
|
||||||
|
label: "Scaling Guide"
|
||||||
title: "Scaling Guide"
|
title: "Scaling Guide"
|
||||||
description: "How to scale the system"
|
|
||||||
|
|
||||||
!!site.page src: "security"
|
!!site.page src: "security"
|
||||||
|
label: "Security Best Practices"
|
||||||
title: "Security Best Practices"
|
title: "Security Best Practices"
|
||||||
description: "Security considerations and best practices"
|
description: "Security considerations and best practices"
|
||||||
|
|
||||||
!!site.page src: "troubleshooting"
|
!!site.page src: "troubleshooting"
|
||||||
|
label: "Troubleshooting"
|
||||||
title: "Troubleshooting"
|
title: "Troubleshooting"
|
||||||
description: "Common issues and solutions"
|
description: "Common issues and solutions"
|
||||||
draft: false
|
draft: false
|
||||||
@@ -174,10 +185,8 @@ const test_heroscript = '
|
|||||||
path: "/tmp/docs-dev"
|
path: "/tmp/docs-dev"
|
||||||
'
|
'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
fn test_site1() ! {
|
fn test_site1() ! {
|
||||||
console.print_header('Site Module Comprehensive Test')
|
console.print_header('Site Module Comprehensive Test - Part 1')
|
||||||
console.lf()
|
console.lf()
|
||||||
|
|
||||||
// ========================================================
|
// ========================================================
|
||||||
@@ -200,7 +209,7 @@ fn test_site1() ! {
|
|||||||
// TEST 3: Retrieve site and validate
|
// TEST 3: Retrieve site and validate
|
||||||
// ========================================================
|
// ========================================================
|
||||||
console.print_item('TEST 3: Retrieving configured site')
|
console.print_item('TEST 3: Retrieving configured site')
|
||||||
mut test_site := site.get(name: 'test_docs')!
|
mut test_site := get(name: 'test_docs')!
|
||||||
console.print_green('✓ Site retrieved successfully')
|
console.print_green('✓ Site retrieved successfully')
|
||||||
console.lf()
|
console.lf()
|
||||||
|
|
||||||
@@ -208,7 +217,7 @@ fn test_site1() ! {
|
|||||||
// TEST 4: Validate SiteConfig
|
// TEST 4: Validate SiteConfig
|
||||||
// ========================================================
|
// ========================================================
|
||||||
console.print_header('Validating SiteConfig')
|
console.print_header('Validating SiteConfig')
|
||||||
mut config := &test_site.siteconfig
|
mut config := &test_site.config
|
||||||
|
|
||||||
help_test_string('Site Name', config.name, 'test_docs')
|
help_test_string('Site Name', config.name, 'test_docs')
|
||||||
help_test_string('Site Title', config.title, 'Test Documentation Site')
|
help_test_string('Site Title', config.title, 'Test Documentation Site')
|
||||||
@@ -221,15 +230,14 @@ fn test_site1() ! {
|
|||||||
help_test_string('Meta Title', config.meta_title, 'Test Docs - Advanced')
|
help_test_string('Meta Title', config.meta_title, 'Test Docs - Advanced')
|
||||||
help_test_string('Meta Image', config.meta_image, 'img/test-og-alternative.png')
|
help_test_string('Meta Image', config.meta_image, 'img/test-og-alternative.png')
|
||||||
|
|
||||||
assert config.build_dest.len == 1, 'Should have 1 production build destination'
|
assert test_site.build_dest.len == 1, 'Should have 1 production build destination'
|
||||||
console.print_green('✓ Production build dest: ${config.build_dest[0].path}')
|
console.print_green('✓ Production build dest: ${test_site.build_dest[0].path}')
|
||||||
|
|
||||||
assert config.build_dest_dev.len == 1, 'Should have 1 dev build destination'
|
assert test_site.build_dest_dev.len == 1, 'Should have 1 dev build destination'
|
||||||
console.print_green('✓ Dev build dest: ${config.build_dest_dev[0].path}')
|
console.print_green('✓ Dev build dest: ${test_site.build_dest_dev[0].path}')
|
||||||
|
|
||||||
console.lf()
|
console.lf()
|
||||||
|
|
||||||
|
|
||||||
// ========================================================
|
// ========================================================
|
||||||
// TEST 5: Validate Menu Configuration
|
// TEST 5: Validate Menu Configuration
|
||||||
// ========================================================
|
// ========================================================
|
||||||
@@ -253,7 +261,6 @@ fn test_site1() ! {
|
|||||||
|
|
||||||
console.lf()
|
console.lf()
|
||||||
|
|
||||||
|
|
||||||
// ========================================================
|
// ========================================================
|
||||||
// TEST 6: Validate Footer Configuration
|
// TEST 6: Validate Footer Configuration
|
||||||
// ========================================================
|
// ========================================================
|
||||||
@@ -291,7 +298,10 @@ fn test_site1() ! {
|
|||||||
// TEST 7: Validate Announcement Bar
|
// TEST 7: Validate Announcement Bar
|
||||||
// ========================================================
|
// ========================================================
|
||||||
console.print_header('Validating Announcement Bar')
|
console.print_header('Validating Announcement Bar')
|
||||||
mut announcement := config.announcement
|
assert test_site.announcements.len == 1, 'Should have 1 announcement, got ${test_site.announcements.len}'
|
||||||
|
console.print_green('✓ Announcement bar present')
|
||||||
|
|
||||||
|
mut announcement := test_site.announcements[0]
|
||||||
|
|
||||||
help_test_string('Announcement Content', announcement.content, '🎉 Version 2.0 is now available! Check out the new features.')
|
help_test_string('Announcement Content', announcement.content, '🎉 Version 2.0 is now available! Check out the new features.')
|
||||||
help_test_string('Announcement BG Color', announcement.background_color, '#1a472a')
|
help_test_string('Announcement BG Color', announcement.background_color, '#1a472a')
|
||||||
@@ -300,109 +310,150 @@ fn test_site1() ! {
|
|||||||
console.print_green('✓ Announcement bar configured correctly')
|
console.print_green('✓ Announcement bar configured correctly')
|
||||||
|
|
||||||
console.lf()
|
console.lf()
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
fn test_site2() ! {
|
fn test_site2() ! {
|
||||||
console.print_header('Site Module Comprehensive Test')
|
console.print_header('Site Module Comprehensive Test - Part 2')
|
||||||
console.lf()
|
console.lf()
|
||||||
|
|
||||||
|
reset()
|
||||||
|
|
||||||
mut plbook := playbook.new(text: test_heroscript)!
|
mut plbook := playbook.new(text: test_heroscript)!
|
||||||
mut test_site := site.get(name: 'test_docs')!
|
play(mut plbook)!
|
||||||
|
mut test_site := get(name: 'test_docs')!
|
||||||
|
|
||||||
// ========================================================
|
// ========================================================
|
||||||
// TEST 8: Validate Pages
|
// TEST 8: Validate Pages
|
||||||
// ========================================================
|
// ========================================================
|
||||||
console.print_header('Validating Pages')
|
console.print_header('Validating Pages')
|
||||||
mut pages := test_site.pages.clone()
|
|
||||||
|
|
||||||
assert pages.len == 13, 'Should have 13 pages, got ${pages.len}'
|
println(test_site)
|
||||||
console.print_green('✓ Total pages: ${pages.len}')
|
|
||||||
|
assert test_site.pages.len == 13, 'Should have 13 pages, got ${test_site.pages.len}'
|
||||||
|
console.print_green('✓ Total pages: ${test_site.pages.len}')
|
||||||
|
|
||||||
// List and validate pages
|
// List and validate pages
|
||||||
mut page_ids := pages.keys()
|
for i, page in test_site.pages {
|
||||||
page_ids.sort()
|
console.print_debug(' Page ${i}: "${page.src}" - "${page.label}"')
|
||||||
|
|
||||||
for page_id in page_ids {
|
|
||||||
mut page := pages[page_id]
|
|
||||||
console.print_debug(' Page: ${page_id} - "${page.title}"')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate specific pages
|
// Validate specific pages exist by src
|
||||||
assert 'guides:introduction' in pages, 'guides:introduction page not found'
|
mut src_exists := false
|
||||||
|
for page in test_site.pages {
|
||||||
|
if page.src == 'guides:introduction' {
|
||||||
|
src_exists = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert src_exists, 'guides:introduction page not found'
|
||||||
console.print_green('✓ Found guides:introduction')
|
console.print_green('✓ Found guides:introduction')
|
||||||
|
|
||||||
assert 'concepts:architecture' in pages, 'concepts:architecture page not found'
|
src_exists = false
|
||||||
|
for page in test_site.pages {
|
||||||
|
if page.src == 'concepts:architecture' {
|
||||||
|
src_exists = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert src_exists, 'concepts:architecture page not found'
|
||||||
console.print_green('✓ Found concepts:architecture')
|
console.print_green('✓ Found concepts:architecture')
|
||||||
|
|
||||||
assert 'api:rest' in pages, 'api:rest page not found'
|
src_exists = false
|
||||||
|
for page in test_site.pages {
|
||||||
|
if page.src == 'api:rest' {
|
||||||
|
src_exists = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert src_exists, 'api:rest page not found'
|
||||||
console.print_green('✓ Found api:rest')
|
console.print_green('✓ Found api:rest')
|
||||||
|
|
||||||
console.lf()
|
console.lf()
|
||||||
|
|
||||||
// ========================================================
|
// ========================================================
|
||||||
// TEST 9: Validate Navigation Structure
|
// TEST 9: Validate Categories
|
||||||
// ========================================================
|
// ========================================================
|
||||||
console.print_header('Validating Navigation Structure')
|
console.print_header('Validating Categories')
|
||||||
mut sidebar := unsafe { test_site.nav.my_sidebar.clone() }
|
|
||||||
|
|
||||||
console.print_item('Navigation sidebar has ${sidebar.len} items')
|
assert test_site.categories.len == 4, 'Should have 4 categories, got ${test_site.categories.len}'
|
||||||
|
console.print_green('✓ Total categories: ${test_site.categories.len}')
|
||||||
|
|
||||||
// Count categories
|
for i, category in test_site.categories {
|
||||||
mut category_count := 0
|
console.print_debug(' Category ${i}: "${category.path}" (collapsible: ${category.collapsible}, collapsed: ${category.collapsed})')
|
||||||
mut doc_count := 0
|
}
|
||||||
|
|
||||||
for item in sidebar {
|
// Validate category paths
|
||||||
|
mut category_paths := test_site.categories.map(it.path)
|
||||||
|
assert category_paths.contains('Getting Started'), 'Missing "Getting Started" category'
|
||||||
|
console.print_green('✓ Found "Getting Started" category')
|
||||||
|
|
||||||
|
assert category_paths.contains('Core Concepts'), 'Missing "Core Concepts" category'
|
||||||
|
console.print_green('✓ Found "Core Concepts" category')
|
||||||
|
|
||||||
|
assert category_paths.contains('API Reference'), 'Missing "API Reference" category'
|
||||||
|
console.print_green('✓ Found "API Reference" category')
|
||||||
|
|
||||||
|
assert category_paths.contains('Advanced Topics'), 'Missing "Advanced Topics" category'
|
||||||
|
console.print_green('✓ Found "Advanced Topics" category')
|
||||||
|
|
||||||
|
console.lf()
|
||||||
|
|
||||||
|
// ========================================================
|
||||||
|
// TEST 10: Validate Navigation Structure (Sidebar)
|
||||||
|
// ========================================================
|
||||||
|
console.print_header('Validating Navigation Structure (Sidebar)')
|
||||||
|
|
||||||
|
mut sidebar := test_site.sidebar()
|
||||||
|
|
||||||
|
console.print_item('Sidebar has ${sidebar.my_sidebar.len} root items')
|
||||||
|
assert sidebar.my_sidebar.len > 0, 'Sidebar should not be empty'
|
||||||
|
console.print_green('✓ Sidebar generated successfully')
|
||||||
|
|
||||||
|
// Count categories in sidebar
|
||||||
|
mut sidebar_category_count := 0
|
||||||
|
mut sidebar_doc_count := 0
|
||||||
|
|
||||||
|
for item in sidebar.my_sidebar {
|
||||||
match item {
|
match item {
|
||||||
NavCat {
|
NavCat {
|
||||||
category_count++
|
sidebar_category_count++
|
||||||
console.print_debug(' Category: "${item.label}" with ${item.items.len} sub-items')
|
|
||||||
}
|
}
|
||||||
NavDoc {
|
NavDoc {
|
||||||
doc_count++
|
sidebar_doc_count++
|
||||||
console.print_debug(' Doc: "${item.label}" (${item.id})')
|
|
||||||
}
|
}
|
||||||
NavLink {
|
else {
|
||||||
console.print_debug(' Link: "${item.label}" -> ${item.href}')
|
// Other types
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assert category_count == 4, 'Should have 4 categories, got ${category_count}'
|
console.print_item('Sidebar contains: ${sidebar_category_count} categories, ${sidebar_doc_count} docs')
|
||||||
console.print_green('✓ Navigation has 4 categories')
|
|
||||||
|
|
||||||
// Validate category structure
|
// Detailed sidebar validation
|
||||||
for item in sidebar {
|
for i, item in sidebar.my_sidebar {
|
||||||
match item {
|
match item {
|
||||||
NavCat {
|
NavCat {
|
||||||
console.print_item('Category: "${item.label}"')
|
console.print_debug(' Category ${i}: "${item.label}" (${item.items.len} items)')
|
||||||
println(' Collapsible: ${item.collapsible}, Collapsed: ${item.collapsed}')
|
|
||||||
println(' Items: ${item.items.len}')
|
|
||||||
|
|
||||||
// Validate sub-items
|
|
||||||
for sub_item in item.items {
|
for sub_item in item.items {
|
||||||
match sub_item {
|
match sub_item {
|
||||||
NavDoc {
|
NavDoc {
|
||||||
println(' - ${sub_item.label} (${sub_item.id})')
|
console.print_debug(' └─ Doc: "${sub_item.label}" (${sub_item.path})')
|
||||||
}
|
|
||||||
else {
|
|
||||||
println(' - Unexpected item type')
|
|
||||||
}
|
}
|
||||||
|
else {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
NavDoc {
|
||||||
|
console.print_debug(' Doc ${i}: "${item.label}" (${item.path})')
|
||||||
|
}
|
||||||
else {}
|
else {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
console.lf()
|
console.lf()
|
||||||
|
|
||||||
|
|
||||||
// ========================================================
|
// ========================================================
|
||||||
// TEST 10: Validate Site Factory
|
// TEST 11: Validate Site Factory
|
||||||
// ========================================================
|
// ========================================================
|
||||||
console.print_header('Validating Site Factory')
|
console.print_header('Validating Site Factory')
|
||||||
|
|
||||||
@@ -420,11 +471,16 @@ fn test_site2() ! {
|
|||||||
|
|
||||||
console.lf()
|
console.lf()
|
||||||
|
|
||||||
// println(test_site)
|
// ========================================================
|
||||||
// if true{panic("ss33")}
|
// TEST 12: Validate Print Output
|
||||||
|
// ========================================================
|
||||||
|
console.print_header('Site Sidebar String Output')
|
||||||
|
println(test_site.sidebar_str())
|
||||||
|
if true {
|
||||||
|
panic('End of tests reached - panic to stop further execution')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ============================================================
|
// ============================================================
|
||||||
// Helper Functions for Testing
|
// Helper Functions for Testing
|
||||||
// ============================================================
|
// ============================================================
|
||||||
|
|||||||
Reference in New Issue
Block a user