COTTON_DIR
).templates
folder can be located in either an app-level or top-level project root folder.Cotton uses the following naming conventions:
COTTON_SNAKE_CASED_NAMES = False
see configuration.<c-my-component />
<c-sidebar.menu.link />
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.
templates/
├── cotton/
│ ├── card/
│ │ ├── index.html
│ │ ├── header.html
<c-card>
<c-card.header>...</c-card.header>
</c-card>
<c-my-component />
or have a closing tag <c-my-component></c-my-component>
The :attrs
dynamic attribute enables us to create wrapper components that proxy all their attributes to an inner component:
<c-outer
class="outer-class"
:count="42"
:enabled="False">
Content passed to inner component
</c-outer>
<c-inner :attrs="attrs">{{ slot }}</c-inner>
{{ 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.