Implements Issue #35 with category snippets, article category routing, category-aware templates, and category RSS feeds with tests. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
65 lines
4.9 KiB
HTML
65 lines
4.9 KiB
HTML
{% extends 'base.html' %}
|
|
{% load core_tags seo_tags %}
|
|
{% block title %}Articles | No Hype AI{% endblock %}
|
|
{% block head_meta %}
|
|
{% canonical_url page as canonical %}
|
|
<link rel="canonical" href="{{ canonical }}" />
|
|
<meta name="description" content="Latest No Hype AI articles and benchmark-driven reviews." />
|
|
<meta property="og:type" content="website" />
|
|
<meta property="og:title" content="Articles | No Hype AI" />
|
|
<meta property="og:url" content="{{ canonical }}" />
|
|
{% endblock %}
|
|
{% block content %}
|
|
|
|
<!-- Page Header -->
|
|
<div class="py-8 md:py-12 border-b border-zinc-200 dark:border-zinc-800 mb-12">
|
|
{% if active_category %}
|
|
<nav aria-label="Breadcrumb" class="font-mono text-xs text-zinc-500 mb-4">
|
|
<a href="/" class="hover:text-brand-cyan">Home</a> / <a href="/articles/" class="hover:text-brand-cyan">Articles</a> / <span>{{ active_category.name }}</span>
|
|
</nav>
|
|
{% endif %}
|
|
<h1 class="font-display font-black text-4xl md:text-6xl mb-3">{% if active_category %}{{ active_category.name }}{% else %}{{ page.title }}{% endif %}</h1>
|
|
{% if active_category.description %}
|
|
<p class="text-zinc-600 dark:text-zinc-400 mb-6">{{ active_category.description }}</p>
|
|
{% endif %}
|
|
|
|
<!-- Category Filters -->
|
|
<div class="flex flex-wrap gap-3 mb-4">
|
|
<a href="/articles/{% if active_tag %}?tag={{ active_tag }}{% endif %}" class="px-4 py-2 font-mono text-sm font-bold border transition-colors {% if not active_category %}bg-brand-dark text-brand-light dark:bg-brand-light dark:text-brand-dark border-transparent{% else %}bg-transparent text-zinc-600 dark:text-zinc-400 border-zinc-300 dark:border-zinc-700 hover:text-brand-dark dark:hover:text-brand-light hover:border-brand-dark dark:hover:border-brand-light{% endif %}" {% if not active_category %}aria-current="page"{% endif %}>All Categories</a>
|
|
{% for category_link in category_links %}
|
|
<a href="{{ category_link.url }}{% if active_tag %}?tag={{ active_tag }}{% endif %}" class="px-4 py-2 font-mono text-sm font-bold border transition-colors {% if active_category and active_category.slug == category_link.category.slug %}bg-brand-dark text-brand-light dark:bg-brand-light dark:text-brand-dark border-transparent{% else %}bg-transparent text-zinc-600 dark:text-zinc-400 border-zinc-300 dark:border-zinc-700 hover:text-brand-dark dark:hover:text-brand-light hover:border-brand-dark dark:hover:border-brand-light{% endif %}" {% if active_category and active_category.slug == category_link.category.slug %}aria-current="page"{% endif %}>{{ category_link.category.name }}</a>
|
|
{% endfor %}
|
|
</div>
|
|
|
|
<!-- Tag Filters -->
|
|
<div class="flex flex-wrap gap-3">
|
|
<a href="{% if active_category %}{{ active_category_url }}{% else %}/articles/{% endif %}" class="px-4 py-2 font-mono text-sm font-bold border transition-colors {% if not active_tag %}bg-brand-dark text-brand-light dark:bg-brand-light dark:text-brand-dark border-transparent{% else %}bg-transparent text-zinc-600 dark:text-zinc-400 border-zinc-300 dark:border-zinc-700 hover:text-brand-dark dark:hover:text-brand-light hover:border-brand-dark dark:hover:border-brand-light{% endif %}" {% if not active_tag %}aria-current="page"{% endif %}>All Tags</a>
|
|
{% for tag in available_tags %}
|
|
<a href="{% if active_category %}{{ active_category_url }}{% else %}/articles/{% endif %}?tag={{ tag.slug }}" class="px-4 py-2 font-mono text-sm font-bold border transition-colors {% if active_tag == tag.slug %}bg-brand-dark text-brand-light dark:bg-brand-light dark:text-brand-dark border-transparent{% else %}bg-transparent text-zinc-600 dark:text-zinc-400 border-zinc-300 dark:border-zinc-700 hover:text-brand-dark dark:hover:text-brand-light hover:border-brand-dark dark:hover:border-brand-light{% endif %}" {% if active_tag == tag.slug %}aria-current="page"{% endif %}>{{ tag.name }}</a>
|
|
{% endfor %}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Article List -->
|
|
<div class="space-y-8">
|
|
{% for article in articles %}
|
|
{% include 'components/article_card.html' with article=article %}
|
|
{% empty %}
|
|
<p class="font-mono text-zinc-500 py-12 text-center">No articles found.</p>
|
|
{% endfor %}
|
|
</div>
|
|
|
|
<!-- Pagination -->
|
|
{% if articles.has_previous or articles.has_next %}
|
|
<nav aria-label="Pagination" class="mt-12 flex justify-center items-center gap-4 font-mono text-sm">
|
|
{% if articles.has_previous %}
|
|
<a href="?page={{ articles.previous_page_number }}{% if active_tag %}&tag={{ active_tag }}{% endif %}" class="px-6 py-3 border border-zinc-300 dark:border-zinc-700 hover:bg-zinc-100 dark:hover:bg-zinc-800 transition-colors">← Previous</a>
|
|
{% endif %}
|
|
<span class="text-zinc-500">Page {{ articles.number }} of {{ paginator.num_pages }}</span>
|
|
{% if articles.has_next %}
|
|
<a href="?page={{ articles.next_page_number }}{% if active_tag %}&tag={{ active_tag }}{% endif %}" class="px-6 py-3 border border-zinc-300 dark:border-zinc-700 hover:bg-zinc-100 dark:hover:bg-zinc-800 transition-colors">Next →</a>
|
|
{% endif %}
|
|
</nav>
|
|
{% endif %}
|
|
{% endblock %}
|