mirror of
https://github.com/kbenestad/mdcms.git
synced 2026-06-18 15:24:32 +00:00
Merge development: update reference-theme.md with all new theme.yml keys
https://claude.ai/code/session_01NQKywehSj8Ku4yKhwB4VNB
This commit is contained in:
commit
bcb451a9ee
4 changed files with 956 additions and 0 deletions
241
docs/reference-config.md
Normal file
241
docs/reference-config.md
Normal file
|
|
@ -0,0 +1,241 @@
|
||||||
|
# config.yml reference
|
||||||
|
|
||||||
|
`config.yml` is the site configuration file. Only `sitename` and `navigation` are required — everything else is optional. `mdcms build` reads this file; so does `index.html` at runtime.
|
||||||
|
|
||||||
|
The first line must not be changed:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# mdcms v0.4 | DO NOT REMOVE THIS COMMENT
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Required
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
sitename: My Site # Displayed in the browser tab, nav header, and meta tags.
|
||||||
|
navigation: sidebar # Layout mode. sidebar or topbar. NOTE: topbar is currently broken — always use sidebar.
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Presentation
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
theme: theme.yml # Path to theme file (relative to site root). Controls colours, fonts, layout.
|
||||||
|
# Omit to use built-in defaults.
|
||||||
|
|
||||||
|
logo: logo.png # Filename in assets/images/. Shown in the nav header above the site name.
|
||||||
|
favicon: favicon.png # Filename in assets/images/. Shown in the browser tab.
|
||||||
|
# Falls back to logo if not set. Required for PWA install icons.
|
||||||
|
|
||||||
|
sitedescription: A short description # Shown below the site name in the sidebar.
|
||||||
|
# Also used as the default meta description tag.
|
||||||
|
|
||||||
|
footer: "© 2026 Your Name" # Shown at the bottom of the nav. Supports inline markdown (bold, links, etc.).
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Navigation
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
homepage: pages/home.md # Override the default landing page. Path relative to site root.
|
||||||
|
# Default: pages/home.md
|
||||||
|
|
||||||
|
nav-position: left # Sidebar position. left or right. Default: left.
|
||||||
|
# Only applies when navigation: sidebar.
|
||||||
|
|
||||||
|
search: true # Show the search box. Set to false to hide it.
|
||||||
|
# Default: true (search is on unless explicitly disabled).
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Theme mode
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
default-theme: system # Starting colour mode. light, dark, or system.
|
||||||
|
# system follows the user's OS preference.
|
||||||
|
# Default: system.
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Layout overrides
|
||||||
|
|
||||||
|
These can also be set in theme.yml. Values here apply on top of theme.yml.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
main-width: 80em # Maximum width of the content column. Any CSS length unit.
|
||||||
|
nav-width: 20em # Width of the sidebar. Any CSS length unit.
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Typography overrides
|
||||||
|
|
||||||
|
These can also be set in theme.yml. Values here apply on top of theme.yml.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
font-body: "bunny:Noto Sans:400" # Body font. Format: "provider:Font Name:weight"
|
||||||
|
font-title: "bunny:Noto Sans:700" # Heading font.
|
||||||
|
font-code: "bunny:Fira Code:400" # Code font.
|
||||||
|
```
|
||||||
|
|
||||||
|
Provider options: `bunny` (GDPR-safe) or `google`. Omitting the provider defaults to Google Fonts.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Localisation
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
language: en # BCP 47 language code. Used for date formatting fallback.
|
||||||
|
|
||||||
|
date: system # Date format for post dates. system uses the browser locale.
|
||||||
|
# Or provide a format string, e.g. DD.MM.YYYY
|
||||||
|
|
||||||
|
time: system # Time format. system uses the browser locale.
|
||||||
|
|
||||||
|
monthnames: January, February, March, April, May, June, July, August, September, October, November, December
|
||||||
|
# Override month names (comma-separated, 12 values).
|
||||||
|
|
||||||
|
monthnamesabbreviated: Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec
|
||||||
|
# Override abbreviated month names (comma-separated, 12 values).
|
||||||
|
|
||||||
|
pagenotfoundmessage: "Page not found." # Message shown when a page cannot be loaded.
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## PWA (Progressive Web App)
|
||||||
|
|
||||||
|
`mdcms build` generates `manifest.json` and `service-worker.js` when `pwa: yes`.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
pwa: yes # Enable PWA. Generates manifest.json and service-worker.js on build.
|
||||||
|
|
||||||
|
pwa-name: "My Site" # Full app name shown on the install prompt and splash screen.
|
||||||
|
# Required when pwa: yes.
|
||||||
|
|
||||||
|
pwa-shortname: "MySite" # Short name for home screen icon labels (keep under ~12 chars).
|
||||||
|
# Falls back to pwa-name if omitted.
|
||||||
|
|
||||||
|
pwa-colour: "#2563EB" # Browser chrome colour (address bar on Android Chrome).
|
||||||
|
|
||||||
|
offline-message: "You are offline. Connect and reload."
|
||||||
|
# Shown when a page cannot be fetched and no cached version exists.
|
||||||
|
# Supports per-language values (see below).
|
||||||
|
```
|
||||||
|
|
||||||
|
Multi-language offline message:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
offline-message:
|
||||||
|
en: "You are offline. Connect and reload."
|
||||||
|
nb: "Du er frakoblet. Koble til og last inn på nytt."
|
||||||
|
```
|
||||||
|
|
||||||
|
The renderer picks the entry matching the active category's language, then falls back to `en`, then the first entry.
|
||||||
|
|
||||||
|
Requires a `favicon.png` (192×192 px recommended) at `assets/images/favicon.png` for the PWA install icon.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Categories
|
||||||
|
|
||||||
|
Categories allow one site to serve multiple language or audience variants of the same content. Each page can have a variant per category using the filename suffix convention (`page.nb.md` for Norwegian).
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
categories-use: yes # Enable the category system. Default: no.
|
||||||
|
|
||||||
|
default-category: # The category used when no ?cat= parameter is in the URL.
|
||||||
|
code: en # Short code. Used in filenames (page.en.md) and URL params.
|
||||||
|
name: English # Display name shown in the category selector.
|
||||||
|
direction: ltr # Text direction. ltr or rtl. Default: ltr.
|
||||||
|
|
||||||
|
categories: # Additional categories.
|
||||||
|
- code: nb
|
||||||
|
name: Norsk
|
||||||
|
direction: ltr
|
||||||
|
- code: ar
|
||||||
|
name: عربي
|
||||||
|
direction: rtl # RTL flips nav position and content text direction.
|
||||||
|
|
||||||
|
categories-sectionnames: same # How section names are shown per category.
|
||||||
|
# same: all categories share one section name (defaultname in nav.yml).
|
||||||
|
# per-category: each section has a name per category (categorynames in nav.yml).
|
||||||
|
|
||||||
|
categories-selecticon: globe # Icon shown in the category selector bar. SVG name from assets/icons/.
|
||||||
|
categories-selecttext: "Language" # Label shown next to the icon in the category selector bar.
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Reusable callout messages
|
||||||
|
|
||||||
|
Define named messages in config.yml and reference them in markdown with `message: <key>`. Useful for standard notices (e.g. AI translation warnings) used across many pages.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
callouts:
|
||||||
|
aitranslation: # Key name — used as message: aitranslation in markdown.
|
||||||
|
type: warning # Callout type: info, warning, success, error.
|
||||||
|
en:
|
||||||
|
title: "PLEASE NOTE:"
|
||||||
|
text: This page has been translated with artificial intelligence.
|
||||||
|
nb:
|
||||||
|
title: "VENNLIGST MERK:"
|
||||||
|
text: Denne siden er maskinoversatt.
|
||||||
|
```
|
||||||
|
|
||||||
|
Usage in a markdown page:
|
||||||
|
|
||||||
|
````markdown
|
||||||
|
```mdcms
|
||||||
|
callout-warning
|
||||||
|
message: aitranslation
|
||||||
|
```
|
||||||
|
````
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Full example
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# mdcms v0.4 | DO NOT REMOVE THIS COMMENT
|
||||||
|
# MD-CMS v0.4 — Site configuration
|
||||||
|
|
||||||
|
sitename: My Documentation
|
||||||
|
navigation: sidebar
|
||||||
|
theme: theme.yml
|
||||||
|
|
||||||
|
logo: logo.png
|
||||||
|
favicon: favicon.png
|
||||||
|
sitedescription: Reference documentation for My Project
|
||||||
|
footer: "© 2026 My Name — [Apache 2.0](https://www.apache.org/licenses/LICENSE-2.0)"
|
||||||
|
|
||||||
|
homepage: pages/home.md
|
||||||
|
nav-position: left
|
||||||
|
search: true
|
||||||
|
default-theme: system
|
||||||
|
|
||||||
|
pwa: yes
|
||||||
|
pwa-name: "My Documentation"
|
||||||
|
pwa-shortname: "MyDocs"
|
||||||
|
pwa-colour: "#2563EB"
|
||||||
|
offline-message:
|
||||||
|
en: "You are offline. Connect to the internet and reload."
|
||||||
|
nb: "Du er frakoblet. Koble til og last inn på nytt."
|
||||||
|
|
||||||
|
language: en
|
||||||
|
|
||||||
|
callouts:
|
||||||
|
aitranslation:
|
||||||
|
type: warning
|
||||||
|
en:
|
||||||
|
title: "PLEASE NOTE:"
|
||||||
|
text: This page has been translated with artificial intelligence. It has not been reviewed by staff.
|
||||||
|
nb:
|
||||||
|
title: "VENNLIGST MERK:"
|
||||||
|
text: Denne siden er maskinoversatt og ikke gjennomgått av redaksjonen.
|
||||||
|
```
|
||||||
185
docs/reference-nav.md
Normal file
185
docs/reference-nav.md
Normal file
|
|
@ -0,0 +1,185 @@
|
||||||
|
# nav.yml reference
|
||||||
|
|
||||||
|
`nav.yml` is generated by `mdcms build`. Do not write it from scratch — run the build command and edit the result.
|
||||||
|
|
||||||
|
```
|
||||||
|
python3 mdcms.py build --path app/
|
||||||
|
```
|
||||||
|
|
||||||
|
**What is preserved on rebuild:** All manual edits to section metadata fields (`defaultname`, `sort`, `parent`, `parent-sort`, `pagesvisibility`, `categorynames`) survive a rebuild. Page entries are re-generated from frontmatter each time.
|
||||||
|
|
||||||
|
**What is overwritten on rebuild:** Page `title`, `sort`, `section-id` — these are always taken from frontmatter.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Top-level structure
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
sections:
|
||||||
|
- code: my-section
|
||||||
|
defaultname: My Section
|
||||||
|
sort: 100
|
||||||
|
pagesvisibility: visible
|
||||||
|
|
||||||
|
pages:
|
||||||
|
- file: pages/my-page.md
|
||||||
|
title: My Page
|
||||||
|
section-id: my-section
|
||||||
|
sort: 100
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## sections
|
||||||
|
|
||||||
|
Each section groups a set of pages under a heading in the nav. Sections are auto-created from `section-id` values found in page frontmatter.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
sections:
|
||||||
|
- code: guides # Internal identifier. Set via section-id in page frontmatter.
|
||||||
|
# Letters, numbers, hyphens, underscores. Not shown to users.
|
||||||
|
|
||||||
|
defaultname: Guides # Display name shown in the nav.
|
||||||
|
# Auto-generated from code on first build; edit freely after.
|
||||||
|
|
||||||
|
sort: 100 # Controls section ordering in the nav (lower = higher).
|
||||||
|
# Sections without a sort value sort to the bottom.
|
||||||
|
|
||||||
|
pagesvisibility: visible # Controls page visibility for this section.
|
||||||
|
# visible — pages appear in nav and search (default).
|
||||||
|
# hidden — pages are hidden from nav but included in search.
|
||||||
|
# draft — pages hidden from nav AND excluded from search.
|
||||||
|
|
||||||
|
parent: getting-started # Optional. Makes this section a child of another section.
|
||||||
|
# Value is the code of the parent section.
|
||||||
|
|
||||||
|
parent-sort: 50 # Sort position of this section within its parent.
|
||||||
|
# Required when parent is set.
|
||||||
|
|
||||||
|
categorynames: # Per-category section display names.
|
||||||
|
# Required when categories-sectionnames: per-category in config.yml.
|
||||||
|
en: Guides
|
||||||
|
nb: Veiledninger
|
||||||
|
ar: أدلة
|
||||||
|
```
|
||||||
|
|
||||||
|
### Section example — nested
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
sections:
|
||||||
|
- code: getting-started
|
||||||
|
defaultname: Getting Started
|
||||||
|
sort: 100
|
||||||
|
pagesvisibility: visible
|
||||||
|
|
||||||
|
- code: installation
|
||||||
|
defaultname: Installation
|
||||||
|
sort: 100
|
||||||
|
pagesvisibility: visible
|
||||||
|
parent: getting-started
|
||||||
|
parent-sort: 10
|
||||||
|
|
||||||
|
- code: configuration
|
||||||
|
defaultname: Configuration
|
||||||
|
sort: 200
|
||||||
|
pagesvisibility: visible
|
||||||
|
parent: getting-started
|
||||||
|
parent-sort: 20
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## pages
|
||||||
|
|
||||||
|
Page entries are generated from markdown frontmatter. The fields below are written by the build and read by the renderer.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
pages:
|
||||||
|
- file: pages/home.md # Path relative to site root. Written by build — do not change.
|
||||||
|
|
||||||
|
title: Home # Page title. Taken from frontmatter title: on each build.
|
||||||
|
|
||||||
|
section-id: guides # Assigns the page to a section. Taken from frontmatter.
|
||||||
|
# Omit to leave the page unsectioned (appears above all sections in nav).
|
||||||
|
|
||||||
|
sort: 100 # Nav ordering within its section (lower = higher).
|
||||||
|
# Taken from frontmatter sort: on each build.
|
||||||
|
```
|
||||||
|
|
||||||
|
**Note:** Pages are sorted within their section by `sort`, then alphabetically by filename as a tiebreaker. Draft pages (frontmatter `draft: true`) are excluded entirely from `nav.yml` and `search.json`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## How sections and pages connect
|
||||||
|
|
||||||
|
1. Add `section-id: my-section` to a page's frontmatter.
|
||||||
|
2. Run `mdcms build` — the section is auto-created in `nav.yml` with `defaultname` derived from the code.
|
||||||
|
3. Edit `defaultname`, `sort`, `pagesvisibility` in `nav.yml` as needed. These edits are preserved on future rebuilds.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Full example
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# nav.yml — generated by mdcms
|
||||||
|
# Manual edits to section metadata (defaultname, sort, parent, parent-sort,
|
||||||
|
# pagesvisibility, categorynames) are preserved on rebuild.
|
||||||
|
|
||||||
|
sections:
|
||||||
|
- code: getting-started
|
||||||
|
defaultname: Getting Started
|
||||||
|
sort: 100
|
||||||
|
pagesvisibility: visible
|
||||||
|
|
||||||
|
- code: reference
|
||||||
|
defaultname: Reference
|
||||||
|
sort: 200
|
||||||
|
pagesvisibility: visible
|
||||||
|
|
||||||
|
- code: advanced
|
||||||
|
defaultname: Advanced Topics
|
||||||
|
sort: 300
|
||||||
|
pagesvisibility: hidden # pages exist but are not shown in the nav
|
||||||
|
|
||||||
|
- code: changelog
|
||||||
|
defaultname: Changelog
|
||||||
|
sort: 400
|
||||||
|
pagesvisibility: visible
|
||||||
|
parent: reference
|
||||||
|
parent-sort: 99
|
||||||
|
|
||||||
|
pages:
|
||||||
|
- file: pages/home.md
|
||||||
|
title: Home
|
||||||
|
sort: 100
|
||||||
|
|
||||||
|
- file: pages/quickstart.md
|
||||||
|
title: Quick Start
|
||||||
|
section-id: getting-started
|
||||||
|
sort: 100
|
||||||
|
|
||||||
|
- file: pages/install.md
|
||||||
|
title: Installation
|
||||||
|
section-id: getting-started
|
||||||
|
sort: 200
|
||||||
|
|
||||||
|
- file: pages/config-reference.md
|
||||||
|
title: Configuration Reference
|
||||||
|
section-id: reference
|
||||||
|
sort: 100
|
||||||
|
|
||||||
|
- file: pages/api.md
|
||||||
|
title: API Reference
|
||||||
|
section-id: reference
|
||||||
|
sort: 200
|
||||||
|
|
||||||
|
- file: pages/internals.md
|
||||||
|
title: Internals
|
||||||
|
section-id: advanced
|
||||||
|
sort: 100
|
||||||
|
|
||||||
|
- file: pages/v04.md
|
||||||
|
title: v0.4
|
||||||
|
section-id: changelog
|
||||||
|
sort: 100
|
||||||
|
```
|
||||||
237
docs/reference-pages.md
Normal file
237
docs/reference-pages.md
Normal file
|
|
@ -0,0 +1,237 @@
|
||||||
|
# Page reference — frontmatter and mdcms tags
|
||||||
|
|
||||||
|
All keys you can use inside a markdown page in `pages/` or `posts/`.
|
||||||
|
|
||||||
|
A page has two parts:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
---
|
||||||
|
# Frontmatter (YAML, optional except for title)
|
||||||
|
title: My Page
|
||||||
|
---
|
||||||
|
|
||||||
|
Markdown body goes here.
|
||||||
|
|
||||||
|
```mdcms
|
||||||
|
toc
|
||||||
|
```
|
||||||
|
|
||||||
|
Regular markdown, plus mdcms code blocks for callouts, table of contents, post lists.
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Frontmatter
|
||||||
|
|
||||||
|
The YAML block delimited by `---` at the top of the file. Read by `mdcms build` to populate `nav.yml` and `search.json`, and by `index.html` at runtime to set the page title, dates, and meta tags.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
title: Page Title # REQUIRED. Browser tab title, nav label, h1 fallback.
|
||||||
|
# Without this, the page is skipped from nav.yml.
|
||||||
|
|
||||||
|
sort: 100 # Position in the nav within its section. Lower = higher.
|
||||||
|
# Default: 100. Tiebreaker is filename.
|
||||||
|
|
||||||
|
section-id: guides # Assigns this page to a section. Must match (or auto-create)
|
||||||
|
# a code: in nav.yml. Omit to leave unsectioned.
|
||||||
|
|
||||||
|
draft: true # Excludes the page from nav.yml AND search.json.
|
||||||
|
# Default: false.
|
||||||
|
|
||||||
|
author: Jane Doe # Shown in the meta line under the page title (pages with author or created).
|
||||||
|
|
||||||
|
created: 2026-05-18 14:30 # Publish date. Format: YYYY-MM-DD or YYYY-MM-DD HH:MM.
|
||||||
|
# Required for posts to appear in posts-* tag listings.
|
||||||
|
# Used as the sort key in chronological/reverse-chronological lists.
|
||||||
|
|
||||||
|
modified: 2026-05-19 09:15 # Last-modified date. Shown next to created date if set.
|
||||||
|
|
||||||
|
description: Short summary # Used for the <meta name="description"> tag.
|
||||||
|
# Falls back to config.yml sitedescription if omitted.
|
||||||
|
|
||||||
|
keywords: foo, bar, baz # Comma-separated. Indexed in search.json.
|
||||||
|
|
||||||
|
language: en # BCP 47 code. Sets the <html lang=""> attribute when this page is loaded.
|
||||||
|
# Doesn't filter pages — that's what categories are for.
|
||||||
|
---
|
||||||
|
```
|
||||||
|
|
||||||
|
**Category variants** are not a frontmatter field — they are encoded in the filename. `about.nb.md` is the Norwegian variant of `about.md`, provided `nb` is declared in `config.yml` under `categories:`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## mdcms code blocks
|
||||||
|
|
||||||
|
Fenced blocks with the `mdcms` language tag are intercepted by the renderer and replaced with dynamic HTML. The tag name goes either on the fence line or on the first line of the block:
|
||||||
|
|
||||||
|
````markdown
|
||||||
|
```mdcms callout-info
|
||||||
|
title: Heads up
|
||||||
|
This is the body.
|
||||||
|
```
|
||||||
|
````
|
||||||
|
|
||||||
|
…is equivalent to:
|
||||||
|
|
||||||
|
````markdown
|
||||||
|
```mdcms
|
||||||
|
callout-info
|
||||||
|
title: Heads up
|
||||||
|
This is the body.
|
||||||
|
```
|
||||||
|
````
|
||||||
|
|
||||||
|
Inside the block, lines matching `key: value` are parsed as options. The first non-matching line begins the body.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Callout tags — `callout-info`, `callout-warning`, `callout-success`, `callout-error`
|
||||||
|
|
||||||
|
A bordered, tinted box for notes, warnings, success messages, errors. Colour and icon come from `theme.yml` (`callouts:` block); fall back to built-in defaults.
|
||||||
|
|
||||||
|
````markdown
|
||||||
|
```mdcms callout-info
|
||||||
|
title: Note # Optional. Bold title row with icon. Omit for a body-only callout.
|
||||||
|
icon: lightbulb # Optional. Override the default icon. Use an SVG name from assets/icons/.
|
||||||
|
message: aitranslation # Optional. Resolves title + body from config.yml callouts: block.
|
||||||
|
# Takes precedence over inline title/body.
|
||||||
|
|
||||||
|
Body text supports **full markdown** — bold, *italics*, `code`,
|
||||||
|
[links](https://example.com), lists, etc.
|
||||||
|
|
||||||
|
- item one
|
||||||
|
- item two
|
||||||
|
```
|
||||||
|
````
|
||||||
|
|
||||||
|
**Behaviour:**
|
||||||
|
- Type comes from the tag name suffix (`info`/`warning`/`success`/`error`).
|
||||||
|
- `message: <key>` looks up the named block in `config.yml`. When matched, the message's title and body override any inline values. The message's `type:` also overrides the tag type.
|
||||||
|
- For multi-language messages, the renderer picks the entry for the active category, then the default category, then the first key.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Table of contents — `toc`
|
||||||
|
|
||||||
|
Renders a section-grouped, sorted list of all visible non-draft pages in the active category. The page containing the tag is excluded.
|
||||||
|
|
||||||
|
````markdown
|
||||||
|
```mdcms
|
||||||
|
toc
|
||||||
|
```
|
||||||
|
````
|
||||||
|
|
||||||
|
No options. Output is grouped by nav section in section sort order; pages within each section follow their own `sort:`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Post listings — `posts-created-*`
|
||||||
|
|
||||||
|
Generate a chronologically sorted list of posts (files in `posts/`). Requires each post to have a `created:` value in frontmatter.
|
||||||
|
|
||||||
|
**Reliable variants** (others are broken — do not use):
|
||||||
|
|
||||||
|
```
|
||||||
|
posts-created-chronological-byyearmonth
|
||||||
|
posts-created-reversechronological
|
||||||
|
```
|
||||||
|
|
||||||
|
The grammar:
|
||||||
|
|
||||||
|
```
|
||||||
|
posts-created-<order>[-<modifier>]
|
||||||
|
order: chronological | reversechronological
|
||||||
|
modifier: byyear | byyearmonth | lastyear | lastmonth (optional)
|
||||||
|
```
|
||||||
|
|
||||||
|
- `byyear` / `byyearmonth` — group output by year, or by year-and-month.
|
||||||
|
- `lastyear` / `lastmonth` — filter to posts from the last 365/30 days.
|
||||||
|
- No modifier — flat list of all posts.
|
||||||
|
|
||||||
|
````markdown
|
||||||
|
```mdcms
|
||||||
|
posts-created-reversechronological
|
||||||
|
limit: 10 # Max number of posts shown. Default: all.
|
||||||
|
# When paginate: yes, this is the page size (batch size).
|
||||||
|
|
||||||
|
paginate: yes # Pagination mode:
|
||||||
|
# yes — show a "load more" button after batchSize posts.
|
||||||
|
# none — show only the first <limit> posts, no pagination.
|
||||||
|
# no — show all posts at once (default).
|
||||||
|
```
|
||||||
|
````
|
||||||
|
|
||||||
|
**Category filtering:** When `categories-use: yes`, the listing automatically filters to the active category.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Markdown features
|
||||||
|
|
||||||
|
Standard CommonMark plus GFM (GitHub-flavoured) extensions:
|
||||||
|
|
||||||
|
- Tables
|
||||||
|
- Strikethrough (`~~text~~`)
|
||||||
|
- Task lists (`- [ ]` / `- [x]`)
|
||||||
|
- Fenced code blocks with syntax language hints (`` ```python ``)
|
||||||
|
- Autolinks
|
||||||
|
|
||||||
|
**Raw HTML** passes through to the DOM. You can embed HTML directly:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
<meta http-equiv="refresh" content="0; url=docs/">
|
||||||
|
```
|
||||||
|
|
||||||
|
**Scripts injected via `<script>` tags in markdown do not execute** — the renderer uses `innerHTML`, which browsers block from running script tags. Use `<meta http-equiv="refresh">` for redirects.
|
||||||
|
|
||||||
|
**Links to other pages** can use either:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
[Docs](pages/docs.md) # Internal link — rewritten to a client-side route.
|
||||||
|
[External](https://example.com) # External — opens in new tab automatically.
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Full example
|
||||||
|
|
||||||
|
````markdown
|
||||||
|
---
|
||||||
|
title: Quick Start
|
||||||
|
sort: 100
|
||||||
|
section-id: getting-started
|
||||||
|
author: Jane Doe
|
||||||
|
created: 2026-05-18 14:30
|
||||||
|
description: How to install and run MD-CMS in five minutes.
|
||||||
|
keywords: install, setup, quickstart
|
||||||
|
---
|
||||||
|
|
||||||
|
# Quick start
|
||||||
|
|
||||||
|
Welcome. This page walks you through installing MD-CMS.
|
||||||
|
|
||||||
|
```mdcms callout-info
|
||||||
|
title: Before you begin
|
||||||
|
Make sure you have Python 3.9 or newer.
|
||||||
|
```
|
||||||
|
|
||||||
|
## Table of contents
|
||||||
|
|
||||||
|
```mdcms
|
||||||
|
toc
|
||||||
|
```
|
||||||
|
|
||||||
|
## Recent posts
|
||||||
|
|
||||||
|
```mdcms
|
||||||
|
posts-created-reversechronological
|
||||||
|
limit: 5
|
||||||
|
paginate: yes
|
||||||
|
```
|
||||||
|
|
||||||
|
## Translation notice
|
||||||
|
|
||||||
|
```mdcms callout-warning
|
||||||
|
message: aitranslation
|
||||||
|
```
|
||||||
|
````
|
||||||
293
docs/reference-theme.md
Normal file
293
docs/reference-theme.md
Normal file
|
|
@ -0,0 +1,293 @@
|
||||||
|
# theme.yml reference
|
||||||
|
|
||||||
|
`theme.yml` controls the visual presentation of your site. It is separate from `config.yml` so you can update colours and fonts without touching site settings, and vice versa. `index.html` loads it at runtime — no build step required.
|
||||||
|
|
||||||
|
Point `config.yml` at it with:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
theme: theme.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Colours — light and dark mode
|
||||||
|
|
||||||
|
`light` and `dark` are the two mode blocks. Both accept the same keys. mdcms switches between them based on the user's system preference or the theme toggle.
|
||||||
|
|
||||||
|
### Base colours
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
light:
|
||||||
|
accent: "#2563EB" # Primary accent — links, active nav item, focus rings.
|
||||||
|
background: "#FFFFFF" # Main content area background.
|
||||||
|
nav-background: "#F8FAFC" # Sidebar / topbar background.
|
||||||
|
text: "#1E293B" # Body text colour.
|
||||||
|
text-muted: "#64748B" # Secondary text — descriptions, timestamps, captions.
|
||||||
|
divider: "#CBD5E1" # Border and hr colour.
|
||||||
|
# Omit to auto-derive: color-mix(background 85%, text).
|
||||||
|
|
||||||
|
dark:
|
||||||
|
accent: "#60A5FA"
|
||||||
|
background: "#0F172A"
|
||||||
|
nav-background: "#1E293B"
|
||||||
|
text: "#F1F5F9"
|
||||||
|
text-muted: "#94A3B8"
|
||||||
|
divider: "#334155" # Omit to auto-derive.
|
||||||
|
```
|
||||||
|
|
||||||
|
All values are CSS colour strings (hex, `rgb()`, `hsl()`, named colours, `rgba()`).
|
||||||
|
|
||||||
|
### Nav colours
|
||||||
|
|
||||||
|
These control every element inside the sidebar. When `nav-background` is a neutral near-white or near-black the defaults (which fall back to the base colours) work fine and can be omitted. Set them explicitly whenever `nav-background` is a saturated brand colour, a dark sidebar in an otherwise light design, or any noticeably tinted background.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
light:
|
||||||
|
# Nav links and section labels
|
||||||
|
nav-link: "#1E293B" # Inactive nav link text. Defaults to text.
|
||||||
|
nav-link-active: "#2563EB" # Active (current page) nav link. Defaults to accent.
|
||||||
|
nav-section-heading: "#64748B" # Section label text (uppercase, small). Defaults to text-muted.
|
||||||
|
|
||||||
|
# Sidebar header elements
|
||||||
|
nav-sitename: "#1E293B" # Site name in the sidebar header. Defaults to nav-link.
|
||||||
|
nav-description: "#64748B" # Site description below the site name. Defaults to nav-section-heading.
|
||||||
|
nav-toggle: "#64748B" # Dark/light mode toggle button. Defaults to nav-section-heading.
|
||||||
|
```
|
||||||
|
|
||||||
|
The same keys apply in the `dark:` block.
|
||||||
|
|
||||||
|
**When nav-background is a bold colour** (e.g. brand red, navy, deep green), set all six nav keys explicitly so links, labels, the site name, description, and toggle are all legible against the nav background. A common pattern is white (`#FFFFFF`) for `nav-link`, `nav-link-active`, and `nav-sitename`, and a semi-transparent white (e.g. `rgba(255,255,255,0.65)`) for `nav-section-heading`, `nav-description`, and `nav-toggle`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Semantic colours
|
||||||
|
|
||||||
|
Used by callout tags (`callout-info`, `callout-warning`, `callout-success`, `callout-error`). `colours-semantic` applies to both modes. `colours-semantic-dark` overrides for dark mode only — use lighter, more luminous variants so callout borders and tinted backgrounds remain legible on dark page backgrounds.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
colours-semantic:
|
||||||
|
info: "#2563EB"
|
||||||
|
warning: "#D97706"
|
||||||
|
success: "#16A34A"
|
||||||
|
error: "#DC2626"
|
||||||
|
|
||||||
|
colours-semantic-dark:
|
||||||
|
info: "#60A5FA" # Lighter blue — visible on dark background
|
||||||
|
warning: "#F59E0B"
|
||||||
|
success: "#34D399"
|
||||||
|
error: "#F87171"
|
||||||
|
```
|
||||||
|
|
||||||
|
If `colours-semantic-dark` is omitted, the `colours-semantic` values are used in both modes.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Callout defaults
|
||||||
|
|
||||||
|
Overrides the icon and colour used for each callout type. `primary-colour` sets the left border; `background-colour` sets the tinted background fill (applied at ~8% opacity by the renderer).
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
callouts:
|
||||||
|
info:
|
||||||
|
icon: info # SVG icon name from assets/icons/ (without .svg)
|
||||||
|
primary-colour: "#2563EB" # Left border colour
|
||||||
|
background-colour: "#2563EB" # Background tint colour
|
||||||
|
|
||||||
|
warning:
|
||||||
|
icon: warning
|
||||||
|
primary-colour: "#D97706"
|
||||||
|
background-colour: "#D97706"
|
||||||
|
|
||||||
|
success:
|
||||||
|
icon: success
|
||||||
|
primary-colour: "#16A34A"
|
||||||
|
background-colour: "#16A34A"
|
||||||
|
|
||||||
|
error:
|
||||||
|
icon: error
|
||||||
|
primary-colour: "#DC2626"
|
||||||
|
background-colour: "#DC2626"
|
||||||
|
```
|
||||||
|
|
||||||
|
Individual callout blocks in markdown can override the icon with `icon: <name>`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Nav section toggle icons
|
||||||
|
|
||||||
|
Sections with `pagesvisibility: hidden` in `nav.yml` are collapsible. These two top-level keys (not inside `light:`/`dark:`) set the icons used for the toggle.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
nav-section-expand-icon: arrow_right # Shown when section is collapsed. Default: arrow_right.
|
||||||
|
nav-section-collapse-icon: arrow_drop_down # Shown when section is expanded. Default: arrow_drop_down.
|
||||||
|
```
|
||||||
|
|
||||||
|
Available icon names:
|
||||||
|
|
||||||
|
| Expand | Collapse | Style |
|
||||||
|
|---|---|---|
|
||||||
|
| `arrow_right` | `arrow_drop_down` | Solid filled triangles (default) |
|
||||||
|
| `keyboard_arrow_right` | `keyboard_arrow_down` | Chevrons — lighter, more modern |
|
||||||
|
| `keyboard_double_arrow_right` | `keyboard_double_arrow_down` | Double chevrons — emphatic |
|
||||||
|
| `expand_content` | `collapse_content` | Corner arrows — editorial |
|
||||||
|
| `add` | `minimize` | Plus / minus — minimal |
|
||||||
|
|
||||||
|
The two keys are independent — expand and collapse do not have to use icons from the same pair, though keeping a consistent visual weight reads better.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Typography
|
||||||
|
|
||||||
|
Font format: `"provider:Font Name:weight"`
|
||||||
|
|
||||||
|
- `provider`: `bunny` (privacy-friendly, GDPR-safe) or `google`
|
||||||
|
- `Font Name`: exact font family name as listed on the font provider
|
||||||
|
- `weight`: numeric CSS weight (`400`, `700`, etc.)
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
font-body: "bunny:Noto Sans:400" # Body text font
|
||||||
|
font-heading: "bunny:Noto Sans:700" # Headings (h1–h6) font
|
||||||
|
font-code: "bunny:Fira Code:400" # Code blocks and inline code
|
||||||
|
```
|
||||||
|
|
||||||
|
System fonts (no external request):
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
font-body: "system-ui:400"
|
||||||
|
```
|
||||||
|
|
||||||
|
Shorthand without provider defaults to Google Fonts:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
font-body: "Noto Sans:400" # equivalent to google:Noto Sans:400
|
||||||
|
```
|
||||||
|
|
||||||
|
Size and spacing:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
font-size: 1.0 # Unitless multiplier. 1.0 = 16px base. 1.125 = 18px.
|
||||||
|
line-height: 1.7 # Unitless multiplier for body text line spacing.
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Layout
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
main-width: 80em # Maximum width of the content column. Any CSS length unit.
|
||||||
|
nav-width: 20em # Width of the sidebar. Any CSS length unit.
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Full example
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# mdcms v0.4 | DO NOT REMOVE THIS COMMENT
|
||||||
|
# MD-CMS v0.4 — Theme configuration
|
||||||
|
|
||||||
|
light:
|
||||||
|
accent: "#2563EB"
|
||||||
|
background: "#FFFFFF"
|
||||||
|
nav-background: "#F8FAFC"
|
||||||
|
text: "#1E293B"
|
||||||
|
text-muted: "#64748B"
|
||||||
|
# nav-link, nav-link-active, nav-section-heading, nav-sitename,
|
||||||
|
# nav-description, nav-toggle — omit when nav-background is neutral.
|
||||||
|
# divider — omit to auto-derive from background + text.
|
||||||
|
|
||||||
|
dark:
|
||||||
|
accent: "#60A5FA"
|
||||||
|
background: "#0F172A"
|
||||||
|
nav-background: "#1E293B"
|
||||||
|
text: "#F1F5F9"
|
||||||
|
text-muted: "#94A3B8"
|
||||||
|
|
||||||
|
colours-semantic:
|
||||||
|
info: "#2563EB"
|
||||||
|
warning: "#D97706"
|
||||||
|
success: "#16A34A"
|
||||||
|
error: "#DC2626"
|
||||||
|
|
||||||
|
colours-semantic-dark:
|
||||||
|
info: "#60A5FA"
|
||||||
|
warning: "#F59E0B"
|
||||||
|
success: "#34D399"
|
||||||
|
error: "#F87171"
|
||||||
|
|
||||||
|
callouts:
|
||||||
|
info:
|
||||||
|
icon: info
|
||||||
|
primary-colour: "#2563EB"
|
||||||
|
background-colour: "#2563EB"
|
||||||
|
warning:
|
||||||
|
icon: warning
|
||||||
|
primary-colour: "#D97706"
|
||||||
|
background-colour: "#D97706"
|
||||||
|
success:
|
||||||
|
icon: success
|
||||||
|
primary-colour: "#16A34A"
|
||||||
|
background-colour: "#16A34A"
|
||||||
|
error:
|
||||||
|
icon: error
|
||||||
|
primary-colour: "#DC2626"
|
||||||
|
background-colour: "#DC2626"
|
||||||
|
|
||||||
|
# nav-section-expand-icon: arrow_right
|
||||||
|
# nav-section-collapse-icon: arrow_drop_down
|
||||||
|
|
||||||
|
font-body: "bunny:Noto Sans:400"
|
||||||
|
font-heading: "bunny:Noto Sans:700"
|
||||||
|
font-code: "bunny:Fira Code:400"
|
||||||
|
font-size: 1.0
|
||||||
|
line-height: 1.7
|
||||||
|
|
||||||
|
main-width: 80em
|
||||||
|
nav-width: 20em
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Bold nav background example
|
||||||
|
|
||||||
|
When `nav-background` matches or is close to `accent`, set all nav colour keys explicitly:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
light:
|
||||||
|
accent: "#D00C33"
|
||||||
|
background: "#FFFFFF"
|
||||||
|
nav-background: "#D00C33"
|
||||||
|
text: "#1A1A1A"
|
||||||
|
text-muted: "#5C5C5C"
|
||||||
|
nav-link: "#FFFFFF"
|
||||||
|
nav-link-active: "#FFFFFF"
|
||||||
|
nav-section-heading: "rgba(255,255,255,0.65)"
|
||||||
|
nav-sitename: "#FFFFFF"
|
||||||
|
nav-description: "rgba(255,255,255,0.65)"
|
||||||
|
nav-toggle: "rgba(255,255,255,0.65)"
|
||||||
|
|
||||||
|
dark:
|
||||||
|
accent: "#D00C33"
|
||||||
|
background: "#0A0A0A"
|
||||||
|
nav-background: "#000000"
|
||||||
|
text: "#FFFFFF"
|
||||||
|
text-muted: "#A89090"
|
||||||
|
nav-link: "#E2E2E2"
|
||||||
|
nav-link-active: "#FFFFFF"
|
||||||
|
nav-section-heading: "#888888"
|
||||||
|
nav-sitename: "#FFFFFF"
|
||||||
|
nav-description: "#888888"
|
||||||
|
nav-toggle: "#888888"
|
||||||
|
|
||||||
|
colours-semantic:
|
||||||
|
info: "#D00C33"
|
||||||
|
warning: "#B26A1F"
|
||||||
|
success: "#2F7A4A"
|
||||||
|
error: "#D00C33"
|
||||||
|
|
||||||
|
colours-semantic-dark:
|
||||||
|
info: "#FF6B6B"
|
||||||
|
warning: "#F59E0B"
|
||||||
|
success: "#34D399"
|
||||||
|
error: "#FF6B6B"
|
||||||
|
```
|
||||||
Loading…
Reference in a new issue