Content Author Mastery
Master advanced Markdown features, directives, and content reuse.
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
Track Contents
Content Authoring
Markdown, MyST directives, and shortcodes
Writing Content
Bengal uses CommonMark Markdown with MyST extensions for rich documentation.
Quick Reference
1 2 3 | |
1 2 3 | |
1 2 | |
1 2 3 4 | |
With line highlighting:
1 2 3 4 | |
MyST Directives
Directives add rich components to your Markdown:
1 2 3 4 5 6 7 8 9 10 11 | |
1 2 3 4 5 6 7 8 | |
1 2 3 4 5 6 | |
1 2 3 4 5 | |
1 2 3 4 5 6 7 8 | |
Syntax Overview
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 | |
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 | |
Then use in any child page:
1 2 | |
Tip
Common use cases: Product names, version numbers, feature flags, environment-specific values, and cascaded metadata like API versions or status badges.
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
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 | |
Used for: Admonitions, dropdowns, badges, checklists, code-tabs, include, literalinclude, rubric
MyST Syntax (3 colons)
1 2 3 4 5 | |
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 | |
Deep Nesting (admonitions within steps, tabs within cards, etc.):
1 2 3 4 5 6 7 8 9 10 11 12 13 | |
Rule: Use:::{/directive-name}to close any container directive. This eliminates the need to count colons.
Categories
Reference for admonition directives (note, warning, tip, danger, etc.)
Reference for layout directives (cards, tabs, dropdown, grid)
Reference for formatting directives (badge, button, steps, checklist, rubric, list-table)
Reference for interactive directives (code-tabs, data-table)
Reference for content reuse directives (include, literalinclude)
Reference for media embed directives (YouTube, Vimeo, video, audio, figure, code playgrounds, terminal recordings)
Reference for navigation directives (child-cards, breadcrumbs, siblings, prev-next, related)
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 | |
Card Grid
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | |
Tabs
1 2 3 4 5 | |
:::
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 | |
Progressive Disclosure - Show first 3 terms, rest expandable:
1 2 3 4 | |
Fully Collapsed - Entire glossary in collapsible section:
1 2 3 4 | |
Both Options - Collapsed, with limited terms when expanded:
1 2 3 4 5 | |
Glossary Data Format
Terms are defined indata/glossary.yaml:
1 2 3 4 5 6 7 8 | |
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
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 | |
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 | |
With Title
1 2 3 | |
Without Title (Uses Type Name)
1 2 3 | |
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 | |
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 | |
Options
Admonitions support standard directive options:
:class:- Additional CSS classes:id:- Element ID
1 2 3 4 5 6 | |
Rendering
Admonitions render as:
1 2 3 4 | |
Best Practices
- Use appropriate types: Choose the type that best matches the content's importance
- Keep titles concise: Short, descriptive titles work best
- Use sparingly: Too many admonitions can overwhelm readers
- Nest carefully: Nested admonitions work but can be visually busy
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 | |
Options:
:columns:- Column layout:auto(default) - Auto-fit based on card width2,3,4- Fixed columns1-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 | |
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 | |
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 | |
Responsive Columns:
1 2 3 4 5 6 7 8 9 10 11 12 13 | |
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 | |
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 | |
The:pull:option supports:
title- Page title from frontmatterdescription- Page description from frontmattericon- Icon from frontmatterimage- Image from frontmatterdate- Page datetags- 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 | |
Layout options:
default- Vertical card (image top, content below)horizontal- Image left, content rightportrait- Tall aspect ratio (2:3), great for app screenshots or TCG-style cardscompact- 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 | |
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 | |
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 | |
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 | |
Synchronized Tabs:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | |
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 | |
Named Closers
Use:::{/name}to explicitly close any container directive, eliminating the need to count colons.
Dropdown
Collapsible sections for optional or advanced content.
Syntax:
1 2 3 4 5 6 7 8 9 10 | |
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 | |
Open by Default:
1 2 3 4 5 6 | |
With Badge and Color:
1 2 3 4 5 6 7 | |
Grid (Sphinx-Design Compatibility)
Compatibility layer for Sphinx-Design grid syntax.
Syntax:
1 2 3 4 5 6 7 8 9 10 | |
Note
Prefer{cards}/{card}for new content. Grid directives convert to cards internally.
Best Practices
- Card Grids: Use for navigation, feature highlights, or content organization
- Tabs: Use for related content that doesn't need to be visible simultaneously
- Dropdowns: Use for optional or advanced content to reduce cognitive load
- 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 | |
See Navigation Directives for full documentation.
Related
- Navigation Directives - Auto-generated cards, breadcrumbs, siblings
- Admonitions - Callout boxes
- Formatting Directives - Badges, buttons, steps
Content Reuse
Snippets, data files, and DRY patterns
Reusing Content
Write once, publish everywhere. Bengal provides multiple ways to avoid repeating yourself.
Reuse Strategies
Quick Reference
Reusable Markdown fragments stored in_snippets/:
_snippets/
├── install/
│ ├── pip.md
│ └── uv.md
└── warnings/
└── experimental.md
Include in any page:
1 2 | |
Structured YAML/JSON indata/:
1 2 3 4 | |
Access in templates:
1 2 3 | |
Query content dynamically:
1 2 3 4 5 6 7 8 | |
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.
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 | |
Include it in any page:
1 2 3 4 5 6 7 8 | |
Include Specific Lines
Include only a portion of a file:
1 2 3 4 | |
This includes lines 5-20 from the file.
Path Resolution
Paths are resolved relative to:
- Current page's directory - If you're in
content/docs/content/,snippets/warning.mdlooks incontent/docs/content/snippets/ - 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 | |
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 | |
Emphasize Lines
Highlight specific lines:
1 2 3 | |
Or a range:
1 2 3 | |
Complete Example
1 2 3 4 5 6 7 | |
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
File Not Found
Error:Include error: File not found: snippets/warning.md
Solutions:
- Check the path is correct relative to your page
- Verify the file exists in the expected location
- Try an absolute path from site root:
content/_snippets/warning.md - Check for typos in the filename (case-sensitive on some systems)
Path Traversal Blocked
Error:Include path traversal rejectedorInclude outside site root
Cause: Attempted to include files outside the site root (security feature)
Solutions:
- Move the file into your site's content directory
- Use a relative path that stays within the site root
- Check that your site root is correctly configured in
bengal.toml
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
- Content Reuse Overview — DRY content strategies
- Filtering — Advanced content queries