Component-like Django template tags with HTML syntax support. Full feature parity between Django templates and Jinja2.
- π§© Component Templates: Create reusable template components with isolated contexts
- π HTML Syntax: Use familiar HTML-like syntax for components (
<include:my-card>) - π― Props System: Define required and optional props with validation
- π¨ Advanced Styling: Conditional classes, extended classes, and CSS utilities
- π Conditional Wrapping: Clean conditional HTML wrapper syntax with
{% wrapif %} - π Icon System: SVG sprite generation from Iconify icons and local SVG files (
<icon:home>)
pip install django-includecontentsChoose your template engine:
Django Templates
Replace your Django template backend in settings.py:
TEMPLATES = [
{
'BACKEND': 'includecontents.django.DjangoTemplates',
# ... rest of your template config
},
]Jinja2
Add the Jinja2 extension in settings.py:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.jinja2.Jinja2',
'OPTIONS': {
'extensions': [
'includecontents.jinja2.IncludeContentsExtension',
],
},
},
]See Jinja2 Setup for complete instructions.
templates/components/welcome-card.html
{# props title, subtitle="" #}
<div class="card">
<h2>{{ title }}</h2>
{% if subtitle %}<p>{{ subtitle }}</p>{% endif %}
<div class="content">{{ contents }}</div>
</div><include:welcome-card title="Hello World" subtitle="Getting started">
<p>Your component content goes here!</p>
</include:welcome-card><div class="card">
<h2>Hello World</h2>
<p>Getting started</p>
<div class="content">
<p>Your component content goes here!</p>
</div>
</div>If you prefer traditional Django template syntax:
{% load includecontents %}
{% includecontents "components/welcome-card.html" title="Hello World" subtitle="Getting started" %}
<p>Your component content goes here!</p>
{% endincludecontents %}π Full Documentation
- Getting Started - Installation and setup
- Jinja2 Setup - Jinja2 template engine setup
- Quick Start Guide - Get started in 5 minutes
- HTML Components - Modern component syntax
- Best Practices - Building great components
<include:article title="My Article">
<content:header>
<h1>Article Title</h1>
<p>By {{ author }}</p>
</content:header>
<p>Main article content...</p>
<content:sidebar>
<h3>Related Links</h3>
</content:sidebar>
</include:article>{% load includecontents %}
{% wrapif user.is_authenticated %}
<a href="/profile" class="user-link">
{% contents %}Welcome, {{ user.name }}{% endcontents %}
</a>
{% endwrapif %}<!-- Vue.js and Alpine.js attributes work seamlessly -->
<include:button @click="handleClick()" :disabled="isLoading">
Submit
</include:button>
<include:modal x-on:click="open = false" x-show="open">
Modal content
</include:modal>
<!-- Nested attributes for complex components -->
<include:form inner.class="form-control" button.@click="submit()">
Form content
</include:form><include:button variant="primary" {disabled} class:loading="{{ is_processing }}">
{% if is_processing %}Processing...{% else %}Submit{% endif %}
</include:button># settings.py
STATICFILES_FINDERS = [
'includecontents.icons.finders.IconSpriteFinder', # Must be first for icons
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
]
INCLUDECONTENTS_ICONS = {
'icons': [
'mdi:home', # Use as <icon:home>
'tabler:user', # Use as <icon:user>
'icons/logo.svg' # Use as <icon:logo>
]
}Note: Icon names auto-generate from config:
'mdi:home'β<icon:home>,'icons/logo.svg'β<icon:logo>
<icon:home class="w-6 h-6" />
<icon:user class="avatar" use.role="img" />
<icon:logo class="brand" />- Python: 3.8+
- Django: 3.2+
MIT License. See LICENSE for details.
Contributions welcome! Please see our GitHub Issues for bug reports and feature requests.
- π Documentation
- π Issue Tracker
- π¬ Discussions