Markdown-first CMS and Application Framework
Project description
Markdown-First Application Framework
A Markdown-first CMS and Application Framework built with FastHTML and HTMX.
Philosophy: Everything is a file. Everything is Markdown. Markdown is declarative UI, Python is behavior.
What Is This?
markdown-cms is a Python web framework where you build complete web applications by writing Markdown files — not just documentation sites.
Pages, layouts, navigation, forms, interactive calculators, data tables, component libraries, admin panels — all driven by Markdown and a file-based structure. Python handles behavior; Markdown handles structure and intent.
Think of it as the intersection of Obsidian's file-first philosophy, WordPress's template system, and Django's project structure — but lighter, faster, and Markdown-native.
Real-World Reference: TechArya
TechArya.net — an electronics and embedded systems learning platform — was built and migrated using this framework. It demonstrates the framework's capability beyond documentation:
- 25+ structured electronics lessons with diagrams, formulas, and categorized navigation
- Live HTMX calculators (Ohm's Law, RC filter, power) — form submission returns parsed Markdown responses
- Nested subject navigation with auto-generated sidebar trees from the file structure
- Multi-theme switching (Bootstrap, Bulma, Tailwind, Materialize) at runtime
- Image galleries, tables, alerts, carousels — all from Markdown
TechArya is proof that this framework handles real content-heavy, interactive applications — not just static docs.
What Can You Build With It?
This is not a documentation generator. It is a full application framework. You can build:
| Use Case | How |
|---|---|
| Documentation sites | pages/ + markdown content |
| Learning platforms | Nested subject folders + sidebar auto-navigation |
| Company portals | Template parts (header/footer/nav) + themes |
| Technical blogs | File-based routing + metadata |
| Interactive tools | HTMX endpoints + Python API handlers in api.py |
| Admin dashboards | Built-in admin routes + SQLite database |
| Product landing pages | Cards, heroes, stats, columns — all in Markdown |
| Form-driven apps | :::form blocks + Python POST handlers |
Philosophy
Markdown describes structure and intent. Python executes behavior and truth.
This framework enforces a strict separation:
- Markdown = pages, layout, content, UI structure, forms, components
- Python = business logic, database queries, API responses, authentication
If a feature requires putting Python logic inside a Markdown file — it does not belong here.
Pure Text Syntax
The framework extends Markdown with a clean, readable syntax for UI elements:
=> Click Me -> <button class="btn btn-primary">
=> Save (success) -> <button class="btn btn-success">
=> Delete (danger) -> <button class="btn btn-danger">
? Your Name (text) -> <input type="text">
?? Your Message -> <textarea>
> [!SUCCESS] Saved! -> styled success alert
> [!WARNING] Review -> styled warning alert
:::card
# Title
Content here
=> Learn More
:::
No HTML required. No YAML. No JSON. Just text that reads like what it means.
Quick Start
pip install markdown-cms
# Create a new project
markdown-cms create my-project
cd my-project
# Run development server
markdown-cms run
Open http://localhost:8000 — your site is live with auto-reload.
Features
- File-based routing —
pages/about.mdbecomes/about,pages/docs/intro.mdbecomes/docs/intro - Template parts — WordPress-style
header.md,footer.md,navbar.md,sidenav.md - Multi-theme system — Switch between Bootstrap, Bulma, Tailwind, Materialize with one command
- HTMX-native — Components load via HTMX fragments; no page refresh needed
- Component library — 3-level hierarchy: Elements, Containers, Layout
- Plugin system — Drop Python plugins into
plugins/directory - Admin panel — Built-in content management at
/admin - Authentication — JWT-based auth, user management
- Database — SQLite via SQLAlchemy, with CLI commands (
markdown-cms db init/seed/reset) - Auto-reload — Watches
pages/,templates/,static/for changes - API routes — Drop an
api.pyin your project root; the framework auto-loads it - Agents — Built-in orchestrator, implementation, and testing agents for development assistance
Project Structure
my-project/
├── pages/ # Markdown content -> URL routes
├── templates/ # header.md, footer.md, navbar.md, sidenav.md
├── static/ # CSS, JS, images
├── components/ # Reusable HTMX-loadable markdown fragments
│ ├── elements/ # Buttons, inputs, dropdowns
│ ├── containers/ # Cards, panels, tabs
│ └── layout/ # Navbar, sidebar, header, footer
├── themes/ # bootstrap/, bulma/, tailwind/, materialize/
├── apps/ # Custom Django-style applications
├── plugins/ # Custom plugins
└── api.py # Your HTMX API endpoints (auto-loaded)
CLI Commands
markdown-cms create <name> # Scaffold new project
markdown-cms run # Development server (auto-reload)
markdown-cms run --port 3000 # Custom port
markdown-cms build # Validate project structure
markdown-cms theme bootstrap # Switch to Bootstrap theme
markdown-cms theme tailwind # Switch to Tailwind theme
markdown-cms db init # Create database tables
markdown-cms db seed # Seed with sample data
markdown-cms db reset # Drop and recreate (with confirmation)
markdown-cms db info # Show database info
markdown-cms agent orchestrator # Run development orchestrator agent
Writing HTMX API Routes
Create api.py in your project root — the framework loads it automatically:
from markdown_cms.core.parser import MarkdownParser
from fasthtml.common import NotStr
_parser = MarkdownParser()
def render_markdown(md_text):
return _parser.parse(md_text).get("html", "")
def setup_api_routes(app):
@app.post("/api/calculate")
async def calculate(request):
form = await request.form()
value = float(form.get("input", 0))
result = value * 2
# Return Markdown — the library parses it to HTML
md = f"> [!SUCCESS] Result\n> **{result}**"
return NotStr(render_markdown(md))
Then call it from any Markdown page:
:::form /api/calculate
? Input Value (number)
=> Calculate (success)
:::
Zero boilerplate. No templates. Pure Markdown + Python.
Limitations
The framework is at v0.1.0 / Alpha stage. Known limitations:
- No built-in search — full-text search across pages requires a custom plugin
- SQLite only — no PostgreSQL or MySQL support yet
- Single-user auth — multi-tenant or org-level permissions not implemented
- No asset pipeline — CSS/JS is served as-is; no bundling or minification
- Plugin API is minimal — the plugin scaffold exists but the hook system is early-stage
- No live preview in admin — content edits require a page reload to see final output
- Python 3.12+ required — uses modern type annotation syntax throughout
- No i18n/l10n — no built-in internationalisation support
Roadmap / Feature Improvements
Planned for future versions:
| Feature | Priority |
|---|---|
| Full-text search across pages | High |
| PostgreSQL / MySQL support | High |
| Live admin preview panel | High |
| Image upload + media manager | Medium |
| Tag and category system | Medium |
| RSS / sitemap generation | Medium |
| Plugin hook system (before/after render) | Medium |
| Multi-language content support | Medium |
| Role-based access control | Medium |
| Static site export (SSG mode) | Low |
| CLI scaffolding for custom plugins | Low |
| VS Code / Obsidian extension | Low |
Tech Stack
| Component | Technology |
|---|---|
| Web framework | FastHTML |
| Interactivity | HTMX |
| Markdown parsing | markdown-it-py |
| Database ORM | SQLAlchemy |
| Auth | python-jose + passlib |
| Build | Hatchling |
Development
git clone https://github.com/rakeshpatil1983/markdown-cms
cd markdown-cms
pip install -e ".[dev]"
pre-commit install
pytest
License
MIT License — see LICENSE for details.
Contributing
Contributions welcome. Please open an issue before submitting large changes.
Markdown describes structure and intent. Python executes behavior and truth.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file markdown_cms-0.1.1.tar.gz.
File metadata
- Download URL: markdown_cms-0.1.1.tar.gz
- Upload date:
- Size: 98.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
043ff424ccbe7be778b87d75495bd6b8d5d951e9ba47400e6b0f66e4e17a4497
|
|
| MD5 |
99b3481ec0ccba62ee680dc4f85de737
|
|
| BLAKE2b-256 |
89f37898e7445262037e238b8afcce00decd84772238e673bf23dda93edba3b7
|
File details
Details for the file markdown_cms-0.1.1-py3-none-any.whl.
File metadata
- Download URL: markdown_cms-0.1.1-py3-none-any.whl
- Upload date:
- Size: 108.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a2740854437be8fdc3edfd55e29e41aa78eba31762a7b212cc223e7048a118ba
|
|
| MD5 |
eb7bbe3d8a86a7d6b41f2b28a4daa24e
|
|
| BLAKE2b-256 |
b6b3357fe0eff768e4f4928577701db0e3f098a8d3342fb45e1150c0ac23e883
|