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:
77
src/layouts/BaseLayout.astro
Normal file
77
src/layouts/BaseLayout.astro
Normal file
@@ -0,0 +1,77 @@
|
||||
---
|
||||
import '../styles/global.css';
|
||||
import Header from '../components/Header.astro';
|
||||
import Sidebar from '../components/Sidebar.astro';
|
||||
import Footer from '../components/Footer.astro';
|
||||
import CookieConsent from '../components/CookieConsent.astro';
|
||||
import Analytics from '../components/Analytics.astro';
|
||||
import { SITE_TITLE, SITE_DESCRIPTION, SITE_URL, SITE_LANG } from '../consts';
|
||||
|
||||
interface Props {
|
||||
title?: string;
|
||||
description?: string;
|
||||
ogImage?: string;
|
||||
noSidebar?: boolean;
|
||||
canonical?: string;
|
||||
}
|
||||
|
||||
const {
|
||||
title,
|
||||
description = SITE_DESCRIPTION,
|
||||
ogImage = '/og-image.png',
|
||||
noSidebar = false,
|
||||
canonical,
|
||||
} = Astro.props;
|
||||
|
||||
const fullTitle = title ? `${title} — ${SITE_TITLE}` : SITE_TITLE;
|
||||
const url = canonical ?? new URL(Astro.url.pathname, SITE_URL).toString();
|
||||
const ogImageUrl = new URL(ogImage, SITE_URL).toString();
|
||||
---
|
||||
|
||||
<!doctype html>
|
||||
<html lang={SITE_LANG}>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>{fullTitle}</title>
|
||||
<meta name="description" content={description} />
|
||||
<link rel="canonical" href={url} />
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||
<link rel="alternate" type="application/rss+xml" title="История города Пушкино — RSS" href="/feed.xml" />
|
||||
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:title" content={fullTitle} />
|
||||
<meta property="og:description" content={description} />
|
||||
<meta property="og:url" content={url} />
|
||||
<meta property="og:image" content={ogImageUrl} />
|
||||
<meta property="og:locale" content="ru_RU" />
|
||||
<meta property="og:site_name" content={SITE_TITLE} />
|
||||
<meta name="twitter:card" content="summary_large_image" />
|
||||
|
||||
<Analytics />
|
||||
</head>
|
||||
<body>
|
||||
<Header />
|
||||
<div class="container">
|
||||
{noSidebar ? (
|
||||
<main class="layout-single">
|
||||
<slot />
|
||||
</main>
|
||||
) : (
|
||||
<div class="layout-grid">
|
||||
<main><slot /></main>
|
||||
<Sidebar />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<Footer />
|
||||
<CookieConsent />
|
||||
</body>
|
||||
</html>
|
||||
|
||||
<style>
|
||||
.layout-single {
|
||||
max-width: var(--reading-max);
|
||||
margin: 2rem auto;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user