Skip to content

maerteijn/crumbles

Repository files navigation

Crumbles

A simple library for class based view breadcrumbs for any python web framework.

CI MIT License PyPI version Python 3.10 Python 3.11 Python 3.12 Python 3.13 Ruff Checked with mypy No Dependencies

Usage

First define a specific mixin for your framework. For example Django:

from django.urls import reverse


class DjangoCrumblesViewMixin(CrumblesViewMixin):
    def url_resolve(self, *args, **kwargs):
        return reverse(*args, **kwargs)

Use the Mixin in your View classes and define the breadcrumbs:

class MyListView(View, DjangoCrumblesViewMixin):
    crumbles = (
        CrumbleDefinition(url_name="my-list-view", title="Home"),
    )

Add a default breadcrumb to the mixin like so:

class DjangoCrumblesViewMixin(CrumblesViewMixin):
    def __init__(self):
        self.crumbles = (
            CrumbleDefinition(url_name="index", title="Home"),
        ) + type(self).crumbles

    def url_resolve(self, *args, **kwargs):
        return reverse(*args, **kwargs)

You can reuse "parent" crumbles for detail pages and use a callable for url resolve arguments or for defining the title:

from operator import attrgetter, methodcaller


class MyDetailView(View, DjangoCrumblesViewMixin):
    crumbles = MyListView.crumbles + (
        CrumbleDefinition(
            url_name="my-detail-view",
            url_resolve_kwargs={"pk": attrgetter("pk")},
            title=methodcaller("__str__"),
        ),
    )

The attributes context will be retrieved from instance.object. If this is not available it will default to the View class instance itself. You can set a custom context variable (including dotted syntakt) by using crumbles_context_attribute:

class MyDetailView(View, DjangoCrumblesViewMixin):
    crumbles_context_attribute = "my_object.parent"
    ...

Rendering the breadcrumb should be done in a template. An example for Django (with bootstrap):

<nav aria-label="breadcrumb">
    <ol class="breadcrumb">
        {% for item in view.resolve_crumbles %}
            {% if forloop.last %}
                <li class="breadcrumb-item active" aria-current="page">{{ item.title }}</li>
            {% else %}
                <li class="breadcrumb-item">
                    {% if item.url %}
                        <a href="{{ item.url }}">{{ item.title}}</a>
                    {% else %}
                        {{ item.title }}
                    {% endif %}
                </li>
            {% endif %}
        {% endfor %}
    </ol>
</nav>

Development setup

First clone this repository

git clone https://github.com/maerteijn/crumbles.git

Install the python project

pyenv virtualenv crumbles  # or your alternative to create a venv
pyenv activate crumbles
make install

Linting

ruff and mypy are installed and configured

make lint

Formatting

ruff are configured

make format

Test

Pytest with coverage is default enabled

make cov

About

A simple library for class based view breadcrumbs for any python web framework

Resources

License

Stars

Watchers

Forks

Packages

No packages published