--- import { getCollection } from 'astro:content'; import Base from '../../layouts/Base.astro'; import NewsCard from '../../components/NewsCard.astro'; import { PAGE_FIRST as FIRST, PAGE_REST as REST } from '../../lib/news.js'; // Paginated archive; the [...page] rest route makes page 1 the bare /news URL, // then /news/2 … /news/N. Custom slicing instead of paginate(): page 1 holds // FIRST items (1 featured lead + 24 grid = even 3-column rows), later pages // REST — paginate() cannot vary page size. Chunk sizes live in lib/news.js, // shared with sitemap.xml.js. export async function getStaticPaths() { const posts = (await getCollection('news', ({ data }) => !data.draft)).sort( (a, b) => b.data.date.valueOf() - a.data.date.valueOf(), ); const chunks = [posts.slice(0, FIRST)]; for (let i = FIRST; i < posts.length; i += REST) chunks.push(posts.slice(i, i + REST)); const lastPage = chunks.length; const hrefOf = (n: number) => (n === 1 ? '/news' : `/news/${n}`); return chunks.map((data, i) => { const n = i + 1; return { params: { page: n === 1 ? undefined : String(n) }, props: { page: { data, currentPage: n, lastPage, url: { prev: n > 1 ? hrefOf(n - 1) : undefined, next: n < lastPage ? hrefOf(n + 1) : undefined, }, } }, }; }); } const { page } = Astro.props; const first = page.currentPage === 1; // Windowed page list — 1 … n-1 n n+1 … last (0 marks an ellipsis) const nums = []; for (let n = 1; n <= page.lastPage; n++) { if (n === 1 || n === page.lastPage || Math.abs(n - page.currentPage) <= 1) nums.push(n); else if (nums.at(-1) !== 0) nums.push(0); } const hrefFor = (n: number) => (n === 1 ? '/news' : `/news/${n}`); --- {/* Section-landing archetype: white head, display Galaxy h1 + standfirst (the navy band is reserved for / and /login). */}

News & Announcements

Science highlights and updates from the observatory and its partners.

{first ? 'All news' : `All news, page ${page.currentPage}`}

{page.data.map((post, i) => )}
{page.lastPage > 1 && ( )}