| name | template |
| description | Create or edit Django templates with cotton components, template partials, and proper Tailwind usage. Use when creating/editing HTML templates, adding components, or when the user mentions templates, UI, or frontend work. |
| allowed-tools | Read, Grep, Glob |
Templates and Cotton Components
When to Use This Skill
Use this Skill when:
- User asks to create a new template, page, or component
- User wants to edit existing templates
- User mentions "UI", "frontend", "template", "HTML"
- Adding new pages to an app
- Creating reusable components
- Working with HTMX or Alpine.js in templates
Template Locations
freedom_ls/<app_name>/templates/
├── <app_name>/ # Page templates (app-namespaced)
├── cotton/ # Cotton components
└── partials/ # Template partials
Base template: freedom_ls/base/templates/_base.html
Naming Conventions
- Pages:
freedom_ls/<app_name>/templates/<app_name>/<page>.html
- Cotton components:
freedom_ls/<app_name>/templates/cotton/<component>.html
- Partials:
freedom_ls/<app_name>/templates/partials/<partial>.html
Standard Page Template
{% extends '_base.html' %}
{% block title %}Page Title{% endblock %}
{% block content %}
<div class="space-y-6">
<h1>{{ page_title }}</h1>
<!-- Content -->
</div>
{% endblock %}
Common Blocks
From _base.html:
{% block title %} - Page title
{% block content %} - Main content
{% block header %} - Header section
{% block extra_head %} - Additional head content
{% block extra_body %} - After main content
Cotton Components
Reusable UI components using <c-component-name> syntax.
Creating a Component
Location: freedom_ls/<app_name>/templates/cotton/<name>.html
<c-vars
prop1="default"
prop2=""
class=""
/>
<div class="{{ class }}" {{ attrs }}>
{{ slot }}
</div>
{% comment %}
Usage:
<c-name prop1="value">Content</c-name>
{% endcomment %}
Using Components
<c-button>Click me</c-button>
<c-button variant="primary" href="/url">Link</c-button>
<c-loading-indicator id="loader" message="Loading..." />
<c-modal id="confirm" title="Confirm">Are you sure?</c-modal>
Best Practices
- Define all props in
<c-vars> with defaults
- Support
class and {{ attrs }} for flexibility
- Use
{{ slot }} for content
- Include usage examples in comments
- Don't reimplement existing components
Template Partials
Separate Files
Location: freedom_ls/<app_name>/templates/partials/<name>.html
<!-- Include in template -->
{% include "partials/header.html" %}
<!-- Load via HTMX -->
<div hx-get="{% url 'app:partial' %}" hx-trigger="load"></div>
Inline Partials (Django built-in)
Inline partials are a Django 6+ built-in feature ({% partialdef %} / {% partial %} tags are part of the Django Template Language).
{% partialdef "partial_name" %}
<!-- content -->
{% endpartialdef %}
<!-- Use it -->
{% partial "partial_name" %}
<!-- Pass context -->
{% with foo=bar %}
{% partial "partial_name" %}
{% endwith %}
Note: Use {% with %} to pass context, NOT {% partial "name" foo=bar %}
HTMX Integration
HTMX loaded globally. CSRF token set in _base.html via hx-headers. Do not add CSRF tokens to individual requests.
View Conventions
- Prefix view functions returning partials with
partial_ (e.g., partial_course_toc, partial_list_courses)
- Return standard
render(request, template, context) — no special HTMX response classes needed
- Return HTTP 422 for HTMX validation errors
Partialdef Naming
- Use kebab-case names for
{% partialdef %} blocks (e.g., {% partialdef view-course-button %})
Common Patterns
<!-- Load on page load -->
<div hx-get="{% url 'app:endpoint' %}" hx-trigger="load"></div>
<!-- Form submission -->
<form hx-post="{% url 'app:submit' %}" hx-target="#result">
<c-button type="submit">Submit</c-button>
</form>
<!-- Click to load -->
<c-button hx-get="{% url 'app:more' %}" hx-target="#content">
Load More
</c-button>
Alpine.js
Loaded globally for reactive components.
<div x-data="{ open: false }">
<c-button @click="open = !open">Toggle</c-button>
<div x-show="open">Content</div>
</div>
Workflow
Creating Templates
- Check location -
freedom_ls/<app_name>/templates/<app_name>/
- Check existing templates - Follow established patterns
- Check available components -
ls freedom_ls/*/templates/cotton/
- Check Tailwind classes -
cat tailwind.components.css
- Write template - Extend
_base.html, use existing components
- Build CSS -
npm run tailwind_build
Editing Templates
- Read the template
- Understand structure (blocks, components, HTMX)
- Check dependencies (partials, components)
- Make focused changes
- Don't refactor unnecessarily
Key Rules
- Check
tailwind.components.css first - Use component classes
- Don't duplicate base styles - Typography/forms are pre-styled
- Don't create cotton components for one-off use - Use partials
- Don't hardcode URLs - Use
{% url %} tag
- Don't skip app namespacing - Templates in
<app_name>/ subdirectory