Skip to content

SmileyChris/django-includecontents

Repository files navigation

Django IncludeContents

PyPI version Django Support

Component-like Django template tags with HTML syntax support.

Features

  • 🧩 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>)

Quick Start

Installation

pip install django-includecontents

Setup

Replace your Django template backend in settings.py:

TEMPLATES = [
    {
        'BACKEND': 'includecontents.django.DjangoTemplates',
        # ... rest of your template config
    },
]

Create a Component

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>

Use the Component

<include:welcome-card title="Hello World" subtitle="Getting started">
    <p>Your component content goes here!</p>
</include:welcome-card>

Result

<div class="card">
    <h2>Hello World</h2>
    <p>Getting started</p>
    <div class="content">
        <p>Your component content goes here!</p>
    </div>
</div>

Template Tag Syntax

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 %}

Documentation

📚 Full Documentation

Examples

Named Content Blocks

<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>

Conditional Wrapping

{% load includecontents %}
{% wrapif user.is_authenticated %}
    <a href="/profile" class="user-link">
        {% contents %}Welcome, {{ user.name }}{% endcontents %}
    </a>
{% endwrapif %}

Dynamic Components

<include:button variant="primary" {disabled} class:loading="{{ is_processing }}">
    {% if is_processing %}Processing...{% else %}Submit{% endif %}  
</include:button>

Icons

# 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" />

Requirements

  • Python: 3.8+
  • Django: 3.2+

License

MIT License. See LICENSE for details.

Contributing

Contributions welcome! Please see our GitHub Issues for bug reports and feature requests.

Support