- Add sophisticated file preservation functionality to _clean_output_dir() - Support .qsgen3_preserve file with shell glob patterns for selective preservation - Preserve shared articles and important files during site regeneration - Maintain backward compatibility (no preserve file = complete cleaning) - Add comprehensive documentation in how-it-works.md - Include example preserve file (.qsgen3_preserve.example) - Remove legacy images directory and update documentation - Fix workflow documentation formatting issues
30 KiB
How qsgen3 Works
Table of Contents
- Philosophy and Design Principles
- Project Structure
- Configuration System
- Theme System
- Creating New Themes
- Content Processing Pipeline
- Static File Handling
- Template System
- Output Generation
- Command Line Interface
- Dependencies and Requirements
- Detailed Workflow
- Troubleshooting and Debugging
Philosophy and Design Principles
Core Philosophy
qsgen3 is designed to be 100% design-agnostic. It does not impose any specific CSS frameworks, JavaScript libraries, or HTML structures on users. The generator's role is strictly to:
- Process Markdown content into HTML
- Combine content with user-chosen templates and styling
- Generate a complete static site structure
Key Principles
- Minimal Dependencies: Only requires Pandoc for content processing
- In-Memory Operations: All content manipulation occurs in memory to improve performance and reduce storage wear
- Flexible Theme System: Supports easy switching between themes via configuration
- Template Agnostic: Works with any Pandoc-compatible HTML templates
- No Forced Assets: Only automatically links the main theme CSS; all other asset inclusion is explicit
Project Structure
A typical qsgen3 project follows this structure:
project-root/
├── bin/
│ └── qsgen3 # Main generator script
├── site.conf # Main configuration file
├── .qsgen3_preserve # Optional: File preservation patterns
├── content/ # Markdown content
│ ├── posts/ # Blog posts
│ │ └── hello-world.md
│ └── pages/ # Static pages
├── layouts/ # Pandoc HTML templates
│ ├── index.html # Homepage template
│ ├── post.html # Blog post template
│ └── rss.xml # RSS feed template
├── static/ # Static assets (CSS, images, etc.)
│ ├── css/
│ └── images/
├── themes/ # Theme directory
│ └── theme-name/ # Individual theme
│ ├── layouts/ # Theme-specific templates (optional)
│ └── css/ # Alternative theme asset location
└── output/ # Generated site (created by qsgen3)
├── index.html
├── rss.xml
├── posts/
└── static/
Configuration System
Primary Configuration: site.conf
The site.conf
file uses a simple key-value format:
# Site Metadata
site_name="My Awesome Site"
site_tagline="A brief description of my site"
site_url="http://localhost:8000"
# Theme Configuration
site_theme="minimal"
site_theme_css_file="css/style.css"
# Directory Paths
paths_content_dir="content"
paths_output_dir="output"
paths_layouts_dir="layouts"
paths_static_dir="static"
# Build Options
build_options_generate_rss=true
build_options_generate_sitemap=true
build_options_process_drafts=false
Configuration Loading Process
- File Location: Defaults to
$PROJECT_ROOT/site.conf
- Override: Can be specified with
-c <file>
or--config <file>
- Parsing: Simple line-by-line parsing of
key="value"
pairs - Storage: Values stored in
QSG_CONFIG
associative array - Validation: Basic validation for required keys and file existence
Key Configuration Variables
site_theme
: Name of the active theme (directory name inthemes/
)site_theme_css_file
: Path to main CSS file relative to theme's static assetssite_url
: Base URL for the site (used in RSS and absolute links)paths_*
: Directory paths (can be relative or absolute)build_options_*
: Boolean flags for optional features
Theme System
Theme Architecture
Themes in qsgen3 provide two main components:
- Templates: Pandoc HTML templates for different page types
- Static Assets: CSS, JavaScript, images, and other resources
Theme Directory Structure
themes/theme-name/
├── layouts/ # Optional: Override default templates
│ ├── index.html # Homepage template
│ ├── post.html # Post template
│ └── rss.xml # RSS template
├── static/ # Preferred: Standard static assets location
│ ├── css/
│ └── js/
└── css/ # Alternative: Direct CSS location
└── style.css
Theme Resolution Logic
- Theme Selection: Based on
site_theme
insite.conf
- Layout Override: If
themes/theme-name/layouts/
exists, it overridespaths_layouts_dir
- Static Asset Source:
- First checks for
themes/theme-name/static/
- Falls back to
themes/theme-name/
(for themes with assets at root level)
- First checks for
- CSS File Location: Determined by
site_theme_css_file
relative to theme's static source
Theme Switching
Switching themes is accomplished by:
- Changing
site_theme
insite.conf
- Updating
site_theme_css_file
to match the new theme's CSS structure - Running qsgen3 to regenerate the site
Creating New Themes
Theme Development Overview
Creating a new theme for qsgen3 involves designing templates and static assets that work together to provide a cohesive visual and functional experience. Themes can range from minimal CSS-only styling to complex designs with custom layouts and interactive elements.
Step-by-Step Theme Creation
1. Create Theme Directory Structure
Start by creating a new directory in the themes/
folder:
mkdir -p themes/my-theme
cd themes/my-theme
Choose one of these organizational approaches:
Option A: Standard Structure (Recommended)
themes/my-theme/
├── layouts/ # Custom templates (optional)
│ ├── index.html # Homepage template
│ ├── post.html # Blog post template
│ └── rss.xml # RSS feed template
└── static/ # Static assets
├── css/
│ └── style.css # Main stylesheet
└── js/ # JavaScript files (optional)
Option B: CSS-Only Structure
themes/my-theme/
└── css/
└── style.css # Main stylesheet only
2. Create the Main Stylesheet
Create your theme's primary CSS file. This is the only asset that qsgen3 will automatically link:
/* themes/my-theme/static/css/style.css */
/* Reset and base styles */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
line-height: 1.6;
color: #333;
background-color: #fff;
}
/* Header styles */
header {
background: #2c3e50;
color: white;
padding: 1rem 0;
margin-bottom: 2rem;
}
header h1 {
max-width: 800px;
margin: 0 auto;
padding: 0 1rem;
}
/* Main content */
main {
max-width: 800px;
margin: 0 auto;
padding: 0 1rem;
}
/* Post styles */
article {
margin-bottom: 3rem;
padding-bottom: 2rem;
border-bottom: 1px solid #eee;
}
article h1, article h2 {
color: #2c3e50;
margin-bottom: 0.5rem;
}
article .meta {
color: #666;
font-size: 0.9rem;
margin-bottom: 1rem;
}
/* Navigation and links */
nav ul {
list-style: none;
display: flex;
gap: 1rem;
}
nav a {
color: #3498db;
text-decoration: none;
}
nav a:hover {
text-decoration: underline;
}
/* Responsive design */
@media (max-width: 768px) {
main {
padding: 0 0.5rem;
}
nav ul {
flex-direction: column;
gap: 0.5rem;
}
}
3. Create Custom Templates (Optional)
If you want to override the default templates, create custom Pandoc templates:
Homepage Template (layouts/index.html
)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>$site_name$</title>
$if(css)$<link rel="stylesheet" href="$css$">$endif$
</head>
<body>
<header>
<h1>$site_name$</h1>
$if(site_tagline)$<p>$site_tagline$</p>$endif$
</header>
<main>
<section class="posts">
<h2>Recent Posts</h2>
$if(posts)$
<ul class="post-list">
$for(posts)$
<li class="post-item">
<h3><a href="$it.post_url$">$it.post_title$</a></h3>
<div class="meta">
$if(it.post_date)$<time>$it.post_date$</time>$endif$
$if(it.post_author)$ by $it.post_author$$endif$
</div>
$if(it.post_description)$<p>$it.post_description$</p>$endif$
</li>
$endfor$
</ul>
$else$
<p>No posts available.</p>
$endif$
</section>
</main>
<footer>
<p>© 2024 $site_name$. Generated with qsgen3.</p>
</footer>
</body>
</html>
Post Template (layouts/post.html
)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>$title$ - $site_name$</title>
$if(css)$<link rel="stylesheet" href="$css$">$endif$
$if(description)$<meta name="description" content="$description$">$endif$
</head>
<body>
<header>
<h1><a href="/">$site_name$</a></h1>
$if(site_tagline)$<p>$site_tagline$</p>$endif$
</header>
<main>
<article>
<header class="post-header">
<h1>$title$</h1>
<div class="meta">
$if(date)$<time datetime="$date$">$date$</time>$endif$
$if(author)$ by <span class="author">$author$</span>$endif$
</div>
</header>
<div class="post-content">
$body$
</div>
</article>
<nav class="post-nav">
<a href="/">← Back to Home</a>
</nav>
</main>
<footer>
<p>© 2024 $site_name$. Generated with qsgen3.</p>
</footer>
</body>
</html>
4. Add JavaScript (Optional)
If your theme requires JavaScript functionality, add it to the static assets:
// themes/my-theme/static/js/theme.js
document.addEventListener('DOMContentLoaded', function() {
// Add smooth scrolling
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
anchor.addEventListener('click', function (e) {
e.preventDefault();
const target = document.querySelector(this.getAttribute('href'));
if (target) {
target.scrollIntoView({
behavior: 'smooth'
});
}
});
});
// Add copy code button functionality
document.querySelectorAll('pre code').forEach(block => {
const button = document.createElement('button');
button.textContent = 'Copy';
button.className = 'copy-button';
button.addEventListener('click', () => {
navigator.clipboard.writeText(block.textContent);
button.textContent = 'Copied!';
setTimeout(() => button.textContent = 'Copy', 2000);
});
block.parentNode.appendChild(button);
});
});
Important: Remember that qsgen3 will not automatically include JavaScript files. You must add <script>
tags to your templates:
<!-- Add to your template's <head> or before </body> -->
<script src="/static/js/theme.js"></script>
5. Configure Theme Usage
Update your site.conf
to use the new theme:
# Theme Configuration
site_theme="my-theme"
site_theme_css_file="css/style.css" # Path relative to theme's static source
For CSS-only themes using the alternative structure:
site_theme="my-theme"
site_theme_css_file="style.css" # Direct path if CSS is at theme root
6. Test Your Theme
Generate your site to test the theme:
./bin/qsgen3
Check the output:
- Verify CSS is applied correctly
- Test responsive design on different screen sizes
- Validate HTML structure
- Check that all assets are copied correctly
Theme Development Best Practices
CSS Guidelines
- Use Relative Units: Prefer
rem
,em
, and percentages over fixed pixels - Mobile-First Design: Start with mobile styles, then add desktop enhancements
- Semantic Selectors: Use class names that describe content, not appearance
- CSS Custom Properties: Use CSS variables for consistent theming
:root {
--primary-color: #2c3e50;
--secondary-color: #3498db;
--text-color: #333;
--background-color: #fff;
--border-color: #eee;
--font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}
body {
color: var(--text-color);
background-color: var(--background-color);
font-family: var(--font-family);
}
Template Guidelines
- Conditional Content: Use Pandoc's conditional syntax for optional elements
- Semantic HTML: Use appropriate HTML5 semantic elements
- Accessibility: Include proper ARIA labels and alt text
- Meta Tags: Include essential meta tags for SEO and social sharing
<!-- Good conditional usage -->
$if(description)$<meta name="description" content="$description$">$endif$
$if(author)$<meta name="author" content="$author$">$endif$
<!-- Semantic structure -->
<main role="main">
<article>
<header>
<h1>$title$</h1>
</header>
<div class="content">
$body$
</div>
</article>
</main>
Asset Organization
- Logical Structure: Group related assets in appropriate directories
- Naming Conventions: Use consistent, descriptive file names
- Optimization: Optimize images and minimize CSS/JS when possible
- Dependencies: Document any external dependencies clearly
Advanced Theme Features
Dark Mode Support
Add CSS custom properties and media queries for dark mode:
:root {
--bg-color: #fff;
--text-color: #333;
--border-color: #eee;
}
@media (prefers-color-scheme: dark) {
:root {
--bg-color: #1a1a1a;
--text-color: #e0e0e0;
--border-color: #333;
}
}
body {
background-color: var(--bg-color);
color: var(--text-color);
transition: background-color 0.3s ease, color 0.3s ease;
}
Print Styles
Include print-specific styles:
@media print {
header, footer, nav {
display: none;
}
body {
font-size: 12pt;
line-height: 1.4;
}
a[href]:after {
content: " (" attr(href) ")";
}
}
Custom Fonts
If using custom fonts, include them properly:
/* Load fonts */
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap');
/* Or use local fonts */
@font-face {
font-family: 'CustomFont';
src: url('/static/fonts/custom-font.woff2') format('woff2'),
url('/static/fonts/custom-font.woff') format('woff');
font-display: swap;
}
Theme Distribution
Documentation
Create a README.md
for your theme:
# My Theme
A clean, minimal theme for qsgen3.
## Features
- Responsive design
- Dark mode support
- Clean typography
- Fast loading
## Installation
1. Copy theme to `themes/my-theme/`
2. Update `site.conf`:
site_theme="my-theme" site_theme_css_file="css/style.css"
3. Run `./bin/qsgen3`
## Customization
- Edit CSS custom properties in `style.css`
- Modify templates in `layouts/` directory
- Add custom JavaScript in `static/js/`
## Browser Support
- Modern browsers (Chrome 90+, Firefox 88+, Safari 14+)
- Graceful degradation for older browsers
Version Control
If sharing your theme:
- Use semantic versioning
- Tag releases appropriately
- Include a changelog
- Provide example configurations
Troubleshooting Theme Development
Common Issues
- CSS Not Loading: Check
site_theme_css_file
path matches actual file location - Templates Not Found: Ensure template files are in
layouts/
directory - Assets Missing: Verify static files are in correct directory structure
- JavaScript Errors: Remember to include
<script>
tags in templates
Testing Checklist
- CSS loads correctly on all page types
- Templates render without Pandoc errors
- Responsive design works on mobile devices
- All static assets are accessible
- JavaScript functionality works (if applicable)
- Print styles are appropriate
- Accessibility standards are met
- Performance is acceptable
Content Processing Pipeline
Markdown Processing
- Discovery: Recursively scans
paths_content_dir
for.md
files - Metadata Extraction: Parses YAML front matter for post metadata
- Content Conversion: Uses Pandoc to convert Markdown to HTML
- Template Application: Applies appropriate template based on content type
- Output Generation: Writes processed HTML to corresponding location in
output/
Content Types
- Posts: Files in
content/posts/
→output/posts/
- Pages: Files in
content/pages/
→output/
- Index: Generated from post metadata →
output/index.html
- RSS: Generated from post metadata →
output/rss.xml
Metadata Handling
Each Markdown file can include YAML front matter:
---
title: "Post Title"
date: "2023-01-01"
author: "Author Name"
description: "Post description"
draft: false
---
# Post Content
Your markdown content here...
Static File Handling
Copy Strategy
Static files are copied in a specific order to handle theme overrides:
- Root Static Files: Copy from
paths_static_dir
tooutput/static/
- Theme Static Files: Copy from theme's static source to
output/static/
- Override Behavior: Theme files overwrite root files with same names
Copy Implementation
- Primary Tool:
rsync
with-av --delete
flags - Fallback:
cp -R
if rsync is unavailable - Preservation: Maintains directory structure and file permissions
CSS File Linking
- Availability: Theme CSS files are copied to
output/static/
- Verification: Script checks for CSS file existence after copying
- Pandoc Integration: CSS path passed to Pandoc via
--css
flag - Path Format: Uses site-root-relative paths (e.g.,
/static/css/style.css
)
Template System
Template Types
qsgen3 uses Pandoc templates with specific purposes:
index.html
: Homepage template (receives post list metadata)post.html
: Individual post template (receives post content and metadata)rss.xml
: RSS feed template (receives post list for syndication)
Template Variables
Templates receive data through Pandoc's variable system:
Post Templates
$title$
: Post title from front matter$date$
: Post date$author$
: Post author$body$
: Converted HTML content- Custom variables from YAML front matter
Index Template
$site_name$
: From site.conf$site_tagline$
: From site.conf$posts$
: Array of post metadata for listing
RSS Template
$site_url$
: Base URL for absolute links$posts$
: Array of post data with URLs and content
Template Resolution
- Theme Override: If theme provides templates, use theme's
layouts/
- Default: Use project's
layouts/
directory - Fallback: Error if required template not found
Output Generation
Directory Structure
Generated output maintains a clean, predictable structure:
output/
├── index.html # Homepage
├── rss.xml # RSS feed
├── posts/ # Individual post pages
│ └── post-name.html
├── static/ # All static assets
│ ├── css/ # Stylesheets
│ └── js/ # JavaScript (if provided by theme)
└── css/ # Legacy: Index-specific CSS location
└── theme.css # Copy of main theme CSS for index page
File Naming
- Posts:
content/posts/hello-world.md
→output/posts/hello-world.html
- Pages:
content/pages/about.md
→output/about.html
- Index: Generated →
output/index.html
- RSS: Generated →
output/rss.xml
URL Structure
- Posts:
/posts/post-name.html
- Pages:
/page-name.html
- Static Assets:
/static/path/to/asset
- CSS:
/static/css/style.css
(for posts),/css/theme.css
(for index)
Command Line Interface
Basic Usage
./bin/qsgen3 [options]
Available Options
-h, --help
: Display usage information and exit-V, --version
: Show script name and version, then exit-c <file>, --config <file>
: Specify custom configuration file path
Path Resolution
PROJECT_ROOT
: Defaults to current working directory ($PWD
)CONFIG_FILE
: Defaults to$PROJECT_ROOT/site.conf
- Relative Paths: Configuration file path can be relative to project root
Exit Codes
- 0: Successful generation
- 1: Error (missing dependencies, configuration issues, processing failures)
Dependencies and Requirements
Required Dependencies
- Pandoc: Core dependency for Markdown processing and HTML generation
- Zsh: Shell interpreter (script written in Zsh)
Optional Dependencies
- rsync: Preferred tool for efficient file copying (falls back to
cp
)
System Requirements
- Operating System: Linux/Unix-like systems
- File System: Support for standard Unix file permissions
- Memory: Minimal requirements (all processing in memory)
Environment Setup
The script configures a consistent environment:
LC_ALL=C
LANG=C
umask 0022
Detailed Workflow
1. Initialization Phase
Start qsgen3
├── Parse command line arguments
├── Set PROJECT_ROOT (default: $PWD)
├── Determine CONFIG_FILE path
├── Set environment variables (LC_ALL, LANG, umask)
└── Initialize QSG_CONFIG array
2. Configuration Loading
Load Configuration
├── Check if CONFIG_FILE exists
├── Parse key="value" pairs line by line
├── Strip quotes from values
├── Store in QSG_CONFIG associative array
└── Validate required configuration keys
3. Dependency Checking
Check Dependencies
├── Verify Pandoc is available
├── Check Pandoc version compatibility
├── Verify other required tools
└── Exit with error if dependencies missing
4. Theme Processing
Process Theme Configuration
├── Read site_theme from configuration
├── Determine theme base path: themes/$site_theme
├── Check for theme layouts directory
│ ├── If exists: Override paths_layouts_dir
│ └── If not: Use default layouts
├── Determine theme static source
│ ├── Check themes/$site_theme/static/
│ ├── Fallback to themes/$site_theme/
│ └── Set QSG_CONFIG[theme_static_source_dir]
└── Log theme processing decisions
5. Output Preparation
Prepare Output Directory
├── Check for .qsgen3_preserve file in project root
├── If preserve file exists:
│ ├── Read file patterns (shell glob patterns)
│ ├── Create temporary backup directory
│ ├── Find and backup matching files from output directory
│ ├── Remove entire output directory
│ ├── Recreate clean output directory
│ ├── Restore preserved files maintaining directory structure
│ └── Clean up temporary backup directory
│ └── Remove entire output directory
│ └── Create fresh output directory
└── Log preservation and cleaning operations
File Preservation System
qsgen3 supports preserving specific files during the cleaning process to handle cases where content has been shared or bookmarked and should remain accessible even after title changes.
Preserve File Format (.qsgen3_preserve
):
- Located in project root directory
- One pattern per line using shell glob patterns (
*
,?
,[]
) - Lines starting with
#
are comments - Empty lines are ignored
- Patterns are relative to the output directory
Example preserve patterns:
# Preserve specific shared articles
posts/my-important-shared-article.html
posts/viral-blog-post.html
# Preserve files by pattern
posts/legacy-*.html
archive/*
# Preserve all PDFs and downloads
*.pdf
downloads/*
Benefits:
- Maintains stable URLs for shared content
- Prevents broken links when content is renamed
- Flexible pattern matching for various preservation needs
- Backward compatible (no preserve file = complete cleaning)
6. Static File Processing
Copy Static Files
├── Copy from paths_static_dir to output/static/
│ ├── Use rsync -av --delete if available
│ └── Fallback to cp -R
├── Copy from theme static source to output/static/
│ ├── Theme files overwrite root files
│ └── Preserve directory structure
└── Log copy operations and results
7. CSS Path Determination
Determine CSS Linking
├── Read site_theme_css_file from configuration
├── Construct expected CSS file path in output/static/
├── Verify CSS file exists after copying
├── Set QSG_CONFIG[pandoc_css_path_arg] for Pandoc
└── Log CSS path decisions and warnings
8. Content Processing
Process Markdown Content
├── Scan paths_content_dir recursively for .md files
├── For each Markdown file:
│ ├── Extract YAML front matter
│ ├── Determine output path and template
│ ├── Run Pandoc with appropriate template and CSS
│ ├── Write generated HTML to output directory
│ └── Log processing results
└── Collect metadata for index and RSS generation
9. Index Generation
Generate Index Page
├── Collect all post metadata
├── Create YAML metadata file for Pandoc
├── Run Pandoc with index template
├── Apply CSS styling
├── Write output/index.html
└── Clean up temporary files
10. RSS Generation
Generate RSS Feed
├── Collect post metadata with URLs
├── Create YAML metadata for RSS template
├── Run Pandoc with RSS template
├── Generate absolute URLs using site_url
├── Write output/rss.xml
└── Clean up temporary files
11. Finalization
Complete Generation
├── Log final directory structure
├── Report generation success
├── Clean up any remaining temporary files
└── Exit with status code 0
Troubleshooting and Debugging
Common Issues
1. CSS Not Applied
Symptoms: Generated HTML doesn't show theme styling Causes:
- Incorrect
site_theme_css_file
path in site.conf - CSS file doesn't exist in theme's static assets
- Theme static directory structure mismatch
Solutions:
- Verify CSS file path relative to theme's static source
- Check theme directory structure
- Enable debug logging to trace CSS path resolution
2. Theme Not Found
Symptoms: Warning about theme directory not found Causes:
- Typo in
site_theme
configuration - Theme directory doesn't exist
- Incorrect theme directory structure
Solutions:
- Verify theme name spelling in site.conf
- Check themes/ directory exists and contains named theme
- Ensure theme directory has expected structure
3. Template Errors
Symptoms: Pandoc errors during HTML generation Causes:
- Missing required templates
- Template syntax errors
- Incompatible template variables
Solutions:
- Verify all required templates exist
- Check Pandoc template syntax
- Review template variable usage
4. Static File Copy Issues
Symptoms: Assets missing from output directory Causes:
- Permission issues
- Disk space problems
- Path resolution errors
Solutions:
- Check file permissions
- Verify available disk space
- Review path configurations for absolute vs. relative paths
5. File Preservation Issues
Symptoms: Expected files not preserved during cleaning, or preservation not working Causes:
- Incorrect patterns in
.qsgen3_preserve
file - File paths don't match patterns
- Permission issues with temporary backup directory
- Malformed preserve file format
Solutions:
- Verify patterns use shell glob syntax (
*
,?
,[]
) - Check that patterns are relative to output directory
- Ensure
.qsgen3_preserve
file is in project root - Test patterns with
find output/ -name "pattern"
before adding to preserve file - Enable debug logging to see preservation process details
- Verify file permissions allow temporary directory creation
Example debugging:
# Test if your pattern matches files
find output/ -name "posts/legacy-*.html"
# Enable debug logging to see preservation process
QSG_DEBUG=1 ./bin/qsgen3
Debug Logging
Enable detailed logging by modifying the _log
function or adding debug statements:
# Enable debug logging
QSG_DEBUG=1 ./bin/qsgen3
Path Debugging
The script includes path resolution logic to handle both relative and absolute paths. If experiencing path issues:
- Check that
PROJECT_ROOT
is correctly set - Verify configuration paths are relative to project root
- Review log messages for path construction details
Configuration Validation
Ensure site.conf follows the correct format:
- Use double quotes for values:
key="value"
- No spaces around the equals sign
- One configuration per line
- Comments start with
#
This document reflects the current implementation of qsgen3 and its design philosophy of remaining completely design-agnostic while providing flexible theme and content management capabilities.