Shortcodes
Shortcodes are reusable content components that can be embedded in Markdown.
Syntax
{{ shortcode_name(param1="value1", param2="value2") }}
Parameter Formats
<div class="alert" style="padding: 1rem; border: 1px solid #ddd; background-color: #f9f9f9; border-left: 5px solid #0070f3; margin: 1rem 0;">
<strong>WARNING:</strong> Be careful!
</div>
{{ figure(src='/images/photo.jpg', alt='Photo') }}
{{ button(href=/docs/, text=Documentation) }}
- Double quotes:
param="value" - Single quotes:
param='value' - Unquoted:
param=value
Creating Shortcodes
Create templates in templates/shortcodes/:
Simple Shortcode
templates/shortcodes/highlight.html:
<mark class="highlight">{{ text }}</mark>
Usage:
{{ highlight(text="Important text") }}
Conditional Shortcode
templates/shortcodes/alert.html:
{% if type and message %}
<div class="alert alert-{{ type }}">
{{ message | safe }}
</div>
{% endif %}
Usage:
<div class="alert" style="padding: 1rem; border: 1px solid #ddd; background-color: #f9f9f9; border-left: 5px solid #0070f3; margin: 1rem 0;">
<strong>INFO:</strong> This is a note.
</div>
<div class="alert" style="padding: 1rem; border: 1px solid #ddd; background-color: #f9f9f9; border-left: 5px solid #0070f3; margin: 1rem 0;">
<strong>WARNING:</strong> <strong>Warning!</strong>
</div>
Shortcode with Defaults
templates/shortcodes/button.html:
<a href="{{ href }}" class="btn btn-{{ style | default(value='primary') }}">
{{ text }}
</a>
Usage:
{{ button(href="/docs/", text="Read Docs") }}
{{ button(href="/buy/", text="Buy Now", style="secondary") }}
Common Shortcodes
Alert
<div class="alert" style="padding: 1rem; border: 1px solid #ddd; background-color: #f9f9f9; border-left: 5px solid #0070f3; margin: 1rem 0;">
<strong>INFO:</strong> Informational note.
</div>
<div class="alert" style="padding: 1rem; border: 1px solid #ddd; background-color: #f9f9f9; border-left: 5px solid #0070f3; margin: 1rem 0;">
<strong>WARNING:</strong> Warning message.
</div>
<div class="alert" style="padding: 1rem; border: 1px solid #ddd; background-color: #f9f9f9; border-left: 5px solid #0070f3; margin: 1rem 0;">
<strong>TIP:</strong> Pro tip here.
</div>
<div class="alert" style="padding: 1rem; border: 1px solid #ddd; background-color: #f9f9f9; border-left: 5px solid #0070f3; margin: 1rem 0;">
<strong>DANGER:</strong> Danger zone!
</div>
Figure
{{ figure(src="/images/screenshot.png", alt="Screenshot", caption="App dashboard") }}
Template:
<figure>
<img src="{{ src }}" alt="{{ alt }}">
{% if caption %}<figcaption>{{ caption }}</figcaption>{% endif %}
</figure>
YouTube
{{ youtube(id="dQw4w9WgXcQ") }}
Template:
<div class="video-embed">
<iframe src="https://www.youtube.com/embed/{{ id }}" allowfullscreen></iframe>
</div>
Image Gallery
templates/shortcodes/images.html:
{% set images_arr = src | split(pat=",") %}
<div class="images-grid">
{% for image in images_arr %}
<img src="{{ image | trim }}" alt="{{ alt | default(value='') }}" loading="lazy">
{% endfor %}
</div>
Usage:
{{ images(src="/img/a.jpg, /img/b.jpg, /img/c.jpg", alt="Gallery") }}
Available Filters
Shortcode templates can use all Jinja2 filters:
| Filter | Description |
|---|---|
| `safe` | Render HTML without escaping |
| `default(value="x")` | Fallback value |
| `split(pat=",")` | Split string |
| `trim` | Remove whitespace |
| `upper` / `lower` | Case conversion |
| `slugify` | URL slug |
| `truncate_words(n)` | Truncate text |
| `strip_html` | Remove HTML tags |
| `markdownify` | Render Markdown |
Example CSS
.alert {
padding: 1rem;
border-radius: 8px;
margin: 1rem 0;
border-left: 4px solid;
}
.alert-info {
background: rgba(59, 130, 246, 0.1);
border-color: #3b82f6;
}
.alert-warning {
background: rgba(234, 179, 8, 0.1);
border-color: #eab308;
}
.alert-danger {
background: rgba(239, 68, 68, 0.1);
border-color: #ef4444;
}
.btn {
display: inline-block;
padding: 0.5rem 1rem;
border-radius: 6px;
text-decoration: none;
}
.btn-primary {
background: #e53935;
color: white;
}
Troubleshooting
Shortcode not rendering:
- Check filename matches:
alert.htmlfor `:` - Verify file is in `templates/shortcodes/` - Check for template syntax errorsHTML appearing escaped:
- Use
{{ message | safe }}for HTML content
Filter not found:
- Use correct syntax:
split(pat=",")notsplit(",")
- Use
Hwaro