Bookmark list component for mkdocs-materialx, with search, tag filtering and pagination
Project description
materialx-bookmarks
A bookmark list component for mkdocs-materialx. Write your links in YAML, drop one fence into any page, and readers get search, tag filtering, sorting and pagination — no JavaScript to write, no database, no build step of your own.
🔖 Try the live demo →
Search for a typo'd name, stack two tag filters, flip the order, page through — then copy the address bar and see the whole view come back.
| Light | Dark |
|---|---|
Why
Documentation sites accumulate link lists. Written as plain Markdown they turn into a wall of bullets nobody can search, and keeping them tidy means editing prose. This plugin keeps the data in YAML and the presentation in the theme:
| 🔍 Fuzzy search | Powered by Fuse.js, tolerant of typos, weighted toward titles |
| 🏷️ Tag filtering | Multi-select, AND semantics, live counts, allowlisted to catch typos at build time |
| ↕️ Sorting | Your YAML order, or reversed |
| 📄 Pagination | Numbered, configurable page size |
| 🔗 Shareable state | Every view is a URL — search, tags, sort and page all round-trip |
| 🧩 Anywhere on any page | Mid-article, several per page, as many collections as you like |
| 🎨 Themed automatically | Styled entirely with the theme's own CSS variables — light, dark and your accent colour |
| ✅ Validated at build time | A typo'd tag or an unknown collection fails the build, not the page |
| 🌍 Translated | English and Turkish included, one file to add your own |
Quick start
1. Install
pip install materialx-bookmarks
2. Write some bookmarks
Create bookmarks/reading.yml next to your mkdocs.yml:
tags:
- python
- rust
bookmarks:
- title: Ruff
url: https://docs.astral.sh/ruff/
description: Linter and formatter for Python, written in Rust.
tags: [python, rust]
- title: ripgrep
url: https://github.com/BurntSushi/ripgrep
description: Recursively searches directories for a regex pattern.
tags: [rust]
3. Register the collection
plugins:
- materialx-bookmarks:
collections:
- name: reading
file: bookmarks/reading.yml
4. Drop it on a page
# My reading list
Things worth coming back to.
```bookmarks
collection: reading
```
That's it. mkdocs serve, and editing the YAML live-reloads the page.
Reference
Bookmark files
tags: [python, rust] # allowlist — a bookmark may only use tags listed here
bookmarks:
- title: Ruff # the only required field
url: https://… # optional — without it the entry renders as plain text
description: … # optional
tags: [python] # optional
Bookmarks appear in the order you write them. The tags allowlist is what turns a misspelled tag
into a build error instead of a chip nobody ever clicks.
Plugin options
plugins:
- materialx-bookmarks:
language: en
collections:
- name: reading
file: bookmarks/reading.yml
per_page: 20
| Option | Required | Default | Description |
|---|---|---|---|
language |
no | theme.language, else en |
Language for the interface strings |
collections[].name |
yes | — | The name pages refer to. Must be unique |
collections[].file |
yes | — | Path to the YAML file, relative to mkdocs.yml. Keep it outside docs/ so it is not copied into the built site |
collections[].per_page |
no | 20 |
Bookmarks per page |
Placing components
A page may hold as many components as you like. Give a fence an id when two of them would
otherwise collide:
```bookmarks
collection: reading
id: reading-secondary
```
| Key | Required | Description |
|---|---|---|
collection |
yes | Name of a collection from mkdocs.yml |
id |
no | Defaults to the collection name. Namespaces this component's URL parameters |
URL state
Every control writes to the address bar, namespaced by component id, so a filtered view can be linked to and returns intact:
?reading.q=ruff&reading.tags=python,rust&reading.sort=reversed&reading.page=2
How it works
At build time the plugin reads your YAML, validates it, and writes one JSON file per collection into the site. Each fence becomes an empty container carrying its configuration. Anything wrong — a missing file, a bookmark without a title, a tag outside the allowlist, a fence naming a collection that does not exist — stops the build with a message naming the file and the entry.
In the browser a small bundle (about 30 KB including Fuse.js) fetches that JSON once per collection and renders the list. Assets are emitted under content-hashed filenames, so upgrading the plugin never leaves a visitor on a stale bundle.
Controls are real buttons with aria-pressed, the search box is labelled, the result count is a
live region, and pagination sits in a landmark nav — all of it keyboard reachable.
Languages
English (en) and Turkish (tr) ship with the plugin, and the language follows your
theme.language unless you set one. Adding another is a single file — see
CONTRIBUTING.md.
Requirements
Python 3.10+, MkDocs 1.5+, and the mkdocs-materialx theme.
Contributing
Tests, the demo site and the release workflow are described in CONTRIBUTING.md.
License
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 materialx_bookmarks-0.1.0.tar.gz.
File metadata
- Download URL: materialx_bookmarks-0.1.0.tar.gz
- Upload date:
- Size: 31.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
450904afe0b8cd02cc4bcc8af0052722fbebaf22270037be00569c256f88f18a
|
|
| MD5 |
bcf22fc7d98a7e2cf347b0b8e2b5e8d0
|
|
| BLAKE2b-256 |
cc2969279aa3377c825b7faa88db9689e018e08816301d5f6b29e52f445ea28d
|
Provenance
The following attestation bundles were made for materialx_bookmarks-0.1.0.tar.gz:
Publisher:
release.yml on berk-karaal/materialx-bookmarks
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
materialx_bookmarks-0.1.0.tar.gz -
Subject digest:
450904afe0b8cd02cc4bcc8af0052722fbebaf22270037be00569c256f88f18a - Sigstore transparency entry: 2314417656
- Sigstore integration time:
-
Permalink:
berk-karaal/materialx-bookmarks@1dfc4c19a2cc5684e27ebefb018b2e1fea60670a -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/berk-karaal
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@1dfc4c19a2cc5684e27ebefb018b2e1fea60670a -
Trigger Event:
release
-
Statement type:
File details
Details for the file materialx_bookmarks-0.1.0-py3-none-any.whl.
File metadata
- Download URL: materialx_bookmarks-0.1.0-py3-none-any.whl
- Upload date:
- Size: 24.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4ad6001dcd31c40957a9ed68f9f1402ff64d51bbf7e4e529e3f58c39ebe4cd27
|
|
| MD5 |
dc192d276ce720646eb94aef3c8daa28
|
|
| BLAKE2b-256 |
432e842124b63292d73f901ab0b56838ff20437a39a117f72c949c8bfc3aff1d
|
Provenance
The following attestation bundles were made for materialx_bookmarks-0.1.0-py3-none-any.whl:
Publisher:
release.yml on berk-karaal/materialx-bookmarks
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
materialx_bookmarks-0.1.0-py3-none-any.whl -
Subject digest:
4ad6001dcd31c40957a9ed68f9f1402ff64d51bbf7e4e529e3f58c39ebe4cd27 - Sigstore transparency entry: 2314417694
- Sigstore integration time:
-
Permalink:
berk-karaal/materialx-bookmarks@1dfc4c19a2cc5684e27ebefb018b2e1fea60670a -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/berk-karaal
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@1dfc4c19a2cc5684e27ebefb018b2e1fea60670a -
Trigger Event:
release
-
Statement type: