Skip to main content

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 routingpages/about.md becomes /about, pages/docs/intro.md becomes /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.py in 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

markdown_cms-0.1.1.tar.gz (98.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

markdown_cms-0.1.1-py3-none-any.whl (108.2 kB view details)

Uploaded Python 3

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

Hashes for markdown_cms-0.1.1.tar.gz
Algorithm Hash digest
SHA256 043ff424ccbe7be778b87d75495bd6b8d5d951e9ba47400e6b0f66e4e17a4497
MD5 99b3481ec0ccba62ee680dc4f85de737
BLAKE2b-256 89f37898e7445262037e238b8afcce00decd84772238e673bf23dda93edba3b7

See more details on using hashes here.

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

Hashes for markdown_cms-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 a2740854437be8fdc3edfd55e29e41aa78eba31762a7b212cc223e7048a118ba
MD5 eb7bbe3d8a86a7d6b41f2b28a4daa24e
BLAKE2b-256 b6b3357fe0eff768e4f4928577701db0e3f098a8d3342fb45e1150c0ac23e883

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page