CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-mkdocs-markdownextradata-plugin

A MkDocs plugin that injects the mkdocs.yml extra variables into the markdown template

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

index.mddocs/

MkDocs Markdown Extra Data Plugin

A MkDocs plugin that enables injection of configuration variables and external data files directly into markdown templates during site generation. It allows users to define variables in mkdocs.yml or external YAML/JSON files and reference them in markdown content using Jinja2 template syntax.

Package Information

  • Package Name: mkdocs-markdownextradata-plugin
  • Package Type: pypi
  • Language: Python
  • Installation: pip install mkdocs-markdownextradata-plugin
  • Requirements: Python 3.6+, mkdocs, pyyaml

Core Imports

# Plugin is automatically loaded by MkDocs when configured
# No direct imports needed for basic usage
# Plugin is registered as entry point: 'markdownextradata = markdownextradata.plugin:MarkdownExtraDataPlugin'

Basic Usage

Configure the plugin in your mkdocs.yml:

plugins:
    - search
    - markdownextradata

Define variables in mkdocs.yml:

extra:
  customer:
    name: "Your Company"
    web: "www.example.com"
    version: "1.0.0"

Use variables in markdown files:

# Welcome to {{ customer.name }}

Visit us at: {{ customer.web }}
Current version: {{ customer.version }}

Capabilities

Plugin Configuration

Configure the plugin with custom data sources and Jinja2 options.

class MarkdownExtraDataPlugin(BasePlugin):
    """
    MkDocs plugin for injecting extra variables into markdown templates.
    
    Configuration Schema:
    - data: Optional[str] - Data source folders (comma-separated paths)
    - jinja_options: Optional[Dict] - Jinja2 template engine configuration
    """
    
    config_scheme = (
        ("data", mkdocs.config.config_options.Type(str_type, default=None)),
        ("jinja_options", mkdocs.config.config_options.Type(dict, default={}))
    )
    
    # Python 2/3 compatibility
    # str_type = str (Python 3+) or mkdocs.utils.string_types (Python 2)

Configuration Examples:

# Basic configuration
plugins:
    - markdownextradata

# With custom data directory
plugins:
    - markdownextradata:
        data: path/to/datafiles

# With multiple data directories
plugins:
    - markdownextradata:
        data: path/to/datafiles, another/path/to/datafiles

# With custom Jinja2 options
plugins:
    - markdownextradata:
        jinja_options:
          comment_start_string: "__CUSTOMCOMMENTSTART__"
          variable_start_string: "<<"
          variable_end_string: ">>"

Data Loading and Processing

Automatically loads data from configured sources and processes external files during the pre-build phase.

def on_pre_build(self, config, **kwargs):
    """
    Load data from configured directories or default _data folders.
    
    Args:
        config: mkdocs configuration object
        **kwargs: Additional keyword arguments from MkDocs
    
    Data Processing:
    1. Parse comma-separated data paths from 'data' config option
    2. Convert relative paths to absolute paths based on config file location
    3. If no data paths configured, search default locations:
       - {config_file_dir}/_data
       - {docs_dir}/_data
    4. Load all .yml, .yaml, .json files recursively
    5. Create namespaced variables based on file path structure
    
    Supported file formats: .yml, .yaml, .json
    Namespace mapping: File path becomes variable namespace
    """

Default Data Locations:

  • ./docs/_data/ (relative to mkdocs.yml)
  • ./_data/ (in project root)

File-to-Namespace Mapping:

  • _data/site.yaml{{ site.variable }}
  • _data/sections/captions.yaml{{ sections.captions.variable }}
  • _data/1_example/data.yaml{{ extra['1_example']['data']['variable'] }}

Template Rendering

Applies Jinja2 template substitution to markdown content and page titles.

def on_page_markdown(self, markdown, page, **kwargs):
    """
    Apply template substitution to page content and title.
    
    Args:
        markdown: str - Raw markdown content
        page: mkdocs.structure.pages.Page - Page object
        
    Returns:
        str: Processed markdown with variables substituted
    """

def apply_template(self, template_string):
    """
    Apply Jinja2 substitution to specified string.
    
    Args:
        template_string: str - String containing Jinja2 template syntax
        
    Returns:
        str: Processed string with variables substituted
        
    Template Context:
        - All mkdocs config variables (site_name, site_author, etc.)
        - All extra variables from mkdocs.yml
        - All loaded data from external files
        
    Raises:
        jinja2.exceptions.TemplateSyntaxError: When template syntax is invalid.
            Displays helpful error message suggesting use of 'extra' dictionary
            for non-Python-compliant variable names.
    """

Configuration Initialization

Initializes the Jinja2 environment with custom options and prepares the MkDocs configuration.

def on_config(self, mkdocsConfig, **kwargs):
    """
    Initialize Jinja2 environment and store MkDocs configuration.
    
    Args:
        mkdocsConfig: mkdocs.config.Config - MkDocs configuration object
        
    Sets up:
    - Jinja2.Environment with DebugUndefined and custom options
    - Access to mkdocs config and extra variables
    """

Variable Access Patterns

Direct Access

Variables defined in mkdocs.yml extra section:

extra:
  site_name: "My Site"
  author: "John Doe"
Site: {{ site_name }}
Author: {{ author }}

Namespaced Access

External data files create namespaced variables:

# _data/company/info.yaml
name: "ACME Corp"
founded: 2020
Company: {{ company.info.name }}
Founded: {{ company.info.founded }}

Dictionary Access

For non-Python-compliant names or safe access:

<!-- For files/folders starting with numbers or containing special characters -->
Value: {{ extra['1_example']['data']['key'] }}

<!-- Alternative access for any variable -->
Site: {{ extra['site_name'] }}

Error Handling

The plugin provides helpful error messages for common issues:

# Template syntax errors with guidance  
jinja2.exceptions.TemplateSyntaxError:
    "ERROR\t-  markdownextradata - One or more yaml files might not comply with "
    "Python's variable naming conventions. Try accessing the variable through the "
    "'extra' dictionary. Check the README for more information."

Common Error Scenarios:

  • Invalid YAML/JSON syntax in data files
  • Non-Python-compliant variable names (use dictionary access)
  • Missing data files or directories (silently ignored)
  • Jinja2 template syntax errors in markdown

Data File Formats

YAML Files (.yml, .yaml)

# _data/config.yaml
api:
  base_url: "https://api.example.com"
  version: "v1"
  endpoints:
    users: "/users"
    posts: "/posts"

Usage: {{ config.api.base_url }}

JSON Files (.json)

// _data/settings.json
{
  "theme": {
    "colors": {
      "primary": "#007acc",
      "secondary": "#f0f0f0"
    },
    "fonts": ["Arial", "Helvetica"]
  }
}

Usage: {{ settings.theme.colors.primary }}

Advanced Configuration

Custom Jinja2 Options

Configure Jinja2 template engine delimiters and behavior:

plugins:
    - markdownextradata:
        jinja_options:
          # Comment delimiters
          comment_start_string: "/*"
          comment_end_string: "*/"
          # Variable delimiters  
          variable_start_string: "[["
          variable_end_string: "]]"
          # Block delimiters
          block_start_string: "{%"
          block_end_string: "%}"
          # Undefined behavior
          undefined: "jinja2.StrictUndefined"

Multiple Data Sources

Organize data across multiple directories:

plugins:
    - markdownextradata:
        data: "shared/_data, project/_data, client/_data"

Processing Order:

  1. Comma-separated paths are converted to absolute paths relative to mkdocs.yml location
  2. Each directory is processed recursively using pathlib.Path.glob("**/*.{yaml,yml,json}")
  3. File namespace derived from relative path: os.path.splitext(os.path.relpath(filename, ds_folder))[0]
  4. Data added to config under ["extra"] + namespace.split(os.sep) hierarchy
  5. Later paths can override earlier paths for same namespace

Types

# Python version compatibility
import sys
if sys.version_info[0] >= 3:
    str_type = str
else:
    str_type = mkdocs.utils.string_types

# Configuration constants
CONFIG_KEYS = [
    "site_name", 
    "site_author", 
    "site_url", 
    "repo_url", 
    "repo_name"
]

# Plugin class with configuration
class MarkdownExtraDataPlugin(BasePlugin):
    """MkDocs plugin for injecting extra variables into markdown templates."""
    
    JINJA_OPTIONS = "jinja_options"
    
    config_scheme = (
        ("data", mkdocs.config.config_options.Type(str_type, default=None)),
        (JINJA_OPTIONS, mkdocs.config.config_options.Type(dict, default={}))
    )
    
    # Instance attributes set during plugin lifecycle
    env: jinja2.Environment  # Set in on_config
    mkdocsConfig: mkdocs.config.Config  # Set in on_config

docs

index.md

tile.json