Attributes

Everything on a component tag is an attribute. Each one is available in the component by name, and all of them together as {{ attrs }}.

Strings

A quoted value is a string. It can contain template syntax, which is rendered first, so the component still receives a string:

<c-weather unit="c" />
<c-weather unit="{{ today.unit }}" icon="fa-{{ today.icon }}" />
{% cotton weather unit="c" /%}
{% cotton weather unit="{{ today.unit }}" icon="fa-{{ today.icon }}" /%}

Dynamic values with :

A : prefix passes the value itself rather than a string. The value is a context variable or a Python literal:

<c-weather :today="today" />
<c-chart :height="300" :animate="True" :fallback="None" />
<c-select :options="['no', 'yes', 'maybe']" />
<c-table :config="{'sortable': True, 'page_size': 20}" />
{% cotton weather :today="today" /%}
{% cotton chart :height="300" :animate="True" :fallback="None" /%}
{% cotton select :options="['no', 'yes', 'maybe']" /%}
{% cotton table :config="{'sortable': True, 'page_size': 20}" /%}

Template expressions work inside literals too, rendered before the literal is evaluated:

<c-gallery :slides="['{{ image1 }}', '{{ image2 }}']" />
<c-row :highlight="{% if important %}True{% else %}False{% endif %}" />
{% cotton gallery :slides="['{{ image1 }}', '{{ image2 }}']" /%}
{% cotton row :highlight="{% if important %}True{% else %}False{% endif %}" %}{% endcotton %}

Unquoted values

A value without quotes is looked up as a variable, falling back to the literal text if there is no such variable:

<c-weather unit=unit />
{% cotton weather unit=unit /%}

Boolean attributes

An attribute with no value is True:

<c-input name="email" required />
{% cotton input name="email" required /%}

cotton/input.html
{% if required %}<span>*</span>{% endif %}

In {{ attrs }} it prints as the bare name, required.

Passing a dictionary with :attrs

:attrs takes a dictionary and merges its keys in alongside the other attributes. Useful when a view, or a wrapping component, already holds them:

<c-input :attrs="widget_attrs" required />
{% cotton input :attrs="widget_attrs" required /%}

cotton/outer.html
<c-inner :attrs="attrs">{{ slot }}</c-inner>
{% cotton inner :attrs="attrs" %}{{ slot }}{% endcotton %}

See attribute proxying.

Alpine's : shorthand

A single : is Cotton's dynamic prefix, so escape Alpine's x-bind shorthand with ::. The attribute reaches {{ attrs }} with one colon:

<c-button ::class="open ? 'active' : ''" />
<!-- <button :class="open ? 'active' : ''"> -->
{% cotton button ::class="open ? 'active' : ''" /%}
<!-- <button :class="open ? 'active' : ''"> -->

Names

Hyphenated attributes are available as snake_case variables, data-id becomes {{ data_id }}, while {{ attrs }} prints them as written. only and is are reserved: only isolates the component and is names a dynamic component, and neither reaches {{ attrs }}.

next c-vars

View this page as markdown, handy as context for your AI tools. Full index at /llms.txt. Spotted a mistake? Edit this page on GitHub.