Files
2018-lpon-site/lpon_site/templates/block/breadcrumbs.html
T

78 lines
6.3 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{% load static %}{% comment %}
Шаблон "Хлебные крошки" (breadcrumbs).
ЗАЧЕМ ЭТОТ БЛОК:
Показывает пользователю путь от главной страницы до текущей
("Главная > Каталог > Винил > The Beatles > Abbey Road"),
помогая ориентироваться в структуре сайта + SEO
Первый пункт (ссылка "Главная") — вставляется САМИМ этим шаблоном,
без участия контекста. Она одинакова абсолютно на всех страницах
сайта, поэтому передавать её через каждую вьюху не нужно: переменная
`breadcrumbs`, которую передаёт вызывающая вьюха, НЕ должна содержать
пункт "Главная" — начинайте сразу со следующего уровня (например,
"Каталог"), см. КОНТРАКТ ниже.
Вместо слова "Главная" используется готовая иконка домика из статики
проекта — public/static/svgs/ico-home.svg, подключаемая через <img />,
БЕЗ подключения иконочного шрифта (Font Awesome, IcoMoon и т.п.).
Пока иконок в проекте немного, тянуть ради них целый шрифт (лишние
килограммы + лишний HTTP-запрос + зависимость от CDN) — невыгодно;
один SVG-файл дешевле и не требует внешних подключений.
ВАЖНО про цвет иконки: иконка из img-тега НЕ наследует
цвет текста и не меняется на hover — она остаётся такой, какая
нарисована в самом файле (чёрная заливка). Чтобы иконка оставалась
видимой на тёмном фоне в тёмной теме, применён CSS-фильтр dark:invert
(инвертирует чёрный в белый только в тёмной теме, в светлой теме
фильтр не применяется).
КОНТРАКТ (что именно должна передать вызывающая вьюха/шаблон):
Контекстная переменная `breadcrumbs` — список (или любой другой iterable)
объектов с двумя атрибутами (БЕЗ пункта "Главная" — его добавляет сам
шаблон, см. выше):
- title: str — видимый текст пункта ("Каталог", "Винил"...);
- url: str | None — ссылка на пункт.
Если url = None (или отсутствует/пуст) — пункт
считается ТЕКУЩЕЙ страницей и рендерится БЕЗ ссылки,
с атрибутом aria-current="page".
Обычно url=None указывают только у ПОСЛЕДНЕГО пункта.
В проекте для этого используется dataclass `BreadcrumbItem` — см. подробное
объяснение (с комментариями "для новичков") прямо в docstring класса в файле
lpon_site/frontend/views.py. Шаблону не важно, dataclass это, NamedTuple или
просто объект с нужными атрибутами — главное, чтобы у каждого элемента были
поля `title` и `url`.
{% endcomment %}{% if breadcrumbs %}<nav aria-label="Хлебные крошки" class="px-4 py-2 text-sm text-slate-500 dark:text-slate-100 hidden md:block bg-slate-50 dark:bg-slate-900 m-2">
{# aria-label="Хлебные крошки" — для доступности, чтобы скринридеры озвучивали #}
{# пользователю, что это именно хлебные крошки, а не просто список ссылок. #}
{# hidden md:block — скрываем на маленьких экранах (мобильных) #}
<ol class="flex flex-wrap items-center gap-x-2">{% comment %}
ol вместо ul — потому что это упорядоченный список, а не просто
набор ссылок. Важный момент для доступности и SEO.{% endcomment %}
<li class="flex items-center gap-x-2">{# Ссылка на главную (домик) #}
{# пунктирное подчёркивание и цвет теперь задаются типовым стилем #}
{# ссылок (см. css/tailwind-custom.css, @layer base { a {...} }); #}
{# opacity-70/hover/transition — собственный эффект именно для иконки-домика. #}
<a href="/" aria-label="Главная" class="opacity-70 hover:opacity-100 transition-opacity py-0.5">
<img src="{% static 'svgs/ico-home.svg' %}" alt="" aria-hidden="true" class="w-5 h-4 dark:invert">
</a>
</li>
{% for crumb in breadcrumbs %}
<li class="flex items-center gap-x-2">
{# Разделитель перед пунктом #}<span aria-hidden="true" class="text-slate-400 dark:text-slate-600">/</span>
{% if crumb.url and not forloop.last %}
{# Обычный пункт со ссылкой (не последний и с заданным url). #}
{# Класс не нужен — типовое оформление ссылки (пунктир, цвет, ховер) #}
{# задаётся автоматически через css/tailwind-custom.css, @layer base { a {...} }. #}
<a href="{{ crumb.url }}">{{ crumb.title }}</a>
{% else %}
{# Текущая страница: без ссылки, с aria-current="page" для доступности и SEO #}
<span aria-current="page" class="font-medium">{{ crumb.title }}</span>
{% endif %}
</li>
{% endfor %}
</ol>
</nav>{% endif %}