Template Tags
Django Palette provides custom template tags for building dynamic, reusable admin components.
Loading the Template Tag Library
Add this to the top of any template using django-palette tags:
{% load palette %}
palette_component
Define a reusable component with named blocks.
Syntax:
{% palette_component component_name %}
<!-- Component HTML -->
{% palette_block block_name %}
Default content
{% endpalette_block %}
{% endpalette_component %}
Parameters:
component_name(required): Name of the component (unquoted identifier)
Description:
Creates a new component that can be rendered multiple times with palette_ui. Components can have multiple palette_block areas that can be overridden when the component is rendered.
Example:
{% palette_component stat_card %}
<div class="card border-0 shadow-sm">
<div class="card-body text-center">
{% palette_block header %}
<h2 class="display-4">{{ number }}</h2>
{% endpalette_block %}
{% palette_block footer %}
<p class="text-muted">{{ label }}</p>
{% endpalette_block %}
</div>
</div>
{% endpalette_component %}
Best Practices:
Define components in a template file that’s included from your base template
Use clear, descriptive component names
Use clear block names (e.g.,
header,content,footer)Provide sensible default content in blocks
palette_block
Define a named block within a component that can be overridden.
Syntax:
{% palette_block block_name %}
Default content here
{% endpalette_block %}
Parameters:
block_name(required): Name of the block (unquoted identifier)
Description:
Creates a named area within a component that can be overridden when rendering. Each block must have a unique name within its component.
Example:
{% palette_block content %}
<p>This is the default content.</p>
{% endpalette_block %}
When rendering the component, you can override this block:
{% palette_ui file="palette/components/card.html" component="card" %}
{% palette_override content %}
<p>This is custom content that replaces the default.</p>
{% endpalette_override %}
{% endpalette_ui %}
Block Naming:
Use descriptive names:
header- Header sectioncontent- Main content areafooter- Footer sectionactions- Action buttonsmetadata- Additional information
palette_ui
Render a component with context variables and optional overrides.
Syntax:
{% palette_ui file="path/to/template.html" component="component_name" with var1=value1 var2=value2 %}
Parameters:
file(required): Path to the template file containing the component definitioncomponent(required): Name of the component to render (unquoted identifier)with(optional): Pass context variables to the componentVariables follow Django’s
withtag syntax
Description:
Renders a previously defined component. You can pass context variables that will be available inside the component. You can also override specific blocks using palette_override.
Example 1: Basic Rendering
{% palette_ui file="palette/components/card.html" component="stat_card" with number="1,234" label="Total Users" %}
This renders the stat_card component with:
- number = “1,234”
- label = “Total Users”
Inside the component, you can access these variables:
<h2>{{ number }}</h2>
<p>{{ label }}</p>
Example 2: With Overrides
{% palette_ui file="palette/components/card.html" component="stat_card" with number="89" label="Active Today" %}
{% palette_override header %}
<h2 class="text-success">{{ number }}</h2>
{% endpalette_override %}
{% endpalette_ui %}
Example 3: With Django Variables
{% palette_ui file="palette/components/card.html" component="stat_card" with number=total_users label="Total Users" %}
{% palette_ui file="palette/components/card.html" component="stat_card" with number=active_count label="Active Sessions" %}
Variable Types:
You can pass any type of value:
Strings:
label="My Label"Numbers:
count=123Variables:
count=total_usersObjects:
user=request.userFilters:
date=now|date:"Y-m-d"
palette_override
Override a specific block when rendering a component.
Syntax:
{% palette_ui file="path/to/template.html" component="component_name" %}
{% palette_override block_name %}
New content for the block
{% endpalette_override %}
{% endpalette_ui %}
Parameters:
block_name(required): Name of the block to override (unquoted identifier)
Description:
Replaces the content of a named block within a component. Can only be used inside palette_ui. You can have multiple overrides for different blocks.
Example 1: Single Override
{% palette_ui file="palette/components/card.html" component="card" %}
{% palette_override content %}
<p>Custom content goes here</p>
{% endpalette_override %}
{% endpalette_ui %}
Example 2: Multiple Overrides
{% palette_ui file="palette/components/card.html" component="card" with title="My Card" %}
{% palette_override header %}
<h1 class="text-primary">{{ title }}</h1>
{% endpalette_override %}
{% palette_override content %}
<p>Custom content in the body</p>
{% endpalette_override %}
{% palette_override footer %}
<small>Custom footer text</small>
{% endpalette_override %}
{% endpalette_ui %}
Override with Variables:
You have access to all variables passed to palette_ui:
{% palette_ui file="palette/components/card.html" component="stat_card" with number=count label="My Stat" %}
{% palette_override header %}
<h2 class="text-info">{{ number }}</h2>
{% endpalette_override %}
{% endpalette_ui %}
Complete Example
Here’s a complete example showing all tags working together:
Component Definition (in templates/components/alert.html)
{% load palette %}
{% palette_component alert %}
<div class="alert alert-{{ type|default:'info' }} border-0" role="alert">
{% palette_block icon %}
<i class="bi bi-info-circle"></i>
{% endpalette_block %}
{% palette_block title %}
<strong>{{ title }}</strong>
{% endpalette_block %}
{% palette_block message %}
{{ message }}
{% endpalette_block %}
</div>
{% endpalette_component %}
Using the Component
{% load palette %}
{% include "components/alert.html" %}
<!-- Basic usage -->
{% palette_ui file="palette/components/alert.html" component="alert" with type="success" title="Success!" message="Your changes have been saved." %}
<!-- With overrides -->
{% palette_ui file="palette/components/alert.html" component="alert" with type="warning" title="Attention" message="Please review before proceeding." %}
{% palette_override icon %}
<i class="bi bi-exclamation-triangle"></i>
{% endpalette_override %}
{% endpalette_ui %}
<!-- With variables -->
{% palette_ui file="palette/components/alert.html" component="alert" with type=alert_type title=alert_title message=alert_message %}
Tips & Tricks
1. Reuse Components Everywhere
Define common components once, use them throughout your templates:
{% palette_ui file="palette/components/card.html" component="card" with title="Users" content=user_count %}
{% palette_ui file="palette/components/card.html" component="card" with title="Orders" content=order_count %}
{% palette_ui file="palette/components/card.html" component="card" with title="Sales" content=total_sales %}
2. Use Variables from Context
Pass context variables directly without quotes:
{% palette_ui "stat_card" with number=request.user.post_count label="Posts" %}
3. Apply Filters to Variables
You can apply Django filters:
{% palette_ui file="palette/components/card.html" component="stat_card" with created=object.created_at|date:"Y-m-d" %}
4. Create Component Variants
Use overrides to create variations without duplicating code:
<!-- Success variant -->
{% palette_ui file="palette/components/alert.html" component="alert" with type="success" title="Success" %}
<!-- Error variant -->
{% palette_ui file="palette/components/alert.html" component="alert" with type="danger" title="Error" %}
{% palette_override icon %}
<i class="bi bi-x-circle"></i>
{% endpalette_override %}
{% endpalette_ui %}
5. Nest Components
You can use components inside other components:
{% palette_component dashboard %}
<div class="dashboard">
{% palette_block stats %}
{% palette_ui file="palette/components/card.html" component="stat_card" with number="100" label="Stat 1" %}
{% palette_ui file="palette/components/card.html" component="stat_card" with number="200" label="Stat 2" %}
{% endpalette_block %}
</div>
{% endpalette_component %}
6. Conditional Content in Blocks
Use Django’s template conditionals inside blocks:
{% palette_block actions %}
{% if user.is_staff %}
<button>Admin Action</button>
{% endif %}
{% endpalette_block %}
Common Patterns
Pattern 1: Card Component
{% palette_component card %}
<div class="card border-0 shadow-sm">
<div class="card-header">
{% palette_block title %}
<h5>{{ title }}</h5>
{% endpalette_block %}
</div>
<div class="card-body">
{% palette_block content %}
<p>{{ content }}</p>
{% endpalette_block %}
</div>
</div>
{% endpalette_component %}
Pattern 2: List Item Component
{% palette_component list_item %}
<li class="list-group-item">
{% palette_block primary %}
<strong>{{ name }}</strong>
{% endpalette_block %}
{% palette_block secondary %}
<small class="text-muted">{{ description }}</small>
{% endpalette_block %}
</li>
{% endpalette_component %}
Pattern 3: Modal Component
{% palette_component modal %}
<div class="modal fade" id="{{ modal_id }}" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
{% palette_block title %}
<h5 class="modal-title">{{ title }}</h5>
{% endpalette_block %}
</div>
<div class="modal-body">
{% palette_block body %}
{{ content }}
{% endpalette_block %}
</div>
<div class="modal-footer">
{% palette_block actions %}
<button type="button" class="btn btn-secondary">Close</button>
{% endpalette_block %}
</div>
</div>
</div>
</div>
{% endpalette_component %}