mkdocs-vwidref
A MkDocs plugin that lets you link to pages by front-matter ID with a compact wiki-style syntax and show status / progress / title inline.
- Title appears only when
:tis present. - Status (
:s) and Progress (:p) can be shown alone or together. - Parentheses / angle brackets appear only when multiple items are shown.
- Links are emitted as relative
.mdpaths so Markdown sources remain navigable in and out of MkDocs.
🧩 Installation
pip install mkdocs-vwidref
Enable in mkdocs.yml:
plugins:
- search
- vwidref
Optional configuration (defaults shown):
plugins:
- vwidref:
id_field: "id"
title_field: "title"
status_field: "status"
progress_field: "progress"
auto_status_field: "auto_status"
auto_progress_1_field: "auto_progress_1"
auto_progress_2_field: "auto_progress_2"
append_hash: true
lowercase_ids: false
debug: false
auto_add_id_comment: true # enable the inline comment feature (default false)
id_key: id # front-matter key for the page ID
title_key: title # front-matter key for the human-readable title
docs_dir: docs # override if your docs live outside the default MkDocs docs_dir
append_hash: append#<id>to the link.lowercase_ids: allow case-insensitive[[id:...]]lookup.debug: verbose transformation logs.auto_status_field: optional derived status (shown with[[id:as:...]]).auto_progress_1_field/auto_progress_2_field: optional derived progress bars (shown with[[id:ap1:...]]and[[id:ap2:...]]).- Progress values below zero render as the empty bar (
:board-progempty:) before rounding. - Generated links pointing to Markdown pages always use the
.mdextension (never.html) and are emitted relative to the current page.
2) Enable custom emoji rendering (Material for MkDocs)
markdown_extensions:
- pymdownx.emoji:
emoji_index: !!python/name:material.extensions.emoji.twemoji
emoji_generator: !!python/name:material.extensions.emoji.to_svg
options:
custom_icons:
- overrides/.icons
Place your SVG icons under
overrides/.icons/board/…so the shortcodes below resolve.
🎨 Custom Emoji Shortcodes
The plugin outputs shortcodes, which the emoji extension renders to SVG. Update your plugin’s icon maps (already set by default) to:
PROGRESS_BARS = {
-1: ":board-progempty:",
0: ":board-progtodo:",
20: ":board-prog20:",
40: ":board-prog70:",
60: ":board-prog60:",
80: ":board-prog80:",
100: ":board-progdone:",
}
STATUS_ICONS = {
"todo": ":board-statustodo:",
"inprogress": ":board-statusinprogress:",
"done": ":board-statusdone:",
"deprecated": ":board-statusdeprecated:",
}
📁 Icon file placement
With the custom_icons path set to overrides/.icons, the shortcode :board-XYZ: resolves to:
overrides/.icons/board/XYZ.svg
Required files for the map above:
overrides/.icons/
└─ board/
├─ progtodo.svg
├─ prog20.svg
├─ prog70.svg
├─ prog60.svg
├─ prog80.svg
├─ progdone.svg
├─ progempty.svg
├─ statustodo.svg
├─ statusinprogress.svg
├─ statusdeprecated.svg
└─ statusdone.svg
You can change filenames / shortcodes — just keep the map and SVG names in sync.
🧭 Authoring
Target page front-matter:
---
id: tm-gp
title: Team – Gameplay
status: inprogress
progress: 63
auto_status: done
auto_progress_1: 80
auto_progress_2: 100
---
# Team – Gameplay
Linking from another page:
[[id:tm-gp]] → tm-gp
[[id:s:tm-gp]] → 🔄
[[id:p:tm-gp]] → 🟨🟨🟨⬛⬛ (63 → rounded to 60)
[[id:t:tm-gp]] → Team – Gameplay
[[id:s:t:tm-gp]] → (🔄) Team – Gameplay
[[id:p:t:tm-gp]] → <🟨🟨🟨⬛⬛> Team – Gameplay
[[id:s:p:t:tm-gp]] → (🔄) <🟨🟨🟨⬛⬛> Team – Gameplay
[[id:s:p:tm-gp]] → (🔄) <🟨🟨🟨⬛⬛> # no title without :t
[[id:as:tm-gp]] → ✅
[[id:ap1:t:tm-gp]] → <🟦🟦🟦🟦⬛> Team – Gameplay
[[id:idt:tm-gp]] → tm-gp Team – Gameplay
[[id:t:test-id#architecture|Arch]] → Arch
!!! note "Custom labels"
A custom label ([[id:s:t:tm-gp|Custom Label]]) is used only when :t is present.
When :idt is present, the label is ignored and the link text becomes <id> <title>.
Without :t, any |Label is ignored (title is suppressed by design).
🔗 Linking to a specific section
You can link directly to a section inside the target page by appending a #fragment after the ID.
[[id:t:test-id#section-id]]
- Finds the page whose front-matter includes
id: test-id. - Links to that page’s
#section-id. - Displays the title (or custom label) because
:tis present.
⚙️ Flags Summary
| Flag | Meaning | Output rule |
|---|---|---|
:s |
Show status | Show status only (no parentheses) if it’s the only item; wrap as (status) if combined. |
:as |
Show auto status | Mirrors :s, but reads from auto_status_field. |
:p |
Show progress | Show bar only (no brackets) if it’s the only item; wrap as <bar> if combined. |
:ap1 |
Show auto progress | Mirrors :p, but reads from auto_progress_1_field. |
:ap2 |
Show auto progress | Mirrors :p, but reads from auto_progress_2_field. |
:t |
Show title | Include title (or custom label). Title appears only when :t is present. |
:idt |
Show id + title | Override label handling; renders "id title" with a single space, even if :t is also supplied. |
:c |
Add/Update the inline comment | for editor |
Combinations
[[id:s:foo]]/[[id:as:foo]]→⏳ / 🔄 / ✅[[id:p:foo]],[[id:ap1:foo]],[[id:ap2:foo]]→ one of⬛⬛⬛⬛⬛,🟧🟧⬛⬛⬛,🟩🟩🟩🟩🟩, etc.[[id:s:t:foo]]→(⏳) Title[[id:p:t:foo]]→<🟧🟧⬛⬛⬛> Title[[id:as:ap1:t:foo]]→(🔄) <🟧🟧⬛⬛⬛> Title[[id:s:p:t:foo]]→(⏳) <🟧🟧⬛⬛⬛> Title[[id:s:p:foo]]→(⏳) <🟧🟧⬛⬛⬛>(no title)[[id:foo]]→foo(raw id string)[[id:idt:foo]]→foo Title
🔢 Status & Progress Mapping
Status → Icon
| Status value | Icon |
|---|---|
todo |
⏳ |
inprogress |
🔄 |
done |
✅ |
deprecated |
🗑️ |
Progress → Bar
Rounded to nearest 0 / 20 / 40 / 60 / 80 / 100 →
| % | Bar |
|---|---|
| <0 | (empty) |
| 0 | ⬛⬛⬛⬛⬛ |
| 20 | 🟥⬛⬛⬛⬛ |
| 40 | 🟧🟧⬛⬛⬛ |
| 60 | 🟨🟨🟨⬛⬛ |
| 80 | 🟦🟦🟦🟦⬛ |
| 100 | 🟩🟩🟩🟩🟩 |
!!! tip
Missing components (no status or progress) are silently skipped.
If nothing remains, the plugin falls back to the raw id.
🔗 How It Links
-
Links point to the page containing the ID, with optional
#<id>anchor. -
Hrefs are emitted as relative
.mdpaths, so the example above becomes:../../01_volworld_portfolio/arts/art-gp_core-gameplay/art-gp.md#art-gpThis keeps generated Markdown portable inside and outside MkDocs.
Auto-append ID comments (editor-friendly)
You can optionally enable an inline comment right after each [[id:...]] token so that, in your editor, you can immediately see what the random-looking ID points to.
Enable
plugins:
- vwidref:
auto_add_id_comment: true # default: false
# optional keys:
# id_key: id
# title_key: title
# docs_dir: docs
What it does
-
On dev server start and after build, scans all Markdown under
docs_dir. -
For every
[[id:SOMETHING]], appends or updates an HTML comment managed by the plugin:-
If the referenced page has a
titlein front matter:[[id:fn_core-loop]] <!-- vwidref-title:Core Loop -->
-
If it has no title:
[[id:sv_audio-pipe]] <!-- vwidref-title:NO title found in front-matter -->
-
-
The comment is only added once per token and is updated automatically if the page title changes (including changes to or from the “NO title…” placeholder).
-
Code fences (
…) are ignored to avoid altering code samples.
Why this helps
- Keep linking by stable IDs for robustness.
- Still see human-readable context right in your editor without opening the target file.
Usage
Write links like:
See [[id:fn_2ae7bf]] for the Echo Fill spec.
With auto_add_id_comment: true, your source will be rewritten on serve/build to:
See [[id:c:fn_2ae7bf]] <!-- vwidref-title:Echo Fill --> for the Echo Fill spec.
If you later rename the target page’s front-matter title to Echo Fill v2, the next run will update the inline comment automatically:
See [[id:c:fn_2ae7bf]] <!-- vwidref-title:Echo Fill v2 --> for the Echo Fill spec.
No comment (and remove any existing managed comment) when :c is not present:
[[id:t:fn_2ae7bf]] -> [[id:t:fn_2ae7bf]]
Configuration
plugins:
- vwidref:
auto_add_id_comment: true # enable the inline comment feature (default false)
id_key: id # front-matter key for the page ID
title_key: title # front-matter key for the human-readable title
docs_dir: docs # override if your docs live outside the default MkDocs docs_dir
The inline comment is identifiable by the prefix
vwidref-title:. Do not hand-edit its contents; the plugin will refresh it on subsequent runs.
Notes
- This feature does not change your linking mechanism; ID-based resolution remains the source of truth.
- It is safe to commit the updated Markdown (recommended for team visibility). If you prefer not to commit, run a local
servebefore editing so the comments show up in your editor.
🩺 Troubleshooting
- Wrong URL → ensure you’re using
mkdocs-vwidref >= 1.0.0. - No replacement → confirm your target page’s front-matter starts at the file top and includes
id:. - No title → you must include
:t. - Case sensitivity → set
lowercase_ids: truefor case-insensitive matches.
🧾 Changelog
1.0.0
- Initial public release.
- Syntax
[[id:s|p|t:...]]with progress rounding, status icons, and relative.mdlinks. - Emoji shortcode support for Material for MkDocs.
📜 License
MIT License © 2025 Gobidesert
Release files for mkdocs-vwidref 1.0.22
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| mkdocs_vwidref-1.0.22.tar.gz | 17.4 kB | Details |
Release files / mkdocs_vwidref-1.0.22.tar.gz
| Download URL | mkdocs_vwidref-1.0.22.tar.gz |
|---|---|
| Size | 17.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
170ed64489a09b3d3ea6f39ccb63b83bca9199ca6851ce3893493786f37ffc77
|
|
BLAKE2b-256 checksum How to use checksums |
ee75cd3eeb8680ec701d7ea631c624464f11afd1f62b0b6e1e338f3a24ace2de
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/3.8.0 colorama/0.4.4 importlib-metadata/4.6.4 keyring/23.5.0 pkginfo/1.8.2 readme-renderer/34.0 requests-toolbelt/0.9.1 requests/2.32.5 rfc3986/1.5.0 tqdm/4.57.0 urllib3/1.26.5 CPython/3.10.12
|