match template and models for docusaurus
This commit is contained in:
@@ -46,12 +46,6 @@ pub fn (mut f DocusaurusFactory) get(args_ DSiteGetArgs) !&DocSite {
|
||||
}
|
||||
args.path = args.path.replace('~', os.home_dir())
|
||||
|
||||
mut r := gs.get_repo(
|
||||
url: 'https://github.com/freeflowuniverse/docusaurus_template.git'
|
||||
reset: args.update
|
||||
)!
|
||||
mut template_path := r.patho()!
|
||||
|
||||
// First, check if the new site args provides a configuration
|
||||
if cfg := args.config {
|
||||
// Use the provided config
|
||||
|
||||
@@ -112,7 +112,7 @@ pub fn load_configuration(cfg_path string) !Configuration {
|
||||
println('Found primary HeroScript file: ${hero_script_main_file_path}. Attempting to load configuration.')
|
||||
|
||||
// Use siteconfig.new from factory.v. This function handles PlayBook creation, playing, and Redis interaction.
|
||||
site_cfg_ref := siteconfig.new(cfg_path) or {
|
||||
site_cfg_ref := siteconfig.new(hero_script_main_file_path) or {
|
||||
eprintln('Error loading configuration from HeroScript file ${hero_script_main_file_path}: ${err}. Falling back to JSON.')
|
||||
return load_configuration_from_json(cfg_path) // Fallback to JSON private helper
|
||||
}
|
||||
@@ -151,15 +151,27 @@ pub fn load_configuration(cfg_path string) !Configuration {
|
||||
title: site_cfg_from_heroscript.title,
|
||||
tagline: site_cfg_from_heroscript.tagline,
|
||||
favicon: site_cfg_from_heroscript.favicon,
|
||||
url: site_cfg_from_heroscript.url,
|
||||
base_url: site_cfg_from_heroscript.base_url,
|
||||
url_home: site_cfg_from_heroscript.url_home,
|
||||
image: site_cfg_from_heroscript.image, // General site image
|
||||
metadata: Metadata{
|
||||
title: site_cfg_from_heroscript.meta_title, // Specific title for metadata
|
||||
description: site_cfg_from_heroscript.description,
|
||||
image: site_cfg_from_heroscript.meta_image, // Use the specific meta_image from siteconfig
|
||||
},
|
||||
build_dest: site_cfg_from_heroscript.build_dest.map(it.path),
|
||||
build_dest_dev: site_cfg_from_heroscript.build_dest_dev.map(it.path),
|
||||
copyright: site_cfg_from_heroscript.copyright,
|
||||
name: site_cfg_from_heroscript.name,
|
||||
// url, base_url, url_home, image, metadata, build_dest etc. from site_cfg_from_heroscript.main if available
|
||||
// or leave to fix_configuration. siteconfig.SiteConfig doesn't have a direct 'Main' substruct.
|
||||
// These fields are top-level in siteconfig.SiteConfig.
|
||||
},
|
||||
navbar: Navbar{
|
||||
title: site_cfg_from_heroscript.menu.title,
|
||||
// logo: site_cfg_from_heroscript.menu.logo, // siteconfig.Menu doesn't have a direct logo struct like docusaurus.Logo
|
||||
logo: Logo{
|
||||
alt: site_cfg_from_heroscript.menu.logo_alt,
|
||||
src: site_cfg_from_heroscript.menu.logo_src,
|
||||
src_dark: site_cfg_from_heroscript.menu.logo_src_dark,
|
||||
},
|
||||
items: nav_items,
|
||||
},
|
||||
footer: Footer{
|
||||
|
||||
106
lib/web/docusaurus/model_configuration_test.v
Normal file
106
lib/web/docusaurus/model_configuration_test.v
Normal file
@@ -0,0 +1,106 @@
|
||||
module docusaurus
|
||||
|
||||
import os
|
||||
import freeflowuniverse.herolib.core.pathlib
|
||||
import freeflowuniverse.herolib.core.base // For context and Redis, if test needs to manage it
|
||||
import time
|
||||
|
||||
const test_heroscript_content = "!!site.config\n name:\"Kristof\"\n title:\"Internet Geek\"\n tagline:\"Internet Geek\"\n url:\"https://friends.threefold.info\"\n url_home:\"docs/\"\n base_url:\"/kristof/\"\n favicon:\"img/favicon.png\"\n image:\"img/tf_graph.png\"\n copyright:\"Kristof\"\n\n!!site.config_meta\n description:\"ThreeFold is laying the foundation for a geo aware Web 4, the next generation of the Internet.\"\n image:\"https://threefold.info/kristof/img/tf_graph.png\"\n title:\"ThreeFold Technology Vision\"\n\n!!site.build_dest\n ssh_name:\"production\"\n path:\"/root/hero/www/info/kristof\"\n\n!!site.navbar\n title:\"Kristof = Chief Executive Geek\"\n logo_alt:\"Kristof Logo\"\n logo_src:\"img/logo.svg\"\n logo_src_dark:\"img/logo.svg\"\n\n!!site.navbar_item\n label:\"ThreeFold Technology\"\n href:\"https://threefold.info/kristof/\"\n position:\"right\"\n\n!!site.navbar_item\n label:\"ThreeFold.io\"\n href:\"https://threefold.io\"\n position:\"right\"\n\n!!site.footer\n style:\"dark\"\n\n!!site.footer_item\n title:\"Docs\"\n label:\"Introduction\"\n href:\"/docs\"\n\n!!site.footer_item\n title:\"Docs\"\n label:\"TFGrid V4 Docs\"\n href:\"https://docs.threefold.io/\"\n\n!!site.footer_item\n title:\"Community\"\n label:\"Telegram\"\n href:\"https://t.me/threefold\"\n\n!!site.footer_item\n title:\"Community\"\n label:\"X\"\n href:\"https://x.com/threefold_io\"\n\n!!site.footer_item\n title:\"Links\"\n label:\"ThreeFold.io\"\n href:\"https://threefold.io\"\n"
|
||||
|
||||
fn test_load_configuration_from_heroscript() ! {
|
||||
// Ensure context is initialized for Redis connection if siteconfig.new() needs it implicitly
|
||||
base.context()!
|
||||
|
||||
temp_cfg_dir := os.join_path(os.temp_dir(), "test_docusaurus_cfg_${time.ticks()}")
|
||||
os.mkdir_all(temp_cfg_dir)!
|
||||
defer {
|
||||
os.rmdir_all(temp_cfg_dir) or { eprintln("Error removing temp dir.") }
|
||||
}
|
||||
|
||||
heroscript_path := os.join_path(temp_cfg_dir, 'config.heroscript')
|
||||
os.write_file(heroscript_path, test_heroscript_content)!
|
||||
|
||||
config := load_configuration(temp_cfg_dir)!
|
||||
|
||||
// Main assertions
|
||||
assert config.main.name == 'kristof' // texttools.name_fix converts to lowercase
|
||||
assert config.main.title == 'Internet Geek'
|
||||
assert config.main.tagline == 'Internet Geek'
|
||||
assert config.main.url == 'https://friends.threefold.info'
|
||||
assert config.main.url_home == 'docs/'
|
||||
assert config.main.base_url == '/kristof/'
|
||||
assert config.main.favicon == 'img/favicon.png'
|
||||
assert config.main.image == 'img/tf_graph.png'
|
||||
assert config.main.copyright == 'Kristof'
|
||||
|
||||
// Metadata assertions
|
||||
assert config.main.metadata.title == 'ThreeFold Technology Vision'
|
||||
assert config.main.metadata.description == 'ThreeFold is laying the foundation for a geo aware Web 4, the next generation of the Internet.'
|
||||
assert config.main.metadata.image == 'https://threefold.info/kristof/img/tf_graph.png'
|
||||
|
||||
// Build Dest assertions
|
||||
assert config.main.build_dest.len == 1
|
||||
assert config.main.build_dest[0] == '/root/hero/www/info/kristof'
|
||||
|
||||
// Navbar assertions
|
||||
assert config.navbar.title == 'Kristof = Chief Executive Geek'
|
||||
assert config.navbar.logo.alt == 'Kristof Logo'
|
||||
assert config.navbar.logo.src == 'img/logo.svg'
|
||||
assert config.navbar.logo.src_dark == 'img/logo.svg'
|
||||
assert config.navbar.items.len == 2
|
||||
assert config.navbar.items[0].label == 'ThreeFold Technology'
|
||||
assert config.navbar.items[0].href == 'https://threefold.info/kristof/'
|
||||
assert config.navbar.items[0].position == 'right'
|
||||
assert config.navbar.items[1].label == 'ThreeFold.io'
|
||||
assert config.navbar.items[1].href == 'https://threefold.io'
|
||||
assert config.navbar.items[1].position == 'right'
|
||||
|
||||
// Footer assertions
|
||||
assert config.footer.style == 'dark'
|
||||
assert config.footer.links.len == 3 // 'Docs', 'Community', 'Links'
|
||||
|
||||
// Check 'Docs' footer links
|
||||
mut docs_link_found := false
|
||||
for link in config.footer.links {
|
||||
if link.title == 'Docs' {
|
||||
docs_link_found = true
|
||||
assert link.items.len == 2
|
||||
assert link.items[0].label == 'Introduction'
|
||||
assert link.items[0].href == '/docs'
|
||||
assert link.items[1].label == 'TFGrid V4 Docs'
|
||||
assert link.items[1].href == 'https://docs.threefold.io/'
|
||||
break
|
||||
}
|
||||
}
|
||||
assert docs_link_found
|
||||
|
||||
// Check 'Community' footer links
|
||||
mut community_link_found := false
|
||||
for link in config.footer.links {
|
||||
if link.title == 'Community' {
|
||||
community_link_found = true
|
||||
assert link.items.len == 2
|
||||
assert link.items[0].label == 'Telegram'
|
||||
assert link.items[0].href == 'https://t.me/threefold'
|
||||
assert link.items[1].label == 'X'
|
||||
assert link.items[1].href == 'https://x.com/threefold_io'
|
||||
break
|
||||
}
|
||||
}
|
||||
assert community_link_found
|
||||
|
||||
// Check 'Links' footer links
|
||||
mut links_link_found := false
|
||||
for link in config.footer.links {
|
||||
if link.title == 'Links' {
|
||||
links_link_found = true
|
||||
assert link.items.len == 1
|
||||
assert link.items[0].label == 'ThreeFold.io'
|
||||
assert link.items[0].href == 'https://threefold.io'
|
||||
break
|
||||
}
|
||||
}
|
||||
assert links_link_found
|
||||
|
||||
println("test_load_configuration_from_heroscript passed successfully.")
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
{
|
||||
"name": "@{name}",
|
||||
"version": "0.0.1",
|
||||
"name": "docs-website",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"docusaurus": "docusaurus",
|
||||
"start": "docusaurus start",
|
||||
"start": "docusaurus start --no-open",
|
||||
"build": "docusaurus build",
|
||||
"swizzle": "docusaurus swizzle",
|
||||
"deploy": "docusaurus deploy",
|
||||
@@ -15,25 +15,42 @@
|
||||
"typecheck": "tsc"
|
||||
},
|
||||
"dependencies": {
|
||||
"@@docusaurus/core": "^3.1.0",
|
||||
"@@docusaurus/preset-classic": "^3.1.0",
|
||||
"@@mdx-js/react": "^3.0.0",
|
||||
"@docusaurus/core": "^3.7.0",
|
||||
"@docusaurus/preset-classic": "^3.7.0",
|
||||
"@docusaurus/theme-mermaid": "^3.7.0",
|
||||
"@mdx-js/react": "^3.0.0",
|
||||
"buffer": "^6.0.3",
|
||||
"chart.js": "^4.4.7",
|
||||
"clsx": "^2.0.0",
|
||||
"echarts": "^5.6.0",
|
||||
"pako": "^2.1.0",
|
||||
"prism-react-renderer": "^2.3.0",
|
||||
"react": "^18.0.0",
|
||||
"react-dom": "^18.0.0"
|
||||
"react": "^18.2.0",
|
||||
"react-chartjs-2": "^5.3.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"remark-kroki": "^0.3.7",
|
||||
"zlib": "^1.0.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@@docusaurus/module-type-aliases": "^3.1.0",
|
||||
"@@docusaurus/tsconfig": "^3.1.0",
|
||||
"@@docusaurus/types": "^3.1.0",
|
||||
"typescript": "^5.2.2"
|
||||
"@docusaurus/module-type-aliases": "^3.7.0",
|
||||
"@docusaurus/tsconfig": "3.5.2",
|
||||
"@docusaurus/types": "3.5.2",
|
||||
"typescript": "~5.5.2"
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [">0.5%", "not dead", "not op_mini all"],
|
||||
"development": ["last 1 chrome version", "last 1 firefox version", "last 1 safari version"]
|
||||
"production": [
|
||||
">0.5%",
|
||||
"not dead",
|
||||
"not op_mini all"
|
||||
],
|
||||
"development": [
|
||||
"last 3 chrome version",
|
||||
"last 3 firefox version",
|
||||
"last 5 safari version"
|
||||
]
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0"
|
||||
}
|
||||
"bun": ">=1.2.5"
|
||||
},
|
||||
"packageManager": "bun@1.2.5"
|
||||
}
|
||||
@@ -3,16 +3,27 @@ module siteconfig
|
||||
pub struct SiteConfig {
|
||||
pub mut:
|
||||
name string
|
||||
title string = 'My Documentation Site'
|
||||
description string
|
||||
title string = 'My Documentation Site' // General site title
|
||||
description string // General site description, can be used for meta if meta_description not set
|
||||
tagline string
|
||||
favicon string = 'img/favicon.png'
|
||||
image string = 'img/tf_graph.png'
|
||||
image string = 'img/tf_graph.png' // General site image, can be used for meta if meta_image not set
|
||||
copyright string = 'someone'
|
||||
footer Footer
|
||||
menu Menu
|
||||
import_collections []CollectionsImport
|
||||
pages []Page
|
||||
|
||||
// New fields for Docusaurus compatibility
|
||||
url string // The main URL of the site (from !!site.config url:)
|
||||
base_url string // The base URL for Docusaurus (from !!site.config base_url:)
|
||||
url_home string // The home page path relative to base_url (from !!site.config url_home:)
|
||||
|
||||
meta_title string // Specific title for SEO metadata (from !!site.config_meta title:)
|
||||
meta_image string // Specific image for SEO metadata (og:image) (from !!site.config_meta image:)
|
||||
|
||||
build_dest []BuildDest // Production build destinations (from !!site.build_dest)
|
||||
build_dest_dev []BuildDest // Development build destinations (from !!site.build_dest_dev)
|
||||
}
|
||||
|
||||
pub struct Page {
|
||||
@@ -60,8 +71,17 @@ pub mut:
|
||||
|
||||
pub struct Menu {
|
||||
pub mut:
|
||||
title string
|
||||
items []MenuItem
|
||||
title string
|
||||
items []MenuItem
|
||||
logo_alt string @[json: 'logoAlt']
|
||||
logo_src string @[json: 'logoSrc']
|
||||
logo_src_dark string @[json: 'logoSrcDark']
|
||||
}
|
||||
|
||||
pub struct BuildDest {
|
||||
pub mut:
|
||||
path string
|
||||
ssh_name string
|
||||
}
|
||||
|
||||
pub struct CollectionsImport {
|
||||
|
||||
@@ -14,6 +14,30 @@ pub mut:
|
||||
reset bool
|
||||
}
|
||||
|
||||
fn play_build_dest(mut plbook PlayBook, mut config SiteConfig) ! {
|
||||
build_dest_actions := plbook.find(filter: 'site.build_dest')!
|
||||
for action in build_dest_actions {
|
||||
mut p := action.params
|
||||
mut dest := BuildDest{
|
||||
path: p.get('path')!
|
||||
ssh_name: p.get_default('ssh_name', '')!
|
||||
}
|
||||
config.build_dest << dest
|
||||
}
|
||||
}
|
||||
|
||||
fn play_build_dest_dev(mut plbook PlayBook, mut config SiteConfig) ! {
|
||||
build_dest_dev_actions := plbook.find(filter: 'site.build_dest_dev')!
|
||||
for action in build_dest_dev_actions {
|
||||
mut p := action.params
|
||||
mut dest_dev := BuildDest{
|
||||
path: p.get('path')!
|
||||
ssh_name: p.get_default('ssh_name', '')!
|
||||
}
|
||||
config.build_dest_dev << dest_dev
|
||||
}
|
||||
}
|
||||
|
||||
pub fn play(args_ PlayArgs) ! {
|
||||
mut context := base.context()!
|
||||
mut redis := context.redis()!
|
||||
@@ -28,6 +52,8 @@ pub fn play(args_ PlayArgs) ! {
|
||||
play_menu(mut plbook, mut config)!
|
||||
play_footer(mut plbook, mut config)!
|
||||
play_pages(mut plbook, mut config)!
|
||||
play_build_dest(mut plbook, mut config)!
|
||||
play_build_dest_dev(mut plbook, mut config)!
|
||||
|
||||
json_config := json.encode(config)
|
||||
redis.hset('siteconfigs', config.name, json_config)!
|
||||
@@ -35,6 +61,44 @@ pub fn play(args_ PlayArgs) ! {
|
||||
}
|
||||
|
||||
fn play_config(mut plbook PlayBook, mut config SiteConfig) ! {
|
||||
// Process !!site.config
|
||||
config_actions := plbook.find(filter: 'site.config')!
|
||||
if config_actions.len == 0 {
|
||||
return error('no site.config directive found')
|
||||
}
|
||||
if config_actions.len > 1 {
|
||||
return error('multiple site.config directives found, only one is allowed')
|
||||
}
|
||||
for action in config_actions { // Should be only one
|
||||
mut p := action.params
|
||||
config.name = p.get('name')!
|
||||
config.name = texttools.name_fix(config.name)
|
||||
config.title = p.get_default('title', 'Documentation Site')!
|
||||
config.description = p.get_default('description', 'Comprehensive documentation built with Docusaurus.')!
|
||||
config.tagline = p.get_default('tagline', 'Your awesome documentation')!
|
||||
config.favicon = p.get_default('favicon', 'img/favicon.png')!
|
||||
config.image = p.get_default('image', 'img/tf_graph.png')!
|
||||
config.copyright = p.get_default('copyright', '© ' + time.now().year.str() + ' Example Organization')!
|
||||
config.url = p.get_default('url', '')!
|
||||
config.base_url = p.get_default('base_url', '/')!
|
||||
config.url_home = p.get_default('url_home', '')!
|
||||
}
|
||||
|
||||
// Process !!site.config_meta for specific metadata overrides
|
||||
meta_actions := plbook.find(filter: 'site.config_meta')!
|
||||
for action in meta_actions { // Should ideally be one
|
||||
mut p_meta := action.params
|
||||
// If 'title' is present in site.config_meta, it overrides. Otherwise, meta_title remains empty or uses site.config.title logic in docusaurus model.
|
||||
config.meta_title = p_meta.get_default('title', config.title)!
|
||||
// If 'image' is present in site.config_meta, it overrides. Otherwise, meta_image remains empty or uses site.config.image logic.
|
||||
config.meta_image = p_meta.get_default('image', config.image)!
|
||||
// 'description' from site.config_meta can also be parsed here if a separate meta_description field is added to SiteConfig
|
||||
// For now, config.description (from site.config) is used as the primary source or fallback.
|
||||
}
|
||||
}
|
||||
|
||||
// Remove the old play_config content as it's now part of the new one above
|
||||
/*
|
||||
config_actions := plbook.find(filter: 'site.config')!
|
||||
if config_actions.len == 0 {
|
||||
return error('no config found')
|
||||
@@ -52,10 +116,7 @@ fn play_config(mut plbook PlayBook, mut config SiteConfig) ! {
|
||||
config.tagline = p.get_default('tagline', 'Your awesome documentation')!
|
||||
config.favicon = p.get_default('favicon', 'img/favicon.png')!
|
||||
config.image = p.get_default('image', 'img/tf_graph.png')!
|
||||
config.copyright = p.get_default('copyright', '© ' + time.now().year.str() +
|
||||
' Example Organization')!
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
fn play_collections(mut plbook PlayBook, mut config SiteConfig) ! {
|
||||
import_actions := plbook.find(filter: 'site.collections')!
|
||||
@@ -84,13 +145,30 @@ fn play_collections(mut plbook PlayBook, mut config SiteConfig) ! {
|
||||
}
|
||||
|
||||
fn play_menu(mut plbook PlayBook, mut config SiteConfig) ! {
|
||||
menu_actions := plbook.find(filter: 'site.menu')!
|
||||
for action in menu_actions {
|
||||
mut p := action.params
|
||||
config.menu.title = p.get_default('title', config.title)!
|
||||
navbar_actions := plbook.find(filter: 'site.navbar')!
|
||||
if navbar_actions.len > 0 {
|
||||
for action in navbar_actions { // Should ideally be one, but loop for safety
|
||||
mut p := action.params
|
||||
config.menu.title = p.get_default('title', config.title)! // Use existing config.title as ultimate fallback
|
||||
config.menu.logo_alt = p.get_default('logo_alt', '')!
|
||||
config.menu.logo_src = p.get_default('logo_src', '')!
|
||||
config.menu.logo_src_dark = p.get_default('logo_src_dark', '')!
|
||||
}
|
||||
} else {
|
||||
// Fallback to site.menu for title if site.navbar is not found
|
||||
menu_actions := plbook.find(filter: 'site.menu')!
|
||||
for action in menu_actions {
|
||||
mut p := action.params
|
||||
config.menu.title = p.get_default('title', config.title)!
|
||||
}
|
||||
}
|
||||
|
||||
mut menu_item_actions := plbook.find(filter: 'site.navbar_item')!
|
||||
if menu_item_actions.len == 0 {
|
||||
// Fallback to site.menu_item if site.navbar_item is not found
|
||||
menu_item_actions = plbook.find(filter: 'site.menu_item')!
|
||||
}
|
||||
|
||||
menu_item_actions := plbook.find(filter: 'site.menu_item')!
|
||||
for action in menu_item_actions {
|
||||
mut p := action.params
|
||||
mut item := MenuItem{
|
||||
|
||||
Reference in New Issue
Block a user