feat: Implement robust theme system and document architecture

- Implement flexible theme switching via site.conf (site_theme, site_theme_css_file).
- Ensure correct copying of theme static assets, with theme assets overriding root assets.
- Resolve CSS linking issues by checking file existence after static copy and using correct paths for Pandoc.
- Refactor path construction to prevent duplication when using absolute/relative output paths.
- Create comprehensive how-it-works.md detailing system architecture, theme creation, and overall workflow.
- Clarify design philosophy: qsgen3 remains design-agnostic, only linking main theme CSS automatically.
This commit is contained in:
2025-05-31 00:00:21 +02:00
parent c14e943f2b
commit c470ac40c0
34 changed files with 5058 additions and 82 deletions

110
layouts/css/default.css Normal file
View File

@ -0,0 +1,110 @@
/* Default Theme for qsgen3 */
body {
font-family: sans-serif;
line-height: 1.6;
margin: 20px auto;
padding: 0 20px;
max-width: 800px;
background-color: #fdfdfd;
color: #333;
}
header {
background-color: #eee;
padding: 1em 0;
margin-bottom: 2em;
text-align: center;
}
header h1 a {
color: #333;
text-decoration: none;
}
header .tagline {
color: #555;
font-size: 0.9em;
}
nav ul {
list-style-type: none;
padding: 0;
text-align: center;
}
nav ul li {
display: inline;
margin-right: 15px;
}
nav ul li a {
text-decoration: none;
color: #007bff;
}
nav ul li a:hover {
text-decoration: underline;
}
article header {
background-color: transparent;
padding: 0;
margin-bottom: 1em;
text-align: left;
}
h1, h2, h3, h4, h5, h6 {
color: #333;
margin-top: 1.5em;
margin-bottom: 0.5em;
}
a {
color: #007bff;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
img {
max-width: 100%;
height: auto;
}
pre {
background-color: #f0f0f0;
padding: 15px;
overflow-x: auto;
border-radius: 4px;
}
code {
font-family: monospace;
background-color: #f0f0f0;
padding: 0.2em 0.4em;
border-radius: 3px;
}
pre code {
padding: 0;
background-color: transparent;
}
blockquote {
border-left: 4px solid #ccc;
padding-left: 15px;
margin-left: 0;
font-style: italic;
color: #555;
}
footer {
text-align: center;
margin-top: 3em;
padding-top: 1em;
border-top: 1px solid #eee;
font-size: 0.9em;
color: #777;
}

47
layouts/index.html Normal file
View File

@ -0,0 +1,47 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>$site_name$ - $site_tagline$</title>
$for(css)$
<link rel="stylesheet" href="$css$">
$endfor$
$if(site_rss_url)$
<link rel="alternate" type="application/rss+xml" title="RSS Feed" href="$site_rss_url$">
$endif$
</head>
<body>
<header>
<h1><a href="$site_url$">$site_name$</a></h1>
<p>$site_tagline$</p>
</header>
<main>
<section id="posts-list">
<h2>Latest Posts</h2>
$if(posts)$
<ul>
$for(posts)$
<li>
<h3><a href="$posts.url$">$posts.title$</a></h3>
$if(posts.date)$
<p class="date">$posts.date$</p>
$endif$
$if(posts.summary)$
<p>$posts.summary$</p>
$endif$
</li>
$endfor$
</ul>
$else$
<p>No posts found.</p>
$endif$
</section>
</main>
<footer>
<p>&copy; $current_year$ $site_name$. Generated by qsgen3.</p>
</footer>
</body>
</html>

32
layouts/page.html Normal file
View File

@ -0,0 +1,32 @@
<!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$</title>
<meta name="description" content="$description$"> <!-- Add description to frontmatter -->
<link rel="stylesheet" href="/static/css/style.css"> <!-- Assuming site served from root -->
$for(css)$
<link rel="stylesheet" href="$css$">
$endfor$
$if(math)$ $math$ $endif$
</head>
<body>
<header>
<h1><a href="/">$site_name$</a></h1>
<p>$site_tagline$</p>
</header>
<main>
<article>
<header>
<h1>$title$</h1>
</header>
$body$
</article>
</main>
<footer>
<p>&copy; $current_year$ $site_name$. Generated by qsgen3.</p>
<p><a href="$site_url$">$site_url$</a></p>
</footer>
</body>
</html>

39
layouts/post.html Normal file
View File

@ -0,0 +1,39 @@
<!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$</title>
<meta name="author" content="$author$">
<meta name="description" content="$description$"> <!-- Add description to frontmatter -->
$if(date)$<meta name="date" content="$date$">$endif$
$for(css)$
<link rel="stylesheet" href="$css$">
$endfor$
$if(math)$ $math$ $endif$
</head>
<body>
<header>
<h1><a href="/">$site_name$</a></h1>
<p>$site_tagline$</p>
</header>
<main>
<article>
<header>
<h1>$title$</h1>
$if(author)$
<p class="author">By: $author$</p>
$endif$
$if(date)$
<p class="date">Published: $date$</p>
$endif$
</header>
$body$
</article>
</main>
<footer>
<p>&copy; $current_year$ $site_name$. Generated by qsgen3. </p>
<p><a href="$site_url$">$site_url$</a></p>
</footer>
</body>
</html>

24
layouts/rss.xml Normal file
View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>$site_name$</title>
<link>$site_url$</link>
<description>$site_tagline$</description>
<language>en-us</language>
<lastBuildDate>$rfc_2822_date$</lastBuildDate>
<atom:link href="$site_url$/rss.xml" rel="self" type="application/rss+xml" />
$if(posts)$
$for(posts)$
<item>
<title>$it.post_title$</title>
<link>$it.post_url$</link>
<pubDate>$it.post_rfc_2822_date$</pubDate>
<guid isPermaLink="true">$it.post_url$</guid>
<description><![CDATA[$it.post_summary$]]></description>
</item>
$endfor$
$endif$
</channel>
</rss>