Migration Guide: Snippets to Macros¶
If you are coming from traditional CKAN development, you are likely used to
writing raw HTML with framework-specific classes or using snippets for complex
UI elements. This guide shows how these patterns translate to the
ckanext-theming system.
1. Simple Buttons¶
Traditional¶
You write HTML with Bootstrap classes (or whatever framework you use).
With Macros¶
You use a semantic call. The theme handles the btn, btn-primary, and btn-lg classes.
2. Information Alerts¶
Traditional¶
With Macros¶
3. Complex Cards (Snippets)¶
Traditional¶
You might use a snippet and pass data to it.
With Macros¶
You use the package component. It's still a single line, but it's now part of
a standardized API that works across different themes.
4. Nested Content (The call pattern)¶
This is where the most power lies. Traditional CKAN development often makes it hard to pass complex HTML into a snippet without using multiple blocks or global variables.
Traditional¶
<div class="card">
<div class="card-header">Custom Header</div>
<div class="card-body">
<p>Some custom HTML content.</p>
<a href="..." class="btn">Click me</a>
</div>
</div>
With Macros¶
Using ui.util.call, you can nest components and raw HTML naturally.
{% call ui.util.call(ui.card, title="Custom Header") %}
<p>Some custom HTML content.</p>
{{ ui.button(_("Click me"), href="...") }}
{% endcall %}
5. Form Fields¶
Traditional¶
{% import "macros/form.html" as form %}
{{ form.input("title", label=_("Title"), value=data.title, placeholder="eg. My Dataset") }}
With Macros¶
The macro handles the wrapper, label, ID generation, and accessibility attributes.
Summary of Changes¶
| Feature | Traditional CKAN | ckanext-theming |
|---|---|---|
| Logic | Mix of HTML and template logic | Pure semantic calls |
| CSS Classes | Hardcoded in templates | Abstracted into the theme |
| Portability | Locked to one CSS framework | Works with any compatible theme |
| Maintenance | Update HTML in every template | Update macro in one place |