{% extends 'django_cotton_gallery/base.html' %} {% load catalog_tags i18n %} {% block title %}{% trans "Home" %}{% endblock %} {% block content %}
{% trans "Cotton component library" %}

{% trans "Production-ready components for" %} Django Cotton

{% trans "Stack-agnostic playground for your Cotton components. Every component is annotated, copy-and-pasteable, and themable through your design tokens — bring your own stack (Tailwind, HTMX, Alpine, your own bundle…) and start shipping." %}

{% trans "Get started" %} {% if categories %} {% trans "Browse components" %} {% else %} {% trans "Read the docs" %} {% endif %}
{% if categories %}

{{ categories|total_components }}

{% trans "Components" %}

{% for cat_name, subcategories in categories.items %}

{{ subcategories|component_count }}

{{ cat_name }}

{% endfor %}
{% endif %}
Django Cotton {% for dep in cotton_gallery.dependencies %} {{ dep.name|capfirst }} {% endfor %}
{% if not categories %}
{% if not onboarding.cotton_dir_exists %}

{% trans "Cotton folder not found" %}

{% blocktranslate with path=onboarding.cotton_dir_abs %}The gallery is looking for components in {{ path }}, but that folder doesn't exist yet.{% endblocktranslate %}

{% trans "Two ways to fix it:" %}

  1. {% blocktranslate with subfolder=onboarding.cotton_subfolder %}Create the folder at {{ subfolder }}/ inside one of your TEMPLATES['DIRS'] entries (or any installed app's templates/ folder when APP_DIRS is on) and drop a component file in it.{% endblocktranslate %}
  2. {% blocktranslate with subfolder=onboarding.cotton_subfolder %}If your components live under a different folder name, change the gallery's lookup by setting COTTON_DIR = '...' in your settings.py. The default is '{{ subfolder }}' — set it to whatever name your components folder uses.{% endblocktranslate %}
{% else %}

{% trans "No components yet" %}

{% blocktranslate with path=onboarding.cotton_dir_abs %}Drop your first Cotton component into {{ path }} and the gallery will pick it up automatically — no restart needed.{% endblocktranslate %}

{% endif %}

{% trans "Example layout:" %}

{{ onboarding.cotton_subfolder }}/
├── atoms/
│   ├── ui/
│   │   └── button.html        <c-atoms.ui.button />
│   └── form/
│       └── input.html         <c-atoms.form.input />
└── molecules/
    └── form/
        └── form-field.html    <c-molecules.form.form-field />
{% comment %} Surface the language-switcher requirement only when the consumer hasn't mounted django.conf.urls.i18n. If `set_language` resolves, their setup is already complete and the switcher is visible in the sidebar — no need to remind them. {% endcomment %} {% url 'set_language' as i18n_setup_url %} {% if not i18n_setup_url %}

{% trans "Optional: enable language switching" %}

{% blocktranslate %}The gallery is translated into English, Spanish, Basque, and French — but the language dropdown only appears when your project mounts Django's i18n URLs and LocaleMiddleware. Add both in your urls.py and settings.py to enable it.{% endblocktranslate %}

{% trans "See the i18n setup steps →" %}

{% endif %}
{% endif %} {% for cat_name, subcategories in categories.items %}

{% if cat_name %}{{ cat_name }}{% else %}{% trans "Components" %}{% endif %}

{{ subcategories|component_count }}
{% for sub_name, components in subcategories.items %} {% if sub_name %}

{{ sub_name }}

{% endif %}
{% for comp in components %}
<c-{{ comp.tag_path }} />

{{ comp.name }}

{% if comp.description %}

{{ comp.description }}

{% else %}

{{ cat_name }}{% if sub_name %} / {{ sub_name }}{% endif %}

{% endif %}
{% endfor %}
{% endfor %}
{% endfor %} {% endblock %}