An MkDocs plugin that allows linking to files by filename only
Project description
MkDocs EasyLinks Plugin
An MkDocs plugin that allows you to create cross-references and embed images by specifying only the filename, without needing to know the full path.
Features
- Simple linking: Reference any file in your docs with just its filename
- Image support: Embed images using simple filenames like
 - Automatic resolution: The plugin finds the file and generates the correct relative path
- Glob patterns: Use wildcards to ignore multiple files (e.g.,
draft-*.md,*.tmp) - Directory exclusion: Exclude entire directories from being indexed
- Link statistics: See which files are most linked and find orphaned content
- Ambiguity warnings: Get notified if multiple files share the same name
- Material for MkDocs compatible: Works seamlessly with Material theme
- Smart protection: Code fences and HTML comments are preserved unchanged
Installation
pip install mkdocs-easylinks-plugin
Or install directly from source:
pip install -e .
Usage
Add the plugin to your mkdocs.yml:
plugins:
- search
- easylinks
Configuration Options
plugins:
- easylinks:
warn_on_missing: true # Warn when a file can't be found (default: true)
warn_on_ambiguous: true # Warn when multiple files have the same name (default: true)
ignore_files: [] # List of filenames/patterns to ignore (default: [])
exclude_dirs: [] # List of directories to exclude (default: [])
show_stats: false # Show link statistics after build (default: false)
Available Options
warn_on_missing(bool, default:true): Show warnings when a linked file cannot be foundwarn_on_ambiguous(bool, default:true): Show warnings when multiple files share the same nameignore_files(list, default:[]): List of filenames/patterns to exclude from link resolution (supports glob patterns)exclude_dirs(list, default:[]): List of directories to exclude completelyshow_stats(bool, default:false): Display link statistics after the build completes
Ignoring Specific Files
Use ignore_files to exclude certain files. Supports both exact matches and glob patterns:
plugins:
- easylinks:
ignore_files:
- draft.md # Exact match
- template.md # Exact match
- "draft-*.md" # Glob pattern - all files starting with "draft-"
- "*.tmp" # Glob pattern - all .tmp files
- "test_*" # Glob pattern - all files starting with "test_"
Excluding Directories
Use exclude_dirs to exclude entire directories:
plugins:
- easylinks:
exclude_dirs:
- drafts/
- templates/
- .archive/
All files in these directories (and subdirectories) will be excluded from indexing.
Note: Directory paths are matched as prefixes against each file's path within the docs directory. This means
exclude_dirs: ["api"]excludesapi/page.mdbut notdocs/api/page.md. To exclude a nested directory, specify the full path from the docs root:exclude_dirs: ["docs/api"].
Link Statistics
Enable show_stats to see detailed statistics after your build:
plugins:
- easylinks:
show_stats: true
This will display:
- Files scanned and indexed
- Links processed, resolved, and unresolved
- Images processed, resolved, and unresolved
- Most frequently linked files
- Orphaned files (indexed but never linked)
Examples
Documentation Links
Instead of writing:
[See the guide](../../advanced/guides/configuration.md)
You can now write:
[See the guide](configuration.md)
The plugin will automatically resolve configuration.md to its full path and generate the correct relative link.
Images
Works with images too! Instead of:

Just write:

With Anchors
Anchors work for document links:
[See section](somefile.md#advanced-features)
What Links Are Processed
Processed (converted to full paths):
[text](filename.md)- Simple document filenames[text](file.md#anchor)- Document filenames with anchors- Simple image filenames (png, jpg, svg, gif, etc.)
Not processed (left as-is):
[text](https://example.com)- External URLs- External images[text](/absolute/path.md)- Absolute paths[text](../relative/path.md)- Explicit relative paths with directories[text](#anchor)- Fragment-only links- Links/images inside code fences (
```or~~~) - Links/images inside HTML comments (
<!-- -->)
Protected Content
The plugin intelligently ignores links in:
Code fences:
```python
# This [link](example.md) won't be processed
```
HTML comments:
<!-- This [link](example.md) won't be processed -->
This ensures that example code and commented-out content remain unchanged.
Important: Indented Content
Only explicit code fences (``` or ~~~) are protected. Indented content, such as in MkDocs admonitions, is processed normally:
!!! note
This [link](guide.md) WILL be processed.
The plugin works inside admonitions!
This design choice ensures the plugin works seamlessly with MkDocs features like admonitions, which rely heavily on indentation.
How It Works
- During the build, the plugin scans all files (documentation, images, assets, etc.)
- It creates a mapping of filenames to their full paths
- When processing each page, it finds markdown links and images with simple filenames
- It replaces them with the correct relative path from the current page to the target
Files that are excluded from mapping:
- Files starting with
.(dotfiles) - always ignored - Files listed in
ignore_filesconfiguration - useful for drafts and templates
Using with mkdocs-macros-plugin (Snippets)
If you use mkdocs-macros-plugin to include snippet files via {% include '...' %}, easylinks works correctly with no extra configuration — as long as the plugin order in mkdocs.yml is correct:
plugins:
- macros:
include_dir: docs/.snippets
- easylinks # must come after macros
Because macros runs first, snippet content is inlined into the page before easylinks processes it. Links in snippets are resolved relative to the including page, not the snippet file itself — which is exactly the right behaviour when a snippet may be included from pages at different directory levels.
Best practices:
- Always list
easylinksaftermacrosin yourpluginsconfiguration. - Use simple filename links (e.g.
[text](target.md)) in your snippets rather than relative paths, since relative paths would break when the same snippet is included from different locations. - If your snippets directory could contain files whose names clash with published docs files, add it to
exclude_dirsto prevent false ambiguity warnings:
plugins:
- easylinks:
exclude_dirs: ['.snippets']
Handling Ambiguous Filenames
If you have multiple files with the same name (e.g., index.md in different folders), the plugin will:
- Warn you about the ambiguity
- Use the first occurrence found
- Recommend using full paths for those specific files
Development
Setup
# Clone the repository
git clone https://github.com/dsferg/mkdocs-easylinks-plugin.git
cd mkdocs-easylinks-plugin
# Install in development mode
pip install -e ".[dev]"
Running Tests
pytest
License
MIT License - See LICENSE file for details
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
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
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 mkdocs_easylinks_plugin-0.1.2.tar.gz.
File metadata
- Download URL: mkdocs_easylinks_plugin-0.1.2.tar.gz
- Upload date:
- Size: 17.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0d7129954a0444efe6b64166009fb97884e9451e6e00b8983468fe7cb0cfa791
|
|
| MD5 |
4dc643053779eae2683f94ce454c2274
|
|
| BLAKE2b-256 |
b3cdbdb4673b3e6ff44348e2b9e0ad33ad28278583341c38122f0c48fc07b218
|
File details
Details for the file mkdocs_easylinks_plugin-0.1.2-py3-none-any.whl.
File metadata
- Download URL: mkdocs_easylinks_plugin-0.1.2-py3-none-any.whl
- Upload date:
- Size: 9.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dedf4c4d9507618bddd97a28fa4cb56a1442ee5f06bb2c08b250b6e6dcae3977
|
|
| MD5 |
e6f63b262be0bd99992c1c1b2ef5e9ab
|
|
| BLAKE2b-256 |
bedd1fade7237a6fb577377437c5725f20c91be536ffd54e412f88792656e056
|