labb 0.5.0 is out

Your first page

Build a task list with a Django view and labb components. Render server-side data, compose a styled page, and use icons.

Build a small task list with the Django patterns you already use: a view prepares context and a template renders it. labb supplies the page’s components and styles; Django renders the finished HTML on the server.

This is what you are building:

Today

2 open
  • Install labb
  • Write a view
  • Render a page
<div class="w-full mx-auto">
    <c-lb.card border>
        <c-lb.card.body>
            <div class="flex items-center justify-between">
                <c-lb.card.title>Today</c-lb.card.title>
                <c-lb.badge variant="primary" size="sm">2 open</c-lb.badge>
            </div>

            <c-lb.list>
                <c-lb.list.row>
                    <c-lbi n="rmx.checkbox-circle" w="18" h="18" class="text-success shrink-0" />
                    <span class="line-through text-base-content/40">Install labb</span>
                </c-lb.list.row>
                <c-lb.list.row>
                    <c-lbi n="rmx.checkbox-blank-circle" w="18" h="18" class="text-base-content/30 shrink-0" />
                    <span>Write a view</span>
                </c-lb.list.row>
                <c-lb.list.row>
                    <c-lbi n="rmx.checkbox-blank-circle" w="18" h="18" class="text-base-content/30 shrink-0" />
                    <span>Render a page</span>
                </c-lb.list.row>
            </c-lb.list>

            <c-lb.card.actions>
                <c-lb.button variant="primary" size="sm" icon="rmx.add">Add task</c-lb.button>
            </c-lb.card.actions>
        </c-lb.card.body>
    </c-lb.card>
</div>

Add the view

Create a view that passes tasks and their open count to a template. labb does not change how views, queries, or template context work.

tasks/views.py
from django.shortcuts import render

TASKS = [
    {"title": "Install labb", "done": True},
    {"title": "Write a view", "done": False},
    {"title": "Render a page", "done": False},
]


def today(request):
    return render(request, "tasks/today.html", {
        "tasks": TASKS,
        "open_count": sum(1 for task in TASKS if not task["done"]),
    })

Map the site root to that view:

urls.py
from django.urls import path
from tasks import views

urlpatterns = [
    path("", views.today, name="today"),
]

Build the template

Create tasks/today.html. The example extends the base.html you set up during installation; it needs <c-lb.m.dependencies /> in its <head> so the compiled CSS loads.

Use labb components as tags. Nest them in the same structure you would use for HTML:

tasks/today.html
{% extends "base.html" %}

{% block content %}
<c-lb.card border class="w-full max-w-md">
    <c-lb.card.body>

        <div class="flex items-center justify-between">
            <c-lb.card.title>Today</c-lb.card.title>
            <c-lb.badge variant="primary" size="sm">{{ open_count }} open</c-lb.badge>
        </div>

        <c-lb.list>
            {% for task in tasks %}
            <c-lb.list.row>
                {% if task.done %}
                    <c-lbi n="rmx.checkbox-circle" w="18" h="18" class="text-success shrink-0" />
                    <span class="line-through text-base-content/40">{{ task.title }}</span>
                {% else %}
                    <c-lbi n="rmx.checkbox-blank-circle" w="18" h="18" class="text-base-content/30 shrink-0" />
                    <span>{{ task.title }}</span>
                {% endif %}
            </c-lb.list.row>
            {% endfor %}
        </c-lb.list>

        <c-lb.card.actions>
            <c-lb.button variant="primary" size="sm" icon="rmx.add">Add task</c-lb.button>
        </c-lb.card.actions>

    </c-lb.card.body>
</c-lb.card>
{% endblock %}

Read the component structure

<c-lb.card> contains <c-lb.card.body> and <c-lb.card.actions>. The dot identifies a component within the card family. Each piece has a focused responsibility, so you can arrange the card’s title, content, and actions without a long list of layout props.

The {% for %} loop and {% if %} branch remain ordinary Django template code. Components accept the surrounding content as a slot, so you can put loops, conditions, and variables inside them.

The icon="rmx.add" prop renders the button icon. The standalone <c-lbi> tags render the status icons in each row. Search the icon catalogue before adding a name: an invalid name produces no icon and no template error.

labb icons search "checkbox"

Start the page

Run the CSS watcher and Django server in separate terminals:

labb dev                    # terminal 1
python manage.py runserver  # terminal 2

Open http://localhost:8000. If the page renders without styles, check that labb dev is running. It scans your templates for the utility classes it needs to compile.

Next steps

You now have the basic labb workflow: keep your Django view, compose the template from components, and run the CSS watcher during development. Browse the component docs to expand the page, or extract repeated markup into a component of your own.

Explore blocks