synops/maskinrommet/src/templates/archive.html
vegard 26c6a3b8d9 Dynamiske sider (oppgave 14.15): kategori, arkiv, søk, om-side
Implementerer fire nye dynamiske sidetyper for publiseringssamlinger:

- Kategori-sider: filtrert på tag-edges, paginert med cache
- Arkiv: kronologisk med månedsgruppering, paginert med cache
- Søk: PG fulltekst med tsvector/ts_rank, paginert med cache
- Om-side: statisk CAS-node (page_role: "about"), immutable cache

Teknisk:
- Ny migrasjon (011): tsvector-kolonne + GIN-indeks + trigger for søk
- Nye Tera-templates: category.html, archive.html, search.html, about.html
- DynamicPageCache for in-memory caching av dynamiske sider
- Ruter for /pub/{slug}/kategori/{tag}, arkiv, sok, om
- Custom domain-varianter for alle nye sidetyper

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 02:39:06 +00:00

126 lines
3.1 KiB
HTML

{% extends "base.html" %}
{% block title %}Arkiv — {{ collection_title }}{% endblock %}
{% block extra_css %}
.dynamic-page {
max-width: var(--layout-max-width);
margin: 2rem auto;
padding: 0 1rem;
}
.dynamic-page__header {
margin-bottom: 2rem;
padding-bottom: 1rem;
border-bottom: 2px solid var(--color-accent);
}
.dynamic-page__title {
font-family: var(--font-heading);
font-size: 2rem;
color: var(--color-primary);
}
.dynamic-page__subtitle {
color: var(--color-muted);
margin-top: 0.25rem;
}
.month-group {
margin-bottom: 2rem;
}
.month-group__heading {
font-family: var(--font-heading);
font-size: 1.25rem;
color: var(--color-primary);
padding-bottom: 0.5rem;
border-bottom: 1px solid #e0e0e0;
margin-bottom: 0.75rem;
}
.article-list { list-style: none; }
.article-list__item {
padding: 1rem 0;
border-bottom: 1px solid #f5f5f5;
}
.article-list__item:last-child { border-bottom: none; }
.article-list__title {
font-family: var(--font-heading);
font-size: 1.2rem;
color: var(--color-primary);
line-height: 1.3;
margin-bottom: 0.15rem;
}
.article-list__meta {
font-size: 0.8rem;
color: var(--color-muted);
}
.pagination {
display: flex;
gap: 0.5rem;
justify-content: center;
margin-top: 2rem;
padding-top: 1rem;
border-top: 1px solid #f0f0f0;
}
.pagination a, .pagination span {
padding: 0.5rem 1rem;
border: 1px solid #e0e0e0;
border-radius: 4px;
font-size: 0.9rem;
}
.pagination .current {
background: var(--color-accent);
color: #fff;
border-color: var(--color-accent);
}
.empty-state {
text-align: center;
padding: 3rem 1rem;
color: var(--color-muted);
}
@media (max-width: 768px) {
.dynamic-page__title { font-size: 1.5rem; }
.article-list__title { font-size: 1.05rem; }
}
{% endblock %}
{% block content %}
<div class="dynamic-page">
<div class="dynamic-page__header">
<h1 class="dynamic-page__title">Arkiv</h1>
<p class="dynamic-page__subtitle">{{ total_articles }} artikler totalt</p>
</div>
{% if month_groups | length > 0 %}
{% for group in month_groups %}
<section class="month-group">
<h2 class="month-group__heading">{{ group.label }}</h2>
<ul class="article-list">
{% for item in group.articles %}
<li class="article-list__item">
<h3 class="article-list__title"><a href="{{ base_url }}/{{ item.short_id }}">{{ item.title }}</a></h3>
<div class="article-list__meta">{{ item.published_at_short }}</div>
</li>
{% endfor %}
</ul>
</section>
{% endfor %}
{% if total_pages > 1 %}
<nav class="pagination">
{% if current_page > 1 %}
<a href="{{ base_url }}/arkiv?side={{ current_page - 1 }}">Forrige</a>
{% endif %}
{% for p in page_range %}
{% if p == current_page %}
<span class="current">{{ p }}</span>
{% else %}
<a href="{{ base_url }}/arkiv?side={{ p }}">{{ p }}</a>
{% endif %}
{% endfor %}
{% if current_page < total_pages %}
<a href="{{ base_url }}/arkiv?side={{ current_page + 1 }}">Neste</a>
{% endif %}
</nav>
{% endif %}
{% else %}
<div class="empty-state">Ingen publiserte artikler ennå.</div>
{% endif %}
</div>
{% endblock %}