From 5a7e8cd2305ccdc56d11ef5db09639ad0bdbe441 Mon Sep 17 00:00:00 2001 From: Ivan Reshetnikov Date: Sun, 3 Mar 2024 14:05:33 +0500 Subject: [PATCH] feat: tags --- public/icons/tag.svg | 1 + src/components/Note.astro | 38 ++++++++++++++ src/components/Tag.astro | 25 +++++++++ src/content/config.ts | 4 ++ src/content/notes/carefree-mountain.md | 1 + src/content/notes/self-hosting.md | 1 + src/content/notes/strelka.md | 1 + src/content/notes/yggdrasil.md | 1 + src/pages/index.astro | 30 +++-------- src/pages/notes/[...slug].astro | 9 ++++ src/pages/tags/[...slug].astro | 71 ++++++++++++++++++++++++++ 11 files changed, 159 insertions(+), 23 deletions(-) create mode 100644 public/icons/tag.svg create mode 100644 src/components/Note.astro create mode 100644 src/components/Tag.astro create mode 100644 src/pages/tags/[...slug].astro diff --git a/public/icons/tag.svg b/public/icons/tag.svg new file mode 100644 index 0000000..095717e --- /dev/null +++ b/public/icons/tag.svg @@ -0,0 +1 @@ + diff --git a/src/components/Note.astro b/src/components/Note.astro new file mode 100644 index 0000000..83159ef --- /dev/null +++ b/src/components/Note.astro @@ -0,0 +1,38 @@ +--- +import Tag from './Tag.astro' + +interface Props { + pubDate: Date + slug: string + title: string + tags: { name: string, slug: string }[] +} +const { pubDate, slug, title, tags } = Astro.props +--- + +
+
{pubDate.toLocaleDateString("ru", {year: "numeric", month: "long", day: "numeric"})}
+
+ { title } + {tags.map(tag => )} +
+ + diff --git a/src/components/Tag.astro b/src/components/Tag.astro new file mode 100644 index 0000000..9f2cd7a --- /dev/null +++ b/src/components/Tag.astro @@ -0,0 +1,25 @@ +--- +interface Props { + name: string + slug: string +} +const { name, slug } = Astro.props +--- + + + + {name} + + + diff --git a/src/content/config.ts b/src/content/config.ts index c5f2741..536f38f 100644 --- a/src/content/config.ts +++ b/src/content/config.ts @@ -7,6 +7,10 @@ const notesCollection = defineCollection({ description: z.string(), pubDate: z.date(), updatedAt: z.date().optional(), + tags: z.array(z.object({ + name: z.string(), + slug: z.string(), + })), }), }) diff --git a/src/content/notes/carefree-mountain.md b/src/content/notes/carefree-mountain.md index d7f523f..5a49228 100644 --- a/src/content/notes/carefree-mountain.md +++ b/src/content/notes/carefree-mountain.md @@ -2,6 +2,7 @@ title: "Беспечная Гляденовская гора" description: "Путешествие до Гляденовской горы." pubDate: 2023-10-16 +tags: [{name: "Путешествия", slug: "traveling"}, {name: "Пермский край", slug: "perm-krai"}] --- Гляденовская гора - это красивый лес в Перми, за которым прячется деревянная часовня. diff --git a/src/content/notes/self-hosting.md b/src/content/notes/self-hosting.md index 92d09c0..99954c1 100644 --- a/src/content/notes/self-hosting.md +++ b/src/content/notes/self-hosting.md @@ -3,6 +3,7 @@ title: "Свободные альтернативы популярным сер description: "Список самых популярных независимых альтернатив коммерческим социальным сетям и сервисам." pubDate: 2023-08-27 updatedAt: 2023-10-01 +tags: [{name: "Интернет", slug: "internet"}] --- Это статья для тех, кто никогда не слышал про альтернативы современным социальным сетям и сервисам. diff --git a/src/content/notes/strelka.md b/src/content/notes/strelka.md index 0158459..142d4ee 100644 --- a/src/content/notes/strelka.md +++ b/src/content/notes/strelka.md @@ -2,6 +2,7 @@ title: "Мыс Стрелка" description: "Фотографии с путешествия на мыс Стрелка." pubDate: 2023-11-11 +tags: [{name: "Путешествия", slug: "traveling"}, {name: "Пермский край", slug: "perm-krai"}] --- *Некоторые вещи стоят того, чтобы встать в 6 утра в воскресенье.* diff --git a/src/content/notes/yggdrasil.md b/src/content/notes/yggdrasil.md index 0b8d965..360cadc 100644 --- a/src/content/notes/yggdrasil.md +++ b/src/content/notes/yggdrasil.md @@ -3,6 +3,7 @@ title: "Интернет №1 продолжают ломать?" description: "Расскажу о событиях, которые побудили меня завести зеркало этого сайта в Yggdrasil." pubDate: 2024-02-02 updatedAt: 2024-02-12 +tags: [{name: "Интернет", slug: "internet"}] --- ## Что случилось? diff --git a/src/pages/index.astro b/src/pages/index.astro index 5e489c7..b5492c0 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -1,5 +1,6 @@ --- import Layout from '../layouts/Layout.astro' +import Note from '../components/Note.astro' import { getCollection } from 'astro:content' const notes = await getCollection('notes') @@ -33,11 +34,12 @@ notes.sort((a, b) => { {notes.map(note => ( -
-
{note.data.pubDate.toLocaleDateString("ru", {year: "numeric", month: "long", day: "numeric"})}
-
- { note.data.title } -
+ ))} @@ -59,22 +61,4 @@ notes.sort((a, b) => { align-items: center; gap: 5px; } - - .note { - margin-bottom: 15px; - } - .dash { - display: none; - } - - @media screen and (min-width: 600px) { - .note { - display: flex; - gap: 6px; - margin-bottom: 5px; - } - .dash { - display: block; - } - } diff --git a/src/pages/notes/[...slug].astro b/src/pages/notes/[...slug].astro index f33672e..940e4ba 100644 --- a/src/pages/notes/[...slug].astro +++ b/src/pages/notes/[...slug].astro @@ -1,6 +1,7 @@ --- import { getCollection } from 'astro:content' import Layout from '../../layouts/Layout.astro' +import Tag from '../../components/Tag.astro' export async function getStaticPaths() { const blogEntries = await getCollection('notes') @@ -23,6 +24,10 @@ const formatDate = (date: Date) => { { entry.data.updatedAt !== undefined && entry.data.updatedAt !== entry.data.pubDate && (

Последнее обновление: { formatDate(entry.data.updatedAt) }

)} + +
+ {entry.data.tags.map(tag => )} +
@@ -39,6 +44,10 @@ const formatDate = (date: Date) => { margin-top: 6px; margin-bottom: 6px; } + .metadata .tags { + display: flex; + gap: 5px; + } .content { img { width: 100%; diff --git a/src/pages/tags/[...slug].astro b/src/pages/tags/[...slug].astro new file mode 100644 index 0000000..fad8629 --- /dev/null +++ b/src/pages/tags/[...slug].astro @@ -0,0 +1,71 @@ +--- +import { getCollection } from 'astro:content' +import Layout from '../../layouts/Layout.astro' +import Note from '../../components/Note.astro' + +export async function getStaticPaths() { + const blogEntries = await getCollection('notes') + const tags = blogEntries + .map(entry => entry.data.tags) + .flat() + .filter((tag, i, self) => self.findIndex(t => t.slug === tag.slug) === i) + + return tags.map(tag => { + const notes = blogEntries + .filter(entry => entry.data.tags.find(t => t.slug === tag.slug) !== undefined) + .toSorted((a, b) => { + if (a.data.pubDate < b.data.pubDate) return 1 + if (a.data.pubDate > b.data.pubDate) return -1 + return 0 + }) + return { + params: { slug: tag.slug }, + props: { tag, notes }, + } + }) +} + +const { notes, tag } = Astro.props +--- + +

Заметки с тегом "{ tag.name }"

+ + {notes.map(note => ( + + ))} +
+ +