# Custom Directives

> Comprehensive guide to all custom markdown directives available

**Site index:** [https://boilerplate.2plot.dev/llms.txt](https://boilerplate.2plot.dev/llms.txt) — every page on this site, as Markdown.  
**Network index:** [https://2plot.dev/llms.txt](https://2plot.dev/llms.txt) — The 2plot network; start here to discover sibling sites.  
**Sibling sites:** 8 more in The 2plot network — listed in the site index above.  
**Sitemap:** https://boilerplate.2plot.dev/sitemap.xml  


---

.. llms_copy::Custom Directives

.. toc::

### Introduction

This documentation boilerplate comes with **powerful custom directives** that extend standard markdown with interactive features. Directives are special commands that let you embed Python components, display source code, generate tables of contents, and more.

All directives use the syntax: `.. directive_name::optional_argument`

---

### Available Directives

#### 1. Table of Contents - `.. toc::`
#### 2. Execute Python - `.. exec::`
#### 3. Source Code Display - `.. source::`
#### 4. Component Props - `.. kwargs::`
#### 5. LLM Copy Button - `.. llms_copy::`

---

### 1. Table of Contents Directive

The `.. toc::` directive automatically generates a navigable table of contents from your markdown headings.

#### Usage

Simply add `.. toc::` anywhere in your markdown (typically at the top):

```markdown
.. toc::

### Section 1
Content...

### Section 2
Content...

#### Subsection 2.1
More content...
```

#### Features

- **Auto-generates** from H2 and H3 headings
- **Clickable links** that scroll to sections
- **Hierarchical structure** showing document organization
- **Automatically updates** when you add new sections

#### Example

The table of contents at the top of this page was generated using `.. toc::`!

---

### 2. Execute Python Directive

The `.. exec::` directive embeds interactive Dash components from Python modules.

#### Usage

```markdown
.. exec::docs.module.submodule
```

This imports and renders the `component` variable from the specified module path.

#### How It Works

1. Create a Python file (e.g., `docs/directives/button_example.py`)
2. Define a `component` variable with your Dash component
3. Reference it in markdown with `.. exec::docs.directives.button_example`

#### Example: Simple Button

**Markdown:**
```markdown
.. exec::docs.directives.button_example
```

**Python file** (`docs/directives/button_example.py`):
```python
import dash_mantine_components as dmc

component = dmc.Button(
    "Click me!",
    variant="filled",
    color="teal"
)
```

**Result:**

.. exec::docs.directives.button_example

---

### 3. Source Code Display Directive

The `.. source::` directive displays syntax-highlighted source code from files.

#### Usage

```markdown

<!-- Error: File not found: path/to/file.py -->

```

#### Features

- **Syntax highlighting** for Python code
- **Line numbers** for easy reference
- **Copy-to-clipboard** functionality (if enabled)
- **Clean formatting** with proper indentation

#### Example: Display Source

Let's display the source code of the button example we just saw:

**Markdown:**
```markdown

```python
# File: docs/directives/button_example.py

import dash_mantine_components as dmc

# Simple button example for directive showcase
component = dmc.Button(
    "Click me!",
    variant="filled",
    color="teal",
    size="md"
)
```

```

**Result:**


```python
# File: docs/directives/button_example.py

import dash_mantine_components as dmc

# Simple button example for directive showcase
component = dmc.Button(
    "Click me!",
    variant="filled",
    color="teal",
    size="md"
)
```


---

### 4. Component Props Directive

The `.. kwargs::` directive auto-generates a documentation table for component properties.

#### Usage

```markdown
.. kwargs::ComponentName
```

For Dash Mantine Components:
```markdown
.. kwargs::dmc.Button
.. kwargs::dmc.TextInput
.. kwargs::dmc.Select
```

#### Features

- **Automatic extraction** of component properties
- **Type information** for each prop
- **Default values** when available
- **Descriptions** of what each prop does

#### Example: Button Props

**Markdown:**
```markdown
.. kwargs::dmc.Button
```

**Result:**

.. kwargs::dmc.Button

---

### 5. LLM Copy Button Directive

The `.. llms_copy::` directive adds a button that copies the page's `/llms.txt` URL to the clipboard, making it easy for users to share documentation with AI assistants like ChatGPT or Claude.

#### Usage

```markdown
.. llms_copy::Page Title
```

The page title should match the `name` field in your page's frontmatter.

#### Features

- **One-click copying** of the page's llms.txt URL
- **Visual feedback** showing when URL is copied
- **Works in all browsers** with fallback for non-HTTPS contexts
- **AI-friendly** - users can paste the URL into ChatGPT, Claude, or other AI assistants
- **Automatic URL detection** - constructs the correct URL based on current page

#### Example

At the top of this page, you'll see a "Copy for llm 📋" button. Clicking it copies a URL like:

```
http://your-site.com/examples/directives/llms.txt
```

Users can then paste this URL into ChatGPT or Claude with a prompt like:

```
"Can you help me understand this documentation? http://your-site.com/examples/directives/llms.txt"
```

The AI assistant will fetch the page's markdown content and can provide context-aware help.

#### When to Use

Place this directive at the top of documentation pages where users might want AI assistance:

```markdown
---
name: My Component
description: Complex component documentation
endpoint: /components/my-component
---

.. llms_copy::My Component

.. toc::

### Overview
...
```

#### Benefits for Users

- **Quick AI help** - Share documentation with AI assistants instantly
- **Better context** - AI gets the full page content in markdown format
- **No copy-paste** - URL copying is more reliable than copying page content
- **Future-proof** - Works with any AI that can fetch URLs

---

### Interactive Examples with Callbacks

You can create fully interactive examples with callbacks using the `.. exec::` directive.

#### Example: Counter

Here's an interactive counter that demonstrates callbacks:

.. exec::docs.directives.counter_example
    :code: false

The source code:


```python
# File: docs/directives/counter_example.py

from dash import html, callback, Input, Output, State
import dash_mantine_components as dmc
from dash_iconify import DashIconify

# Interactive counter example with callbacks
component = html.Div([
    dmc.Title("Interactive Counter", order=4, mb=10),
    dmc.Group([
        dmc.Button(
            "Increment",
            id="increment-btn",
            variant="filled",
            color="teal",
            leftSection=DashIconify(icon="mdi:plus-circle")
        ),
        dmc.Button(
            "Decrement",
            id="decrement-btn",
            variant="filled",
            color="red",
            leftSection=DashIconify(icon="mdi:minus-circle")
        ),
        dmc.Button(
            "Reset",
            id="reset-btn",
            variant="light",
            color="gray"
        ),
    ], gap="sm", mb=15),
    dmc.Paper([
        dmc.Text("Current Count:", size="sm", c="dimmed"),
        dmc.Title(
            "0",
            id="counter-display",
            order=2,
            c="teal"
        )
    ], p="md", withBorder=True, radius="md")
])


@callback(
    Output("counter-display", "children"),
    Input("increment-btn", "n_clicks"),
    Input("decrement-btn", "n_clicks"),
    Input("reset-btn", "n_clicks"),
    State("counter-display", "children"),
    prevent_initial_call=True
)
def update_counter(inc_clicks, dec_clicks, reset_clicks, current):
    from dash import ctx

    current_value = int(current) if current else 0

    button_id = ctx.triggered_id

    if button_id == "increment-btn":
        return str(current_value + 1)
    elif button_id == "decrement-btn":
        return str(current_value - 1)
    elif button_id == "reset-btn":
        return "0"

    return current
```


---

### Complex Example: Form with Validation

Let's create a more complex example with form inputs and validation:

.. exec::docs.directives.form_example
    :code: false
Source code for this example:


```python
# File: docs/directives/form_example.py

from dash import html, callback, Input, Output, State, ALL
import dash_mantine_components as dmc
from dash_iconify import DashIconify

# Form validation example
component = html.Div([
    dmc.Title("User Registration Form", order=4, mb=10),
    dmc.Stack([
        dmc.TextInput(
            label="Full Name",
            placeholder="Enter your full name",
            id="form-name",
            required=True,
            leftSection=DashIconify(icon="mdi:account")
        ),
        dmc.TextInput(
            label="Email",
            placeholder="your.email@example.com",
            id="form-email",
            required=True,
            leftSection=DashIconify(icon="mdi:email")
        ),
        dmc.PasswordInput(
            label="Password",
            placeholder="Enter password",
            id="form-password",
            required=True,
            leftSection=DashIconify(icon="mdi:lock")
        ),
        dmc.Select(
            label="Country",
            placeholder="Select your country",
            id="form-country",
            data=[
                {"label": "United States", "value": "us"},
                {"label": "United Kingdom", "value": "uk"},
                {"label": "Canada", "value": "ca"},
                {"label": "Australia", "value": "au"},
                {"label": "Germany", "value": "de"},
            ],
            leftSection=DashIconify(icon="mdi:earth")
        ),
        dmc.Checkbox(
            label="I agree to the terms and conditions",
            id="form-terms",
        ),
        dmc.Group([
            dmc.Button(
                "Submit",
                id="form-submit-btn",
                variant="filled",
                color="teal",
                fullWidth=True
            ),
        ]),
        dmc.Paper(
            id="form-output",
            p="md",
            withBorder=True,
            radius="md",
            style={"display": "none"}
        )
    ], gap="sm")
])


@callback(
    Output("form-output", "children"),
    Output("form-output", "style"),
    Input("form-submit-btn", "n_clicks"),
    State("form-name", "value"),
    State("form-email", "value"),
    State("form-password", "value"),
    State("form-country", "value"),
    State("form-terms", "checked"),
    prevent_initial_call=True
)
def validate_form(n_clicks, name, email, password, country, terms):
    errors = []

    if not name or len(name.strip()) < 2:
        errors.append("Name must be at least 2 characters")

    if not email or "@" not in email:
        errors.append("Please enter a valid email")

    if not password or len(password) < 6:
        errors.append("Password must be at least 6 characters")

    if not country:
        errors.append("Please select a country")

    if not terms:
        errors.append("You must agree to the terms and conditions")

    if errors:
        return [
            dmc.Alert(
                title="Validation Errors",
                color="red",
                children=[
                    html.Ul([html.Li(error) for error in errors])
                ]
            )
        ], {"display": "block"}

    return [
        dmc.Alert(
            title="Success!",
            color="teal",
            children=f"Welcome, {name}! Your account has been created."
        )
    ], {"display": "block"}
```


---

### Combining Directives

The real power comes from **combining multiple directives** in one documentation page:

#### Pattern 1: Show Code & Result

```markdown
### My Feature

Description of the feature...

#### Interactive Demo

.. exec::docs.my-feature.demo

#### Source Code


<!-- Error: File not found: docs/my-feature/demo.py -->

```

#### Pattern 2: Documentation with Props

```markdown
### Component API

#### Example Usage

.. exec::docs.component.example

#### Component Properties

.. kwargs::MyComponent

#### Full Source


<!-- Error: File not found: docs/component/example.py -->

```

#### Pattern 3: Comprehensive Page

```markdown
---
name: My Component
description: Full documentation
endpoint: /components/my-component
---

.. toc::

### Overview
Description...

### Basic Example
.. exec::docs.component.basic

<!-- Error: File not found: docs/component/basic.py -->


### Advanced Example
.. exec::docs.component.advanced

<!-- Error: File not found: docs/component/advanced.py -->


### API Reference
.. kwargs::MyComponent

### Related Components
Links to other docs...
```

---

### Best Practices

#### 1. Use Meaningful Module Names

✅ Good:
```markdown
.. exec::docs.buttons.primary_button_example
```

❌ Bad:
```markdown
.. exec::docs.ex1
```

#### 2. Show Code and Result Together

Always pair `.. exec::` with `.. source::` so users can see both the result and how it's made:

```markdown
.. exec::docs.component.example

<!-- Error: File not found: docs/component/example.py -->

```

#### 3. Add Context with Markdown

Explain what the example demonstrates before showing it:

```markdown
This example demonstrates how to handle form validation:

.. exec::docs.forms.validation_example
```

#### 4. Use Table of Contents for Long Pages

For documentation pages with multiple sections, always include:

```markdown
.. toc::
```

#### 5. Document Component Props

When documenting a new component, include the props table:

```markdown
.. kwargs::YourComponent
```

---

### Advanced Tips

#### Organizing Python Examples

Keep your Python examples organized by feature:

```text
docs/
├── buttons/
│   ├── buttons.md
│   ├── basic_button.py
│   ├── icon_button.py
│   └── loading_button.py
├── forms/
│   ├── forms.md
│   ├── text_input.py
│   ├── select.py
│   └── validation.py
```

#### Reusing Components

You can reference the same Python component from multiple markdown files:

```markdown
# In docs/examples/page1.md
.. exec::docs.shared.common_example

# In docs/examples/page2.md
.. exec::docs.shared.common_example
```

#### Error Handling

If a directive fails to render:

1. Check the module path is correct
2. Ensure the Python file has a `component` variable
3. Check for syntax errors in your Python code
4. Look at the server logs for detailed error messages

---

### Directive Reference

#### Quick Reference Table

| Directive | Syntax | Purpose |
|-----------|--------|---------|
| `toc` | `.. toc::` | Generate table of contents |
| `exec` | `.. exec::module.path` | Render Python component |
| `source` | `.. source::file/path.py` | Display source code |
| `kwargs` | `.. kwargs::ComponentName` | Show component props |
| `llms_copy` | `.. llms_copy::Page Title` | Add AI-friendly copy button |

---

### Next Steps

- **Interactive Components** - Learn advanced callback patterns
- **Data Visualization** - Create beautiful charts and graphs
- **AI Integration** - Make your docs AI-friendly

---

### Need Help?

If you're having trouble with directives:

1. Check the Python module path is correct (use dots, not slashes)
2. Ensure your Python file exports a `component` variable
3. Look for syntax errors in your code
4. Check the terminal for error messages

For more help, visit the [GitHub Issues](https://github.com/pip-install-python/Dash-Documentation-Boilerplate/issues).


---

*Source: /examples/directives*
