Go beyond basic Markdown. This track covers directives (callouts, tabs, cards), content reuse (snippets, includes), and variable substitution.

Tip

Duration: ~60 min | Prerequisite: Zero to Deployed or equivalent

1

Content Authoring

Markdown, MyST directives, and shortcodes

Writing Content

Bengal uses CommonMark Markdown with MyST extensions for rich documentation.

Quick Reference

1
2
3
**bold** and *italic*
~~strikethrough~~
`inline code`
1
2
3
[External](https://example.com)
[Internal](/docs/get-started/)
[Relative](../other-page/)
1
2
![Alt text](/images/hero.jpg)
![With title](/images/hero.jpg "Title")
1
2
3
4
```python
def hello():
    print("Hello!")
```

With line highlighting:

1
2
3
4
```python {hl_lines="2"}
def hello():
    print("Highlighted!")
```

MyST Directives

Directives add rich components to your Markdown:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
:::{note}
Informational callout.
:::

:::{warning}
Important warning!
:::

:::{tip}
Helpful suggestion.
:::
1
2
3
4
5
6
7
8
:::{tab-set}
:::{tab} Python
print("Hello")
:::{/tab}
:::{tab} JavaScript
console.log("Hello")
:::{/tab}
:::{/tab-set}
1
2
3
4
5
6
:::{cards}
:::{card} Title
:link: ./path/
Description here
:::{/card}
:::{/cards}
1
2
3
4
5
:::{dropdown} Click to expand
:icon: info

Hidden content here.
:::
1
2
3
4
5
6
7
8
:::{youtube} dQw4w9WgXcQ
:title: Video Title
:::

:::{figure} /images/diagram.png
:alt: Architecture diagram
:caption: System overview
:::

Syntax Overview

flowchart LR A[Markdown] --> B[MyST Parser] B --> C{Directive?} C -->|Yes| D[Render Component] C -->|No| E[Render HTML] D --> F[Final Page] E --> F

Tip

Most common: Admonitions (note,warning,tip) and code blocks with syntax highlighting. Start there, add tabs and cards as needed. For visual elements, see the Icon Reference for inline SVG icons.

Variable Substitution

Use{{ variable }}syntax to insert frontmatter values directly into your content:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
---
product_name: Bengal
version: 1.0.0
beta: true
---

Welcome to **{{ product_name }}** version {{ version }}.

{% if beta %}
:::{warning}
This is a beta release.
:::
{% endif %}

Available Variables

Variable Source Example
{{ page.title }} Current page {{ page.title }}
{{ page.description }} Current page {{ page.description }}
{{ product_name }} Frontmatter Direct access to any frontmatter key
{{ params.key }} Frontmatter Hugo-style access viaparams
{{ site.title }} Site config {{ site.title }}
{{ config.baseurl }} Site config {{ config.baseurl }}

Cascaded Variables

Variables cascade from parent sections. Set them once in a section's_index.md:

1
2
3
4
5
6
7
# docs/api/_index.md
---
title: API Reference
cascade:
  api_version: v2
  deprecated: false
---

Then use in any child page:

1
2
# docs/api/users.md
This endpoint uses API {{ api_version }}.

Tip

Common use cases: Product names, version numbers, feature flags, environment-specific values, and cascaded metadata like API versions or status badges.

2

Directives Reference

Complete reference for all available markdown directives in Bengal

Directives Reference

Bengal extends Markdown with powerful directives using:::{name}or```{name}syntax. Directives provide rich components like callouts, tabs, cards, and more.

Key Terms

Directive
Extended markdown syntax that creates rich components. Bengal supports two syntax styles:fenced ( `{name} ) and MyST (:::{name}).
Fenced Syntax
Directives using triple backticks (e.g., `{note} ). Used for admonitions, dropdowns, badges, checklists, and include directives.
MyST Syntax
Directives using triple colons (e.g.,:::{card}). Used for cards, tabs, buttons, steps, and list tables. Named after the MyST Markdown specification.
Show 30 more terms
Container Directive
A directive that contains other directives (e.g.,{cards},{steps},{tab-set}). Requires 4 fences minimum (::::) and increments for deeper nesting.
Nesting
Placing directives inside other directives. Each nesting level requires incrementing the fence count (container:4 fences, nested item:4 fences, deeper nesting:5+ fences).
Admonition
A styled callout box that draws attention to important information. Available in multiple types (note, warning, tip, danger, etc.) with distinct visual styling.
Callout
Another name for an admonition - a visual box that highlights important content separate from the main text flow.
Card Grid
A container directive ({cards}) that creates a responsive grid of card components. Supports flexible column layouts and responsive breakpoints.
Card
An individual card component ({card}) within a card grid. Can include icons, links, images, colors, and footer content.
Tab Set
A container directive ({tab-set}) that groups multiple tab items together. Provides tabbed navigation for organizing related content.
Tab Item
An individual tab ({tab-item}) within a tab set. Contains content for one tab panel.
Dropdown
A collapsible section directive ({dropdown}) that can be expanded or collapsed. Useful for optional or advanced content to reduce cognitive load.
Grid
A Sphinx-Design compatibility directive ({grid}) that converts to card grids internally. Prefer{cards}for new content.
Badge
A small styled label for tags, status indicators, or labels. Renders as an inline element with customizable CSS classes.
Button
A styled link element that appears as a button. Supports colors, sizes, icons, and link targets for calls-to-action.
Steps Container
A container directive ({steps}) that groups multiple step directives together. Requires 4 fences minimum (::::).
Step
An individual step directive ({step}) within a steps container. Contains content for one step in a sequential guide.
Checklist
A styled container for bullet lists and task lists. Provides visual styling for prerequisites, requirements, or task tracking.
Rubric
A pseudo-heading that looks like a heading but doesn't appear in the table of contents. Perfect for API documentation section labels.
List Table
A table created from nested lists, avoiding pipe character conflicts in type annotations. Useful for Python type hints and complex data structures.
Code Tabs
An interactive tabbed interface ({code-tabs}) for displaying code examples in multiple languages. Users can switch between languages with tab navigation.
Data Table
An interactive table directive ({data-table}) with JavaScript-enhanced features like sorting, filtering, and pagination. Requires Tabulator.js in your theme.
Object Tree
Bengal's hierarchical representation of your site structure (Site → Sections → Pages). Navigation directives traverse this tree to generate content automatically.
Child Cards
A directive ({child-cards}) that automatically creates a card grid from a section's child pages and subsections.
Breadcrumbs
A directive ({breadcrumbs}) that generates hierarchical navigation showing the current page's location in the site structure.
Siblings
A directive ({siblings}) that lists pages at the same level as the current page within their shared parent section.
Prev/Next
A directive ({prev-next}) that generates previous/next navigation links within a section.
Related
A directive ({related}) that lists pages with matching tags.
Include Directive
A directive ({include}) that includes markdown files directly in your content. Supports line ranges and relative path resolution.
Literal Include Directive
A directive ({literalinclude}) that includes code files as syntax-highlighted code blocks. Auto-detects language from file extension and supports line ranges, emphasis, and line numbers.
Snippet
A reusable content file (typically markdown or code) that can be included in multiple pages. Organized in dedicated directories likecontent/snippets/.
Path Resolution
The process of finding included files. Bengal resolves paths relative to the current page's directory first, then falls back to the site root.
Path Traversal Prevention
Security feature that prevents including files outside the site root. Blocks../sequences and absolute paths to protect against unauthorized file access.

Quick Reference

Directive Syntax Purpose Category
{note} ```{note} Information callout Admonitions
{warning} ```{warning} Warning callout Admonitions
{tip} ```{tip} Tip callout Admonitions
{danger} ```{danger} Danger callout Admonitions
{cards} :::{cards} Card grid layout Layout
{card} :::{card} Individual card Layout
{tab-set} :::{tab-set} Tab container Layout
{tab-item} :::{tab-item} Individual tab Layout
{dropdown} ```{dropdown} Collapsible section Layout
{code-tabs} ```{code-tabs} Multi-language code Interactive
{badge} ```{badge} Styled badge Formatting
{button} :::{button} Link button Formatting
{steps} :::{steps} Step-by-step guide Formatting
{step} :::{step} Individual step Formatting
{checklist} ```{checklist} Styled checklist Formatting
{rubric} ```{rubric} Pseudo-heading Formatting
{include} ```{include} Include markdown file Content Reuse
{literalinclude} ```{literalinclude} Include code file Content Reuse
{list-table} :::{list-table} Table from lists Formatting
{data-table} :::{data-table} Interactive data table Interactive
{youtube} :::{youtube} YouTube embed (privacy default) Media
{vimeo} :::{vimeo} Vimeo embed (DNT default) Media
{video} :::{video} Self-hosted HTML5 video Media
{figure} :::{figure} Image with caption Media
{audio} :::{audio} Self-hosted HTML5 audio Media
{gist} :::{gist} GitHub Gist embed Media
{codepen} :::{codepen} CodePen embed Media
{codesandbox} :::{codesandbox} CodeSandbox embed Media
{stackblitz} :::{stackblitz} StackBlitz embed Media
{asciinema} :::{asciinema} Terminal recording Media
{child-cards} :::{child-cards} Auto-generate cards from children Navigation
{breadcrumbs} :::{breadcrumbs} Breadcrumb navigation Navigation
{siblings} :::{siblings} Sibling page list Navigation
{prev-next} :::{prev-next} Prev/next links Navigation
{related} :::{related} Related pages by tags Navigation
{glossary} :::{glossary} Render terms from glossary data Data
{icon} Inline SVG icon Icons

Directive Syntax

Bengal supports two directive syntax styles:

Fenced Syntax (3 backticks)

1
2
3
4
5
:::{directive-name} Optional Title
:option: value

Content here
:::

Used for: Admonitions, dropdowns, badges, checklists, code-tabs, include, literalinclude, rubric

MyST Syntax (3 colons)

1
2
3
4
5
:::{directive-name} Optional Title
:option: value

Content here
:::

Used for: Cards, tabs, buttons, steps, list-table

Nesting with Named Closers

Bengal supports named closers to avoid fence-counting when nesting directives. Use:::{/name}to explicitly close a directive:

Basic Nesting (container with items):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
:::{cards}
:columns: 3

:::{card} Card Title
Card content here
:::

:::{card} Card Title 2
More content
:::

:::{/cards}

Deep Nesting (admonitions within steps, tabs within cards, etc.):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
:::{steps}

:::{step} First Step
:::{tip}
Remember to check the logs!
:::
:::{/step}

:::{step} Second Step
More content
:::{/step}

:::{/steps}

Rule: Use:::{/directive-name}to close any container directive. This eliminates the need to count colons.

Categories

Common Options

Many directives support these common options:

  • :class:- Custom CSS class
  • :id:- Element ID
  • :title:- Title text (alternative to title in directive name)

Examples

Basic Admonition

1
2
3
:::{note}
This is a note with **markdown** support.
:::

Card Grid

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
:::{cards}
:columns: 3

:::{card} Card 1
:icon: book
:link: /docs/

Content here
:::

:::{card} Card 2
Content here
:::

:::{/cards}

Tabs

1
2
3
4
5
:::{tab-set}

:::{tab-item} Python
```python
print("Hello")

:::

console.log("Hello");

:::{/tab-set}


## Glossary Directive

The `{glossary}` directive renders terms from a centralized glossary data file (`data/glossary.yaml`) as a styled definition list. Filter terms by tags to show relevant definitions for each page.

### Syntax

```markdown
:::{glossary}
:tags: directives, core
:sorted: true
:collapsed: true
:limit: 3
:::

Options

Option Default Description
:tags: (required) Comma-separated tags to filter terms (OR logic)
:sorted: false Sort terms alphabetically
:show-tags: false Display tag badges under each term
:collapsed: false Wrap in collapsible<details>element
:limit: (all) Show only first N terms; remaining in expandable section
:source: data/glossary.yaml Custom glossary file path

Examples

Basic Usage - Show terms tagged with "directives":

1
2
3
:::{glossary}
:tags: directives
:::

Progressive Disclosure - Show first 3 terms, rest expandable:

1
2
3
4
:::{glossary}
:tags: directives, core
:limit: 3
:::

Fully Collapsed - Entire glossary in collapsible section:

1
2
3
4
:::{glossary}
:tags: formatting
:collapsed: true
:::

Both Options - Collapsed, with limited terms when expanded:

1
2
3
4
5
:::{glossary}
:tags: layout
:collapsed: true
:limit: 2
:::

Glossary Data Format

Terms are defined indata/glossary.yaml:

1
2
3
4
5
6
7
8
terms:
  - term: Directive
    definition: Extended markdown syntax using `{name}` that creates rich components.
    tags: [directives, core]

  - term: Admonition
    definition: A styled callout box for **important** information.
    tags: [directives, admonitions]

Note: Definitions support inline markdown: backticks forcode,**bold**, and*italic*.

Next Steps

  • Browse directive categories above for detailed syntax
  • See Content Reuse for include/literalinclude strategies
  • Check Writer Quickstart for markdown basics
3

Admonitions

Reference for admonition directives (note, warning, tip, danger, etc.)

Admonition Directives

Admonitions create styled callout boxes for notes, warnings, tips, and other important information.

Key Terms

Admonition
A styled callout box that draws attention to important information. Available in multiple types (note, warning, tip, danger, etc.) with distinct visual styling.
Callout
Another name for an admonition - a visual box that highlights important content separate from the main text flow.

Syntax

1
2
3
:::{admonition-type} Optional Title
Content with **full markdown** support.
:::

Available Types

Type Purpose CSS Class
{note} General information admonition note
{tip} Helpful tips admonition tip
{warning} Warnings admonition warning
{caution} Cautions admonition warning
{danger} Critical warnings admonition danger
{error} Error messages admonition error
{info} Informational content admonition info
{example} Examples admonition example
{success} Success messages admonition success

Examples

Basic Note

1
2
3
:::{note}
This is a note with **markdown** support.
:::

With Title

1
2
3
:::{warning} Important
This feature requires admin access.
:::

Without Title (Uses Type Name)

1
2
3
:::{tip}
Use this pattern for better performance.
:::

Renders as "Tip" (capitalized type name).

Nested Content

Admonitions support full markdown including nested directives. Use named closers for clarity:

1
2
3
4
5
6
7
:::{note}
Here's a tip:

:::{tip}
Nested admonitions work!
:::
:::{/note}

All Types

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
:::{note} Note
General information
:::

:::{tip} Tip
Helpful suggestion
:::

:::{warning} Warning
Something to be careful about
:::

:::{danger} Danger
Critical warning
:::

:::{error} Error
Error message
:::

:::{info} Info
Informational content
:::

:::{example} Example
Example usage
:::

:::{success} Success
Success message
:::

:::{caution} Caution
Cautionary note
:::

Options

Admonitions support standard directive options:

  • :class:- Additional CSS classes
  • :id:- Element ID
1
2
3
4
5
6
:::{note} Custom Note
:class: custom-class
:id: my-note

Content here
:::

Rendering

Admonitions render as:

1
2
3
4
<div class="admonition note">
  <p class="admonition-title">Note</p>
  <div>Content here</div>
</div>

Best Practices

  1. Use appropriate types: Choose the type that best matches the content's importance
  2. Keep titles concise: Short, descriptive titles work best
  3. Use sparingly: Too many admonitions can overwhelm readers
  4. Nest carefully: Nested admonitions work but can be visually busy
4

Layout Directives

Reference for layout directives (cards, tabs, dropdown, grid)

Layout Directives

Layout directives organize content into structured components like card grids, tabs, and collapsible sections.

Key Terms

Card Grid
A container directive ({cards}) that creates a responsive grid of card components. Supports flexible column layouts and responsive breakpoints.
Card
An individual card component ({card}) within a card grid. Can include icons, links, images, colors, and footer content.
Tab Set
A container directive ({tab-set}) that groups multiple tab items together. Provides tabbed navigation for organizing related content.
Tab Item
An individual tab ({tab-item}) within a tab set. Contains content for one tab panel.
Dropdown
A collapsible section directive ({dropdown}) that can be expanded or collapsed. Useful for optional or advanced content to reduce cognitive load.
Grid
A Sphinx-Design compatibility directive ({grid}) that converts to card grids internally. Prefer{cards}for new content.

Cards

Create responsive card grids for navigation, feature highlights, or content organization.

Card Grid ({cards})

Container for multiple cards with responsive column layout. Use:::{/cards}to close.

Syntax:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
:::{cards}
:columns: 3
:gap: medium
:style: default
:variant: navigation

:::{card} Card Title
:icon: book
:link: /docs/
:color: blue
:image: /hero.jpg
:footer: Updated 2025

Card content with **markdown** support.
:::

:::{/cards}

Options:

  • :columns:- Column layout:
    • auto(default) - Auto-fit based on card width
    • 2,3,4- Fixed columns
    • 1-2-3- Responsive (mobile-tablet-desktop)
    • 1-2-3-4- Responsive with wide breakpoint
  • :gap:- Gap between cards:small,medium(default),large
  • :style:- Card style:default,minimal,bordered
  • :variant:- Variant:navigation(default),info,concept
  • :layout:- Card layout:default,horizontal,portrait,compact

Individual Card ({card})

Single card within a cards container.

Syntax:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
:::{card} Card Title
:icon: book
:link: /docs/
:color: blue
:image: /hero.jpg
:footer: Footer text

Card content with **markdown** support.

+++
Footer content (alternative to :footer: option)
:::

Options:

  • :icon:- Icon name (e.g.,book,code,rocket)
  • :link:- Card link URL (path, slug, orid:ref-target)
  • :color:- Color:blue,green,red,yellow,orange,purple,gray,pink,indigo
  • :image:- Header image URL
  • :footer:- Footer text (or use+++separator)
  • :pull:- Auto-fetch fields from linked page:title,description,icon,image,date,tags
  • :layout:- Override grid layout:horizontal,portrait,compact

Footer Separator:

1
2
3
4
5
:::{card} Title
Body content
+++
Footer content
:::

Examples

Basic Card Grid:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
:::{cards}
:columns: 3

:::{card} Getting Started
:icon: rocket
:link: /docs/get-started/

Learn the basics
:::

:::{card} API Reference
:icon: code
:link: /api/

Complete API docs
:::

:::{card} Tutorials
:icon: book
:link: /docs/tutorials/

Step-by-step tutorials
:::

:::{/cards}

Responsive Columns:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
:::{cards}
:columns: 1-2-3
:gap: large

:::{card} Card 1
Content
:::

:::{card} Card 2
Content
:::

:::{/cards}

Cards with Nested Admonitions:

Named closers eliminate fence-counting for complex nesting:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
:::{cards}
:columns: 2

:::{card} Important Card
:::{warning}
This feature requires special setup.
:::
:::{/card}

:::{card} Regular Card
Standard content here.
:::{/card}

:::{/cards}

Named Closers

Use:::{/name}to explicitly close any container directive, eliminating the need to count colons.

Auto-Pull from Linked Pages:

Use:pull:to automatically fetch metadata from linked pages, reducing content duplication:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
:::{cards}
:columns: 3

:::{card}
:link: docs/getting-started/writer-quickstart
:pull: title, description
:::

:::{card}
:link: id:themer-qs
:pull: title, description, icon
:::

:::{card} Custom Title
:link: /docs/contributor/
:pull: description

Custom content overrides pulled description.
:::

:::{/cards}

The:pull:option supports:

  • title- Page title from frontmatter
  • description- Page description from frontmatter
  • icon- Icon from frontmatter
  • image- Image from frontmatter
  • date- Page date
  • tags- Page tags

Reference Targets

Useid:ref-namesyntax to reference pages by their frontmatteridfield instead of path. This makes links stable even if you reorganize content.

Layout Variants:

Use:layout:for different card arrangements:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
:::{cards}
:columns: 2
:layout: horizontal

:::{card} Feature One
:image: /images/feature1.png

Image on left, content on right.
:::

:::{card} Feature Two
:image: /images/feature2.png

Great for feature showcases.
:::

:::{/cards}

Layout options:

  • default- Vertical card (image top, content below)
  • horizontal- Image left, content right
  • portrait- Tall aspect ratio (2:3), great for app screenshots or TCG-style cards
  • compact- Reduced padding for dense reference lists

Portrait Cards (TCG/Phone Style):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
:::{cards}
:columns: 3
:layout: portrait

:::{card} App Screenshot
:image: /images/app-home.png

Home screen of our mobile app.
:::

:::{card} Dashboard
:image: /images/app-dashboard.png

Analytics dashboard view.
:::

:::{/cards}

Tabs

Create tabbed content sections for organizing related content.

Tab Set ({tab-set})

Container for tab items. Use:::{/tab-set}to close.

Syntax:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
:::{tab-set}
:sync: my-key

:::{tab-item} Tab Title
:selected:

Tab content with **markdown** support.
:::

:::{tab-item} Another Tab
More content
:::

:::{/tab-set}

Options:

  • :sync:- Sync key for multiple tab-sets (same key = synchronized selection)
  • :id:- Tab set ID

Tab Item ({tab-item})

Individual tab within a tab-set.

Syntax:

1
2
3
4
5
:::{tab-item} Tab Title
:selected:

Tab content
:::

Options:

  • :selected:- Mark this tab as initially selected (no value needed)

Examples

Basic Tabs:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
:::{tab-set}

:::{tab-item} Python
```python
print("Hello")
```
:::

:::{tab-item} JavaScript
```javascript
console.log("Hello");
```
:::

:::{/tab-set}

Synchronized Tabs:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
:::{tab-set}
:sync: code-example

:::{tab-item} Python
Python code
:::

:::{/tab-set}

:::{tab-set}
:sync: code-example

:::{tab-item} Python
Same Python code (synced)
:::

:::{/tab-set}

Tabs with Nested Admonitions:

Named closers eliminate fence-counting for complex nesting:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
:::{tab-set}

:::{tab-item} Setup
:::{warning}
Make sure to backup your data first!
:::

Setup instructions here.
:::{/tab-item}

:::{tab-item} Usage
Regular usage content.
:::{/tab-item}

:::{/tab-set}

Named Closers

Use:::{/name}to explicitly close any container directive, eliminating the need to count colons.

Collapsible sections for optional or advanced content.

Syntax:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
:::{dropdown} Title
:open: true
:icon: info

Content with **markdown** support.

:::{note}
Nested directives work!
:::
:::

Options:

  • :open:- Open by default:true,false(default)
  • :icon:- Icon name to display next to title (e.g.,info,settings,star)
  • :badge:- Badge text (e.g., "New", "Advanced")
  • :color:- Color variant:success,warning,danger,info,minimal
  • :class:- Additional CSS classes

Alias:{details}works the same as{dropdown}.

Examples

Collapsed by Default:

1
2
3
4
:::{dropdown} Advanced Options
:icon: settings
Click to expand advanced configuration options.
:::

Open by Default:

1
2
3
4
5
6
:::{dropdown} Quick Reference
:icon: info
:open: true

Common commands and shortcuts.
:::

With Badge and Color:

1
2
3
4
5
6
7
:::{dropdown} New Features
:icon: star
:badge: New
:color: success

Check out the latest features!
:::

Grid (Sphinx-Design Compatibility)

Compatibility layer for Sphinx-Design grid syntax.

Syntax:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
:::{grid} 1 2 2 2
:gutter: 1

:::{grid-item-card} Title
:link: /docs/

Content
:::

:::{/grid}

Note

Prefer{cards}/{card}for new content. Grid directives convert to cards internally.

Best Practices

  1. Card Grids: Use for navigation, feature highlights, or content organization
  2. Tabs: Use for related content that doesn't need to be visible simultaneously
  3. Dropdowns: Use for optional or advanced content to reduce cognitive load
  4. Responsive Design: Use responsive column syntax (1-2-3) for mobile-friendly layouts

Auto-Generated Cards

For section index pages, consider using{child-cards}instead of manual cards. It automatically generates cards from child sections and pages:

1
2
3
4
5
:::{child-cards}
:columns: 2
:include: sections
:fields: title, description, icon
:::

See Navigation Directives for full documentation.

5

Content Reuse

Snippets, data files, and DRY patterns

Reusing Content

Write once, publish everywhere. Bengal provides multiple ways to avoid repeating yourself.

Reuse Strategies

flowchart LR subgraph "Single Source" A[Snippet] B[Data File] C[Shortcode] end subgraph "Multiple Outputs" D[Page 1] E[Page 2] F[Page 3] end A --> D A --> E B --> D B --> F C --> E C --> F

Quick Reference

Reusable Markdown fragments stored in_snippets/:

_snippets/
├── install/
│   ├── pip.md
│   └── uv.md
└── warnings/
    └── experimental.md

Include in any page:

1
2
:::{include} _snippets/install/pip.md
:::

Structured YAML/JSON indata/:

1
2
3
4
# data/team.yaml
- name: Jane Doe
  role: Lead Developer
  github: janedoe

Access in templates:

1
2
3
{% for member in site.data.team %}
  {{ member.name }} - {{ member.role }}
{% endfor %}

Query content dynamically:

1
2
3
4
5
6
7
8
{# All tutorials #}
{% set tutorials = site.pages
   | selectattr("params.type", "equalto", "tutorial") %}

{# Recent posts #}
{% set recent = site.pages
   | sort(attribute="date", reverse=true)
   | list | slice(5) %}

When to Use What

Method Best For Example
Snippets Repeated prose blocks Installation instructions, warnings
Data Files Structured data Team members, product features
Filtering Dynamic lists Recent posts, related pages
Shortcodes Parameterized components Video embeds, API badges

Tip

Start with snippets for common content blocks. Graduate to data files when you need structured data, and filtering when you need dynamic queries.

6

Content Snippets

Reusable content fragments with include directives

Content Snippets

Maintaining consistency across hundreds of pages is hard. If you copy-paste the same "Warning" or "Code Example" into 20 pages, updating it becomes a nightmare.

Bengal provides powerful directives to implement a "Write Once, Publish Everywhere" strategy directly in your Markdown content.

Strategy 1: Include Markdown Files

Use the{include}directive to include entire markdown files or sections.

Basic Usage

Create a reusable snippet file:

1
2
3
4
<!-- content/snippets/warning.md -->
:::{warning}
This feature is in beta. Please report any issues.
:::

Include it in any page:

1
2
3
4
5
6
7
8
# My Article

Here is some content.

```{include} snippets/warning.md
```

More content.

Include Specific Lines

Include only a portion of a file:

1
2
3
4
```{include} snippets/api-example.md
:start-line: 5
:end-line: 20
```

This includes lines 5-20 from the file.

Path Resolution

Paths are resolved relative to:

  1. Current page's directory - If you're incontent/docs/content/,snippets/warning.mdlooks incontent/docs/content/snippets/
  2. Site root - Falls back to site root if not found relative to page

Strategy 2: Include Code Files

Use the{literalinclude}directive to include code files as syntax-highlighted code blocks.

Basic Usage

1
2
```{literalinclude} examples/api.py
```

This automatically:

  • Detects the language from the file extension (.py→ Python)
  • Applies syntax highlighting
  • Includes the entire file

Include Specific Lines

Include only a portion of a code file:

1
2
3
4
```{literalinclude} examples/api.py
:start-line: 10
:end-line: 25
```

Emphasize Lines

Highlight specific lines:

1
2
3
```{literalinclude} examples/api.py
:emphasize-lines: 7,8,9
```

Or a range:

1
2
3
```{literalinclude} examples/api.py
:emphasize-lines: 7-9
```

Complete Example

1
2
3
4
5
6
7
```{literalinclude} examples/api.py
:language: python
:start-line: 10
:end-line: 30
:emphasize-lines: 15,16,17
:linenos: true
```

Supported Languages

literalincludeauto-detects language from file extensions:

  • Python:.py
  • JavaScript:.js,.ts
  • Web:.html,.css
  • Config:.yaml,.yml,.json,.toml
  • Shell:.sh,.bash,.zsh
  • And many more - See the directive documentation for full list

Best Practices

Organize Snippets

Create a dedicated directory for reusable content:

content/
├── _snippets/
│   ├── warnings/
│   │   ├── beta-notice.md
│   │   └── deprecated-feature.md
│   ├── code-examples/
│   │   ├── api-client.py
│   │   └── config.yaml
│   └── common-content/
│       ├── installation-steps.md
│       └── troubleshooting.md
└── docs/
    └── guides/
        └── my-guide.md  # Uses snippets via {include}

Keep Snippets Focused

Each snippet should have a single purpose:

Good:_snippets/warnings/beta-notice.md- One warning
Bad:_snippets/all-warnings.md- Multiple warnings mixed together

Use Relative Paths

Prefer relative paths for portability:

Good:_snippets/warning.md
Bad:/absolute/path/to/warning.md

Security Model

Bengal includes built-in security protections to prevent path traversal attacks and unauthorized file access.

Security Features

1. Path Traversal Prevention

  • All include paths are validated to ensure they stay within the site root
  • Attempts to use../to access files outside the site root are blocked
  • Absolute paths (starting with/) are rejected

2. Site Root Enforcement

  • Files must be within the site's content directory or site root
  • Resolved paths are checked against the site root boundary
  • Invalid paths log warnings and fail gracefully

Troubleshooting

Summary

Directive Best For Example
{include} Reusable markdown content (warnings, steps, explanations) {include} _snippets/warning.md
{literalinclude} Code examples, configuration files, scripts {literalinclude} examples/api.py

Both directives support:

  • ✅ Line ranges (:start-line:,:end-line:)
  • ✅ Relative path resolution
  • ✅ Security (prevents path traversal)
  • ✅ Nested directives (included content can use other directives)

Seealso