cotton
for
docs syntax
HTML: Snippets will be shown in HTML-like syntax.
Native: Snippets will be shown in native Django template syntax.

Usage Patterns

Basics

  • Cotton components should be placed in the templates/cotton folder ('cotton' path is configurable using COTTON_DIR).
  • The templates folder can be located in either an app-level or top-level project root folder.

Naming

Cotton uses the following naming conventions:

  • By default, component file names are in snake_case (my_component.html).
  • kebab-case filenames (my-component.html) can be enabled with COTTON_SNAKE_CASED_NAMES = False see configuration.
  • Components are included in templates using kebab-case name of the component: <c-my-component />

Subfolders

  • Components in subfolders can be called using dot notation to represent folder levels.
  • A component in sidebar/menu/link.html would be included with <c-sidebar.menu.link />

Tag Syntax

Cotton components can be used with HTML-like syntax or native Django template tags.

HTML-like Syntax

Cotton enables you to use html-like syntax to include your components. This tends to enhance productivity as editors and IDEs often provide autocompletion, auto closing and syntax highlighting of xml-like tags out of the box.

With content
<c-button>
    Click me
</c-button>
{% cotton button %}
    Click me
{% endcotton %}

Native Template Tags

If you prefer using native template tags you can use Cotton's template tags.

HTML Syntax
HTML-like syntax
<c-button title="Click me">
    Click here
</c-button>
Native Syntax
Native Django template syntax
{% cotton button title="Click me" %}
    Click here
{% endcotton %}

Syntax Comparison

Feature HTML-like Syntax Native Template Syntax
Component <c-button>...</c-button> {% cotton button %}...{% endcotton %}
Self-closing Component <c-button /> {% cotton button / %}
Variables <c-vars title /> {% cotton:vars title %}
Named Slot
<c-slot name="header">
...
</c-slot>
{% cotton:slot header %}
...
{% endcotton:slot %}

The index.html component

When your component has sub-components, you can define the default component of a folder by adding an index.html. This helps to keep your project structure tidy and reduce additional code in the template.

Project structure
templates/
├── cotton/
│   ├── card/
│   │   ├── index.html
│   │   ├── header.html
Usage
<c-card>
    <c-card.header>...</c-card.header>
</c-card>
{% cotton card %}
    {% cotton card.header %}...{% endcotton %}
{% endcotton %}

Attribute Proxying Pattern

The :attrs dynamic attribute enables us to create wrapper components that proxy all their attributes to an inner component:

view.html
<c-outer
    class="outer-class"
    :count="42"
    :enabled="False">
    Content passed to inner component
</c-outer>
{% cotton outer class="outer-class" :count="42" :enabled="False" %}
    Content passed to inner component
{% endcotton %}
cotton/outer.html
<c-inner :attrs="attrs">{{ slot }}</c-inner>
{% cotton inner :attrs="attrs" %}{{ slot }}{% endcotton %}
cotton/inner.html
{{ class }}     <!-- "outer-class" -->
{{ count }}     <!-- 42 -->
{{ enabled }}   <!-- False -->
{{ slot }}      <!-- Content passed to inner component -->

The attributes are passed through to the inner component with their original types preserved (strings, numbers, booleans, lists, etc.), making this pattern ideal for creating higher-order components.

This pattern is particularly useful for Django form fields, where you might create a component hierarchy that passes Django widget attributes through multiple layers while adding labels, error handling, and styling at each level.