rewrite: Vite+React → Astro 5 + Content Collections
Some checks failed
deploy / deploy (push) Failing after 12s
Some checks failed
deploy / deploy (push) Failing after 12s
- Бэкап старой версии на ветке vite-react-backup - Stack: Astro 5 + nginx:alpine runtime, образ ~50 МБ (был ~600 МБ) - @astrojs/rss заменён ручным buildRss() — гарантия CDATA в content:encoded для IPB Importer - @astrojs/sitemap → sitemap-index.xml + sitemap.txt - 152-ФЗ cookie consent + privacy.astro + Analytics с gating - AI-файлы: robots.txt с явным allow для AI-краулеров, ai.txt, llms.txt - Гибридный визуал: фото-фон шапки (аэрофото Пушкино) + PT Serif + IBM Plex Sans - Иерархия: hero "Главная история" с рамкой + "Ещё из истории" + "Хроника" - Категория "main" (псевдо) скрыта из плашек и из Рубрик в сайдбаре - hideFromList: true для технических постов - featuredImage в frontmatter для постов без хорошей первой <img> - WP resized-URL (-WxH.ext) автоматически → оригинал - CI/CD: .gitea/workflows/deploy.yml (push → SSH-build) - Внешние RSS: scripts/pull-external-rss.mjs пишет news.json в bind-mount, фронт фетчит client-side
This commit is contained in:
49
src/pages/cat/[slug].astro
Normal file
49
src/pages/cat/[slug].astro
Normal file
@@ -0,0 +1,49 @@
|
||||
---
|
||||
import { getCollection } from 'astro:content';
|
||||
import BaseLayout from '../../layouts/BaseLayout.astro';
|
||||
import PostCard from '../../components/PostCard.astro';
|
||||
import { plural } from '../../consts';
|
||||
|
||||
export async function getStaticPaths() {
|
||||
const all = await getCollection('posts');
|
||||
const slugs = new Map<string, string>(); // slug -> display name
|
||||
for (const p of all) {
|
||||
p.data.categorySlugs.forEach((s, i) => {
|
||||
if (!slugs.has(s)) slugs.set(s, p.data.categories[i] ?? s);
|
||||
});
|
||||
}
|
||||
return [...slugs.entries()].map(([slug, name]) => ({
|
||||
params: { slug },
|
||||
props: { catSlug: slug, catName: name },
|
||||
}));
|
||||
}
|
||||
|
||||
const { catSlug, catName } = Astro.props;
|
||||
const all = await getCollection('posts');
|
||||
const posts = all
|
||||
.filter((p) => p.data.categorySlugs.includes(catSlug))
|
||||
.sort((a, b) => b.data.pubDate.valueOf() - a.data.pubDate.valueOf());
|
||||
---
|
||||
|
||||
<BaseLayout title={`Категория: ${catName}`} description={`Записи в рубрике «${catName}»`}>
|
||||
<div class="cat-head">
|
||||
<h1>Категория: {catName}</h1>
|
||||
<p class="meta">
|
||||
{posts.length} {plural(posts.length, ['запись', 'записи', 'записей'])}
|
||||
·
|
||||
<a href={`/cat/${catSlug}/feed.xml`}>RSS этой рубрики</a>
|
||||
</p>
|
||||
</div>
|
||||
<div class="post-list">
|
||||
{posts.map((p) => <PostCard post={p} />)}
|
||||
{posts.length === 0 && <p class="empty">В этой рубрике пока нет записей.</p>}
|
||||
</div>
|
||||
</BaseLayout>
|
||||
|
||||
<style>
|
||||
.cat-head { border-bottom: 1px solid var(--rule); padding-bottom: 1rem; margin-bottom: 1rem; }
|
||||
.cat-head h1 { font-family: var(--font-serif); font-size: 1.8rem; margin: 0; }
|
||||
.cat-head .meta { margin: 0.5rem 0 0; font-size: 0.85rem; color: var(--muted); }
|
||||
.cat-head a { color: var(--accent); }
|
||||
.empty { color: var(--muted); margin: 1rem 0; }
|
||||
</style>
|
||||
Reference in New Issue
Block a user