Markdown-based static site publishing — no server, no database required. Write in markdown, build with Python, deploy anywhere.
Find a file
2026-05-08 15:29:54 +00:00
app Rename website/ directory to app/ 2026-05-08 15:29:54 +00:00
resources v0.2.2 migrated to GitHub 2026-04-20 00:02:43 +07:00
samplesite v0.2.2 migrated to GitHub 2026-04-20 00:02:43 +07:00
.gitignore v0.2.2 migrated to GitHub 2026-04-20 00:02:43 +07:00
CLAUDE.md Add CLAUDE.md with codebase documentation for AI assistants 2026-04-27 04:27:24 +00:00
mdcms.py v0.2.2 migrated to GitHub 2026-04-20 00:02:43 +07:00
README.md Add installation section to README 2026-04-21 10:29:23 +07:00

MD-CMS

Markdown-based static site publishing — no server, no database, no terminal required.

MD-CMS lets you write and publish a website entirely in markdown. Drop your .md files in a folder, run the build tool, upload the output to any static host, and you're done. All rendering happens in the browser.


Installation

  1. Download the latest release.
  • The contents of mdcms-vNNN.zip and mdcms.zip are identical. Choose whatever suits your preference.
  1. Unzip the content in your project directory.
  2. Make necessary changes to config.yml and add pages to pages/. Please note: Links to other pages are in the form pages/pagename.md.
  3. Open the terminal in your project directory, and:
  • Open MDCMS.py with python3 mdcms.py.
  • Select option 3 to generate a nav.yml and search.json file.
  • Open nav.yml in your text editor and make sure that the section and title names are correct.
  • Once you're satisfied, you're ready to upload the content of website/. If you need a ZIP file, return to the terminal and select option 1.

How it works

MD-CMS has two parts:

index.html — a single-file browser renderer. It reads your markdown files, config, and navigation at runtime and renders everything client-side. No build pipeline, no framework, no compilation step.

mdcms.py — a zero-dependency Python CLI tool. It scans your content, generates nav.yml and search.json, validates your config, and packages everything into a zip file ready for upload.


Features

  • Write in markdown — pages and posts with YAML frontmatter
  • Categories — serve multiple versions of the same page (e.g. languages, destinations, variants) via ?cat= URL parameter and a dropdown UI
  • Sections — nested navigation defined in nav.yml; pages declare their section via frontmatter
  • Full-text search — category-aware, generated at build time
  • Dynamic content tags — embed post lists with date sorting, pagination, and year grouping using fenced mdcms code blocks
  • RTL support — per-category text direction
  • Custom fonts per category — load a font file from assets/fonts/ when a category is selected
  • Light and dark mode — fully themeable via config.yml
  • No server required — everything is static; deploy to GitHub Pages, Codeberg Pages, Cloudflare Pages, Netlify, or any file host
  • Zero dependenciesmdcms.py uses only the Python standard library

File structure

mdcms.py          ← build tool, run this
quickstart.md     ← getting started guide
website/          ← everything in here gets deployed
  index.html
  config.yml
  nav.yml
  search.json
  pages/
    home.md
    about.md
    about.nb.md   ← Norwegian variant of about.md
  posts/
    2025-01-01-my-first-post.md
  assets/
    images/
    fonts/

The website/ folder is your deployable site. mdcms.py lives outside it.


Getting started

Requirements: Python 3 (standard library only). A modern browser.

  1. Clone or download this repository.
  2. Run python3 mdcms.py and choose option 2 to build your config and folder structure from scratch.
  3. Write your pages in website/pages/ and posts in website/posts/.
  4. Run mdcms.py again and choose option 3 to generate nav.yml and search.json.
  5. Choose option 8 to start a local webserver and preview your site.
  6. When ready to publish, choose option 1 to validate, build, and export website.zip.
  7. Upload the contents of website.zip to your static host.

Local preview note: Open index.html via the built-in webserver (option 8), not by double-clicking the file. Browsers block local file access due to CORS restrictions.


Configuration

Site behaviour is controlled by two YAML files in website/:

config.yml — site title, logo, default page, search settings, typography, layout dimensions, light/dark theme colours, and category definitions.

nav.yml — navigation structure. Sections are defined here; pages declare their section via section-id in frontmatter. Sections can be nested.

Both files are human-readable and comment-supported. The mdcms.py wizard generates them for you and can fill in missing values interactively.


Categories

Categories let you publish multiple versions of the same page — different languages, regions, or product variants — under a single URL with a ?cat= parameter.

Each variant is a separate file:

about.md          ← default
about.en-gb.md    ← British English variant
about.nb.md       ← Norwegian variant

The category dropdown shows only categories for which a variant exists (or where a "not available" message is configured). All internal links preserve the active category.


Tag system

Embed dynamic post lists in any page using fenced mdcms code blocks:

```mdcms
posts-date-reversechronological
limit: 10
paginate: yes
```

Available tags cover chronological and reverse-chronological post lists, grouped by year, with date or datetime display, and configurable pagination.


Licence

Apache 2.0 — see LICENCE.

© Kristian Benestad