mirror of
https://gitverse.ru/kpa39l/vesti.git
synced 2026-09-29 09:55:03 +00:00
feat(web): архив опубликованных — дерево навигации по годам/месяцам + пагинация (openspec archive-navigation)
This commit is contained in:
+130
-36
@@ -1,43 +1,137 @@
|
||||
{% extends "base.html" %}
|
||||
{% block title %}Опубликовано{% endblock %}
|
||||
{% block title %}Архив — Опубликовано{% endblock %}
|
||||
{% block content %}
|
||||
<h4 class="mb-3">Опубликованные посты</h4>
|
||||
{% for p in posts %}
|
||||
<div class="card mb-3">
|
||||
<div class="card-body">
|
||||
<div class="d-flex justify-content-between">
|
||||
<span class="badge bg-secondary">#{{ p.id }} · {{ p.direction or '?' }}</span>
|
||||
<small class="text-muted">{{ p.source_name }} · {{ p.published_at | dt }}</small>
|
||||
</div>
|
||||
<div class="post-text mt-2">{{ (p.summary or p.text or '')[:2000] | markdown }}</div>
|
||||
{% if p.media_path %}
|
||||
{% set media_src = '/media/' ~ p.media_path.split('/')[-1] %}
|
||||
{% set media_ext = p.media_path.lower().rsplit('.', 1)[-1] if '.' in p.media_path else '' %}
|
||||
{% if media_ext in ['jpg','jpeg','png','gif','webp'] %}
|
||||
<a href="{{ media_src }}" target="_blank" title="Открыть полноразмер">
|
||||
<img src="{{ media_src }}" class="img-fluid rounded mt-2 d-block" style="max-height:180px" alt="медиа поста">
|
||||
</a>
|
||||
{% elif media_ext in ['mp4','webm','mov'] %}
|
||||
<video src="{{ media_src }}" controls class="mt-2 d-block" style="max-height:180px"></video>
|
||||
{% endif %}
|
||||
<div class="row">
|
||||
<!-- Левая колонка: список постов за выбранный период -->
|
||||
<div class="col-lg-9">
|
||||
<h4 class="mb-3">
|
||||
Опубликованные посты
|
||||
{% set filter_label = '' %}
|
||||
{% if nodate %}
|
||||
{% set filter_label = 'Без даты' %}
|
||||
{% elif year and month %}
|
||||
{% set filter_label = year ~ '-' ~ month %}
|
||||
{% elif year %}
|
||||
{% set filter_label = year %}
|
||||
{% endif %}
|
||||
{% if p.is_own %}<span class="badge bg-warning text-dark">⭐ СВОЙ</span>{% endif %}
|
||||
<small class="text-muted">👁 {{ p.pub_views or p.views or 0 }}</small>
|
||||
{% if p.distributed_dirs %}
|
||||
<div class="mt-2">
|
||||
<small class="text-muted">Разослан в:</small>
|
||||
{% for d in (p.distributed_dirs | from_json) %}
|
||||
<span class="badge bg-info text-dark">@dedinit_vesti_{{ d }}_ru_bot</span>
|
||||
{% endfor %}
|
||||
{% if filter_label %}
|
||||
<span class="badge bg-secondary ms-2">{{ filter_label }}</span>
|
||||
{% endif %}
|
||||
<small class="text-muted fs-6 fw-normal">({{ total }})</small>
|
||||
</h4>
|
||||
|
||||
{% for p in posts %}
|
||||
<div class="card mb-3">
|
||||
<div class="card-body">
|
||||
<div class="d-flex justify-content-between">
|
||||
<span class="badge bg-secondary">#{{ p.id }} · {{ p.direction or '?' }}</span>
|
||||
<small class="text-muted">{{ p.source_name }} · {{ p.published_at | dt }}</small>
|
||||
</div>
|
||||
<div class="post-text mt-2">{{ (p.summary or p.text or '')[:2000] | markdown }}</div>
|
||||
{% if p.media_path %}
|
||||
{% set media_src = '/media/' ~ p.media_path.split('/')[-1] %}
|
||||
{% set media_ext = p.media_path.lower().rsplit('.', 1)[-1] if '.' in p.media_path else '' %}
|
||||
{% if media_ext in ['jpg','jpeg','png','gif','webp'] %}
|
||||
<a href="{{ media_src }}" target="_blank" title="Открыть полноразмер">
|
||||
<img src="{{ media_src }}" class="img-fluid rounded mt-2 d-block" style="max-height:180px" alt="медиа поста">
|
||||
</a>
|
||||
{% elif media_ext in ['mp4','webm','mov'] %}
|
||||
<video src="{{ media_src }}" controls class="mt-2 d-block" style="max-height:180px"></video>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if p.is_own %}<span class="badge bg-warning text-dark">⭐ СВОЙ</span>{% endif %}
|
||||
<small class="text-muted">👁 {{ p.pub_views or p.views or 0 }}</small>
|
||||
{% if p.distributed_dirs %}
|
||||
<div class="mt-2">
|
||||
<small class="text-muted">Разослан в:</small>
|
||||
{% for d in (p.distributed_dirs | from_json) %}
|
||||
<span class="badge bg-info text-dark">@dedinit_vesti_{{ d }}_ru_bot</span>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if p.bundle_path %}
|
||||
<a class="btn btn-sm btn-outline-primary ms-2" href="/bundle/{{ p.bundle_path }}" target="_blank">📄 Бандл</a>
|
||||
{% endif %}
|
||||
{% if p.tg_message_id %}<span class="badge bg-light text-dark ms-2">msg #{{ p.tg_message_id }}</span>{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if p.bundle_path %}
|
||||
<a class="btn btn-sm btn-outline-primary ms-2" href="/bundle/{{ p.bundle_path }}" target="_blank">📄 Бандл</a>
|
||||
{% endif %}
|
||||
{% if p.tg_message_id %}<span class="badge bg-light text-dark ms-2">msg #{{ p.tg_message_id }}</span>{% endif %}
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="alert alert-info">Нет постов за этот период</div>
|
||||
{% endfor %}
|
||||
|
||||
{% if pages > 1 %}
|
||||
<nav aria-label="Пагинация архива">
|
||||
<ul class="pagination justify-content-center">
|
||||
<li class="page-item {% if page <= 1 %}disabled{% endif %}">
|
||||
<a class="page-link" href="{{ _archive_href(year, month, nodate, page-1) }}" aria-label="Назад">«</a>
|
||||
</li>
|
||||
{% set from = [1, page - 3] | max %}
|
||||
{% set to = [pages, page + 3] | min %}
|
||||
{% if from > 1 %}
|
||||
<li class="page-item"><a class="page-link" href="{{ _archive_href(year, month, nodate, 1) }}">1</a></li>
|
||||
{% if from > 2 %}<li class="page-item disabled"><span class="page-link">…</span></li>{% endif %}
|
||||
{% endif %}
|
||||
{% for n in range(from, to + 1) %}
|
||||
<li class="page-item {% if n == page %}active{% endif %}">
|
||||
<a class="page-link" href="{{ _archive_href(year, month, nodate, n) }}">{{ n }}</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
{% if to < pages %}
|
||||
{% if to < pages - 1 %}<li class="page-item disabled"><span class="page-link">…</span></li>{% endif %}
|
||||
<li class="page-item"><a class="page-link" href="{{ _archive_href(year, month, nodate, pages) }}">{{ pages }}</a></li>
|
||||
{% endif %}
|
||||
<li class="page-item {% if page >= pages %}disabled{% endif %}">
|
||||
<a class="page-link" href="{{ _archive_href(year, month, nodate, page+1) }}" aria-label="Вперёд">»</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<!-- Правая колонка: дерево навигации по годам/месяцам -->
|
||||
<div class="col-lg-3">
|
||||
<!-- На мобильных — сворачивается под кнопку -->
|
||||
<button class="btn btn-outline-secondary d-lg-none w-100 mb-2" type="button"
|
||||
data-bs-toggle="collapse" data-bs-target="#archive-tree" aria-expanded="false" aria-controls="archive-tree">
|
||||
🗂 Архив
|
||||
</button>
|
||||
<div id="archive-tree" class="collapse d-lg-block position-sticky" style="top: 5rem;">
|
||||
<div class="card shadow-sm">
|
||||
<div class="card-body py-3">
|
||||
<h6 class="card-title mb-2">🗂 Архив</h6>
|
||||
<div class="list-group list-group-flush">
|
||||
<a href="/published"
|
||||
class="list-group-item list-group-item-action d-flex justify-content-between align-items-center {% if not year and not month and not nodate %}active{% endif %}">
|
||||
Все посты
|
||||
<span class="badge rounded-pill {% if not year and not month and not nodate %}bg-light text-dark{% else %}bg-secondary{% endif %}">{{ tree.years | sum(attribute='n') + tree.no_date }}</span>
|
||||
</a>
|
||||
{% for y in tree.years %}
|
||||
<a href="/published?year={{ y.year }}"
|
||||
class="list-group-item list-group-item-action d-flex justify-content-between align-items-center {% if year == y.year and not month and not nodate %}active{% endif %}">
|
||||
{{ y.year }}
|
||||
<span class="badge rounded-pill {% if year == y.year and not month and not nodate %}bg-light text-dark{% else %}bg-secondary{% endif %}">{{ y.n }}</span>
|
||||
</a>
|
||||
{% if year == y.year %}
|
||||
{% for m in y.months %}
|
||||
<a href="/published?year={{ y.year }}&month={{ m.m }}"
|
||||
class="list-group-item list-group-item-action ps-4 d-flex justify-content-between align-items-center {% if month == m.m and not nodate %}active{% endif %}">
|
||||
{{ m.label }}
|
||||
<span class="badge rounded-pill {% if month == m.m and not nodate %}bg-light text-dark{% else %}bg-secondary{% endif %}">{{ m.n }}</span>
|
||||
</a>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% if tree.no_date > 0 %}
|
||||
<a href="/published?nodate=1"
|
||||
class="list-group-item list-group-item-action d-flex justify-content-between align-items-center {% if nodate %}active{% endif %}">
|
||||
Без даты
|
||||
<span class="badge rounded-pill {% if nodate %}bg-light text-dark{% else %}bg-secondary{% endif %}">{{ tree.no_date }}</span>
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="alert alert-info">Пока ничего не опубликовано</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user