--- import ArticleList from '../../components/ArticleList.astro'; import TagList from '../../components/TagList.astro'; import Page from '../../layouts/Page.astro'; import { absoluteUrl, articlePath, buildBreadcrumbJsonLd, buildBreadcrumbTrail, getAllTags, getPublishedPosts, optimizeOgImage, site, yearOf, } from '../../lib/site'; const description = 'Technical articles and notes about projects, systems, AI deployment, graphics, simulations, and tools.'; const posts = await getPublishedPosts(); const years = [...new Set(posts.map((post) => yearOf(post.data.date)))]; const tags = getAllTags(posts); const postOgImages = await Promise.all( posts.map((post) => optimizeOgImage(post.data.thumbnail.src)) ); const personId = absoluteUrl('/about/#person'); const blogJsonLd = { '@context': 'https://schema.org', '@type': 'Blog', name: `${site.name} — Articles`, url: absoluteUrl('/articles/'), description, publisher: { '@id': personId }, blogPost: posts.map((post, index) => ({ '@type': 'BlogPosting', headline: post.data.title, description: post.data.description, datePublished: post.data.date.toISOString(), url: absoluteUrl(articlePath(post)), author: { '@id': personId }, image: absoluteUrl(postOgImages[index].src), keywords: post.data.tags.join(', '), })), }; const breadcrumbJsonLd = buildBreadcrumbJsonLd(buildBreadcrumbTrail({ articles: true })); const jsonLd = [blogJsonLd, breadcrumbJsonLd]; --- { years.map((year) => { const postsForYear = posts.filter((post) => yearOf(post.data.date) === year); return (

{year}

); }) }