Templates#
mdjango renders every HTML response through one template, mdjango/page.html, which composes
cotton components from cotton/docs/. There are no {% block %} tags, no {% extends %}, no
template tags and no context processors. The one component a Consumer may override is the head
slot (head_extra.html) — shadow it to add analytics or other <head> tags; see
Add analytics and other head tags. Every other template is a closed
surface. What else a Consumer may change is listed in settings and
theme tokens.
Page context#
mdjango.views.page_context(page) builds this dict. Runtime views and the export both use it.
| Key | Type | Content |
|---|---|---|
conf |
mdjango.conf.Conf |
resolved settings: brand, home_url, version, github_url, header_links, site_title, description, llm_docs, and title (site title or brand) |
page |
Page |
the current Page: path, title, weight, description, draft, source, body, section, subsection, groups |
article_html |
str |
rendered article, marked safe by the article component |
toc |
tuple of TocItem(id, label, level) |
H2 and H3 headings; empty when the page has none |
home |
dict or None |
{kind, title, url, active} for the Index page; None without a root _index.md |
nav |
list of dicts | groups {title, loose, items}; items are {kind: "link", title, url, active} or {kind: "subgroup", title, open, items} |
breadcrumb |
list of dicts | {label, url} per crumb, outermost group first, then the Page; url is always "" |
eyebrow |
str |
title of the Page's innermost group; "" for root Pages |
prev, next |
Page or None |
neighbours in flattened navigation order |
prev_url, next_url |
str |
their URLs, or "" |
page_md_url |
str |
the .md alternate URL, or "" when MDJANGO_LLM_DOCS is false |
The page template#
mdjango/templates/mdjango/page.html wraps everything in <c-docs.base>, then renders the header,
the drawer backdrop, a .docs-shell grid holding the sidebar, <main> (inline TOC, eyebrow,
article, pager) and the TOC rail, then the search dialog. When toc is empty both TOC instances
are omitted and the shell gets the docs-shell--no-toc class, which drops the rail column.
Components#
All under mdjango/templates/cotton/docs/. "Attributes" are passed explicitly by the page
template. "Outer context" is read from the page context without being passed.
| File | Renders | Attributes | Outer context |
|---|---|---|---|
base.html |
<!doctype html> through </html>: <title>, the rel="alternate" link, the no-flash theme script, the mdjango.css link, the import map, the head slot (<c-docs.head-extra />), <body class="docs-body" data-controller="theme search disclosure"> with {{ slot }}, and the application.js module |
title, page_md_url (default "") |
— |
head_extra.html |
nothing — ships empty. A Consumer shadows it to inject <head> content (analytics, a verification <meta>, a preconnect); rendered at the end of <head>. See Add analytics and other head tags |
— | — |
header.html |
hamburger, wordmark, breadcrumb, search trigger, version chip, llms.txt links, header links, GitHub link, theme toggle |
conf, breadcrumb |
— |
sidebar.html |
<nav class="docs-sidebar">: Home link, mobile llms.txt group, one group per nav entry with <details class="docs-nav-sub"> for subgroups |
nav |
home, conf |
toc.html |
<nav class="docs-toc docs-toc--{variant}"> with one link per heading, data-controller="scrollspy" |
items, variant (default rail) |
— |
eyebrow.html |
<p class="docs-eyebrow">; nothing when the label is empty |
label (default "") |
— |
article.html |
<article class="article">{{ html\|safe }}</article> |
html |
— |
pager.html |
<nav class="docs-pager"> with prev/next links; an empty placeholder where a neighbour is absent |
prev, next, prev_url, next_url |
— |
breadcrumb.html |
<nav class="docs-breadcrumb">; crumbs are <span>s, never links |
items |
— |
search.html |
the search dialog, data-search-index-url="{% url 'mdjango:search_index' %}" |
— | — |
Stimulus controllers#
Booted by application.js, which registers five controllers. theme, search and disclosure
mount on <body>.
| Identifier | Mounted on | Does |
|---|---|---|
theme |
<body> |
flips data-theme on <html> and persists it to localStorage |
search |
<body> |
the palette: / and Ctrl/⌘-K open it, fetches MiniSearch and the index on first open, keyboard navigation |
disclosure |
<body> |
opens and closes the mobile navigation drawer |
scrollspy |
each <c-docs.toc> |
marks the TOC link of the heading nearest the top of the viewport |
clipboard |
each code block, injected by the renderer | copies the block's text; shows "copied" for 1.6 seconds |
Static assets#
Under mdjango/static/mdjango/, all vendored:
| Path | Purpose |
|---|---|
mdjango.css |
the compiled stylesheet, @font-face rules included |
fonts.css |
the @font-face rules alone |
fonts/*.woff2, fonts/LICENSE.txt |
IBM Plex Mono, six faces, OFL 1.1 |
application.js |
Stimulus boot; registers the five controllers |
controllers/{theme,clipboard,scrollspy,disclosure,search}_controller.js |
one file per controller |
vendor/stimulus.js, vendor/minisearch.js |
ESM builds, resolved by the import map in base.html |