- Consolidate site configuration loading and parsing - Refactor navbar and menu item processing logic - Add console output for configuration steps - Update copyright year dynamically - Simplify and clarify parameter handling - Enhance error handling for missing required parameters
213 lines
6.4 KiB
V
213 lines
6.4 KiB
V
module atlas
|
|
|
|
import incubaid.herolib.core.pathlib
|
|
import incubaid.herolib.core.base
|
|
import json
|
|
|
|
@[params]
|
|
pub struct ExportArgs {
|
|
pub mut:
|
|
destination string @[required]
|
|
reset bool = true
|
|
include bool = true
|
|
redis bool = true
|
|
}
|
|
|
|
// Export all collections
|
|
pub fn (mut a Atlas) export(args ExportArgs) ! {
|
|
mut dest := pathlib.get_dir(path: args.destination, create: true)!
|
|
|
|
if args.reset {
|
|
dest.empty()!
|
|
}
|
|
|
|
// Validate links before export to populate page.links
|
|
a.validate_links()!
|
|
|
|
for _, mut col in a.collections {
|
|
col.export(
|
|
destination: dest
|
|
reset: args.reset
|
|
include: args.include
|
|
redis: args.redis
|
|
)!
|
|
}
|
|
}
|
|
|
|
@[params]
|
|
pub struct CollectionExportArgs {
|
|
pub mut:
|
|
destination pathlib.Path @[required]
|
|
reset bool = true
|
|
include bool = true // process includes during export
|
|
redis bool = true
|
|
}
|
|
|
|
// Export a single collection
|
|
// Export a single collection with recursive link processing
|
|
pub fn (mut c Collection) export(args CollectionExportArgs) ! {
|
|
// Create collection directory
|
|
mut col_dir := pathlib.get_dir(
|
|
path: '${args.destination.path}/content/${c.name}'
|
|
create: true
|
|
)!
|
|
mut dir_meta := pathlib.get_dir(
|
|
path: '${args.destination.path}/meta/'
|
|
create: true
|
|
)!
|
|
|
|
if c.has_errors() {
|
|
c.print_errors()
|
|
}
|
|
|
|
meta := json.encode_pretty(c)
|
|
mut json_file := pathlib.get_file(
|
|
path: '${dir_meta.path}/${c.name}.json'
|
|
create: true
|
|
)!
|
|
json_file.write(meta)!
|
|
|
|
// Track all cross-collection pages and files that need to be exported
|
|
// Use maps with collection:name as key to track globally across all resolutions
|
|
mut cross_collection_pages := map[string]&Page{} // key: "collection:page_name"
|
|
mut cross_collection_files := map[string]&File{} // key: "collection:file_name"
|
|
mut processed_local_pages := map[string]bool{} // Track which local pages we've already processed
|
|
mut processed_cross_pages := map[string]bool{} // Track which cross-collection pages we've processed for links
|
|
|
|
// First pass: export all pages in this collection and recursively collect ALL cross-collection references
|
|
for _, mut page in c.pages {
|
|
// Get content with includes processed and links transformed for export
|
|
content := page.content_with_fixed_links(
|
|
include: args.include
|
|
cross_collection: true
|
|
export_mode: true
|
|
)!
|
|
|
|
mut dest_file := pathlib.get_file(path: '${col_dir.path}/${page.name}.md', create: true)!
|
|
dest_file.write(content)!
|
|
|
|
// Recursively collect cross-collection references from this page
|
|
c.collect_cross_collection_references(mut page, mut cross_collection_pages, mut
|
|
cross_collection_files, mut processed_cross_pages)!
|
|
|
|
// println('------- ${c.name} ${page.key()}')
|
|
// if page.key() == 'geoaware:solution' && c.name == 'mycelium_nodes_tiers' {
|
|
// println(cross_collection_pages)
|
|
// println(cross_collection_files)
|
|
// // println(processed_cross_pages)
|
|
// $dbg;
|
|
// }
|
|
|
|
// copy the pages to the right exported path
|
|
for _, mut ref_page in cross_collection_pages {
|
|
mut src_file := ref_page.path()!
|
|
mut subdir_path := pathlib.get_dir(
|
|
path: '${col_dir.path}'
|
|
create: true
|
|
)!
|
|
mut dest_path := '${subdir_path.path}/${ref_page.name}.md'
|
|
src_file.copy(dest: dest_path)!
|
|
// println(dest_path)
|
|
// $dbg;
|
|
}
|
|
// copy the files to the right exported path
|
|
for _, mut ref_file in cross_collection_files {
|
|
mut src_file2 := ref_file.path()!
|
|
|
|
// Determine subdirectory based on file type
|
|
mut subdir := if ref_file.is_image() { 'img' } else { 'files' }
|
|
|
|
// Ensure subdirectory exists
|
|
mut subdir_path := pathlib.get_dir(
|
|
path: '${col_dir.path}/${subdir}'
|
|
create: true
|
|
)!
|
|
|
|
mut dest_path := '${subdir_path.path}/${ref_file.name}'
|
|
mut dest_file2 := pathlib.get_file(path: dest_path, create: true)!
|
|
src_file2.copy(dest: dest_file2.path)!
|
|
}
|
|
|
|
processed_local_pages[page.name] = true
|
|
|
|
// Redis operations...
|
|
if args.redis {
|
|
mut context := base.context()!
|
|
mut redis := context.redis()!
|
|
redis.hset('atlas:${c.name}', page.name, page.path)!
|
|
}
|
|
}
|
|
|
|
// Copy all files/images from this collection to the export directory
|
|
for _, mut file in c.files {
|
|
mut src_file := file.path()!
|
|
|
|
// Determine subdirectory based on file type
|
|
mut subdir := if file.is_image() { 'img' } else { 'files' }
|
|
|
|
// Ensure subdirectory exists
|
|
mut subdir_path := pathlib.get_dir(
|
|
path: '${col_dir.path}/${subdir}'
|
|
create: true
|
|
)!
|
|
|
|
mut dest_path := '${subdir_path.path}/${file.name}'
|
|
mut dest_file := pathlib.get_file(path: dest_path, create: true)!
|
|
src_file.copy(dest: dest_file.path)!
|
|
}
|
|
}
|
|
|
|
// Helper function to recursively collect cross-collection references
|
|
// This processes a page's links and adds all non-local references to the collections
|
|
fn (mut c Collection) collect_cross_collection_references(mut page Page,
|
|
mut all_cross_pages map[string]&Page,
|
|
mut all_cross_files map[string]&File,
|
|
mut processed_pages map[string]bool) ! {
|
|
page_key := page.key()
|
|
|
|
// If we've already processed this page, skip it (prevents infinite loops with cycles)
|
|
if page_key in processed_pages {
|
|
return
|
|
}
|
|
|
|
// Mark this page as processed BEFORE recursing (prevents infinite loops with circular references)
|
|
processed_pages[page_key] = true
|
|
|
|
// Process all links in the current page
|
|
// Use cached links from validation (before transformation) to preserve collection info
|
|
for mut link in page.links {
|
|
if link.status != .found {
|
|
continue
|
|
}
|
|
|
|
is_local := link.target_collection_name == c.name
|
|
|
|
// Collect cross-collection page references and recursively process them
|
|
if link.file_type == .page && !is_local {
|
|
page_ref := '${link.target_collection_name}:${link.target_item_name}'
|
|
|
|
// Only add if not already collected
|
|
if page_ref !in all_cross_pages {
|
|
mut target_page := link.target_page()!
|
|
all_cross_pages[page_ref] = target_page
|
|
|
|
// Recursively process the target page's links to find more cross-collection references
|
|
// This ensures we collect ALL transitive cross-collection page and file references
|
|
c.collect_cross_collection_references(mut target_page, mut all_cross_pages, mut
|
|
all_cross_files, mut processed_pages)!
|
|
}
|
|
}
|
|
|
|
// Collect cross-collection file/image references
|
|
if (link.file_type == .file || link.file_type == .image) && !is_local {
|
|
file_key := '${link.target_collection_name}:${link.target_item_name}'
|
|
|
|
// Only add if not already collected
|
|
if file_key !in all_cross_files {
|
|
mut target_file := link.target_file()!
|
|
all_cross_files[file_key] = target_file
|
|
}
|
|
}
|
|
}
|
|
}
|