Skip to main content

A simple in-app Markdown documentation viewer for Django.

Project description

django-docs-viewer

tests PyPI version Supported Python versions Supported Django versions License: MIT

A simple in-app Markdown documentation viewer for Django.

Point it at a directory of Markdown files and it serves them as browsable documentation pages with an auto-generated sidebar. No build step, no database, no models — pages are read from disk and rendered on request.

Features

  • Renders Markdown files (fenced_code, tables, toc, sane_lists).
  • Auto-generated sidebar navigation grouped by folder — or hand-written via a menu.md file.
  • Automatic per-page table of contents built from each page's headings.
  • Case-insensitive, traversal-safe URL resolution.
  • Serves images referenced from your Markdown.
  • Login required by default; can be made public with one setting.
  • Self-contained, overridable templates.

How it compares

The niche is zero-build, database-free, self-navigating docs: Markdown rendered at request time, with the sidebar and per-page table of contents built from the folder tree and headings. django-markdown-view also renders at request time but builds no navigation; Django Spellbook builds navigation but via a generation step and as part of a larger Markdown-components framework.

Installation

pip install django-docs-viewer

Usage

Add the app to INSTALLED_APPS and point DOCS_VIEWER_ROOT at your docs directory:

# settings.py
INSTALLED_APPS = [
    # ...
    "docs_viewer",
]

DOCS_VIEWER_ROOT = BASE_DIR / "docs"

Include the URLs:

# urls.py
from django.urls import include, path

urlpatterns = [
    # ...
    path("docs/", include("docs_viewer.urls")),
]

By default the docs require an authenticated user and redirect anonymous visitors to LOGIN_URL, so make sure your project has a login view — or set DOCS_VIEWER_LOGIN_REQUIRED = False to make the docs public.

Your docs directory can be flat:

docs/
├── README.md                     # landing page + site title
├── 01-getting-started.md
└── 02-configuration.md

or nested, with folders becoming sidebar groups:

docs/
├── README.md                     # landing page + site title
└── manual/
    ├── 01-getting-started.md
    ├── 02-configuration.md
    └── images/
        └── status-legend.png

Folders nest to any depth, and each level becomes a sidebar group, so a subfolder per language keeps translated pages neatly separated instead of listing every language in one flat group:

docs/
├── README.md                     # landing page + site title
└── manual/
    ├── deutsch/
    │   ├── 01-erste-schritte.md
    │   └── 02-konfiguration.md
    ├── english/
    │   ├── 01-getting-started.md
    │   └── 02-configuration.md
    └── francais/
        ├── 01-prise-en-main.md
        └── 02-configuration.md

Group labels come from the folder name, humanized (dashes and underscores become spaces, and it is title-cased), so name folders in lowercase — deutsch renders as Deutsch in the sidebar.

Pages sort by filename within their folder (the index/README first). Prefix filenames with a zero-padded number (01-, 02-) to control the order; the prefix is stripped from the sidebar label, so 01-getting-started.md shows as Getting started. Zero-pad once you pass nine pages, otherwise 10-… sorts ahead of 2-….

Settings

Setting Default Description
DOCS_VIEWER_ROOT (required) Path to the directory containing your Markdown files.
DOCS_VIEWER_BASE_TEMPLATE "docs_viewer/base.html" Template the docs page extends. Point at your own layout.
DOCS_VIEWER_LOGIN_REQUIRED True Redirect anonymous users to LOGIN_URL. Set False to make docs public.
DOCS_VIEWER_TITLE "Documentation" Fallback page title when no index heading is available.
DOCS_VIEWER_TOC_DEPTH "2-3" Heading levels included in the per-page table of contents.
DOCS_VIEWER_SKIP_DIRS ["_*"] Glob patterns; directories matching any are hidden (excluded from navigation and not served). A custom value replaces the default, so include "_*" if you still want underscore-prefixed directories hidden.

The page title is taken from the first level-1 heading of the index (index.md or README.md) at the docs root, falling back to DOCS_VIEWER_TITLE.

Customizing the template

The docs page (docs_viewer/detail.html) extends whatever template DOCS_VIEWER_BASE_TEMPLATE names, resolved dynamically at render time. By default it extends the minimal docs_viewer/base.html bundled with the app, so it works with no configuration.

To make docs pages inherit your site's chrome, point the setting at your own base template:

DOCS_VIEWER_BASE_TEMPLATE = "myproject/base.html"

Your base template only needs a content block (and, optionally, a title block):

{% block title %}{% endblock %}
...
{% block content %}{% endblock %}

To change the docs page itself rather than the surrounding layout, override docs_viewer/detail.html in your own template directory.

Custom navigation

By default the sidebar is generated from your folder tree. To control it by hand instead, add a menu.md file at the root of your docs directory. When present, its rendered Markdown replaces the auto-generated sidebar (and menu.md itself is never served as a page).

Write it as a normal Markdown list of links:

- [Introduction](/docs/)
- [Getting started](/docs/manual/01-getting-started)
- [Configuration](/docs/manual/02-configuration)

The links are rendered as-is, so point them at the paths where you mounted the viewer — the /docs/ prefix above matches path("docs/", include(...)).

Translations

The interface strings ship translated into English, German and French. The active language follows Django's usual i18n machinery, so enable django.middleware.locale.LocaleMiddleware (and keep USE_I18N = True) if you want the docs to follow the request's language.

Development

poetry install
poetry run python manage.py test tests

Run the full support matrix with tox:

poetry run tox

See CONTRIBUTING.md for coverage, translations, and the pull-request checklist.

License

MIT

Download files

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

Source Distribution

django_docs_viewer-0.2.0.tar.gz (12.4 kB view details)

Uploaded Source

Built Distribution

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

django_docs_viewer-0.2.0-py3-none-any.whl (15.2 kB view details)

Uploaded Python 3

File details

Details for the file django_docs_viewer-0.2.0.tar.gz.

File metadata

  • Download URL: django_docs_viewer-0.2.0.tar.gz
  • Upload date:
  • Size: 12.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for django_docs_viewer-0.2.0.tar.gz
Algorithm Hash digest
SHA256 0f90a4e76764c8d69469c61d2c3b8b16dd8cd0fd0df0c7d23a8f5b6b08a7c1a4
MD5 30161f55cd17f83392a0013fcd1caf5b
BLAKE2b-256 3276b7f3793a171a1a26293b01b4fa63f41f0830351f3f7d96d31fc64ff3cc21

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_docs_viewer-0.2.0.tar.gz:

Publisher: publish.yml on JanMalte/django-docs-viewer

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file django_docs_viewer-0.2.0-py3-none-any.whl.

File metadata

File hashes

Hashes for django_docs_viewer-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 2a975c7e0510a74daf9df634b7b510d88bd676145976e5b8282267aaf31aaa49
MD5 55036b5363940ba3fc74969852d14e83
BLAKE2b-256 740df02d947703a31bcc1a5aded4b1a1c41023913db5682939d52c72e6f71927

See more details on using hashes here.

Provenance

The following attestation bundles were made for django_docs_viewer-0.2.0-py3-none-any.whl:

Publisher: publish.yml on JanMalte/django-docs-viewer

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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