Skip to content

Commit bff6c1d

Browse files
committed
feat: added blog page
1 parent 23e7c97 commit bff6c1d

File tree

8 files changed

+214
-16
lines changed

8 files changed

+214
-16
lines changed

app/pages/blog.vue

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,3 @@
1-
<script setup lang="ts">
2-
3-
</script>
4-
51
<template>
6-
<div>
7-
<!-- -->
8-
</div>
2+
<NuxtPage />
93
</template>

app/pages/blog/[slug].vue

Lines changed: 86 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,92 @@
11
<script setup lang="ts">
2+
const route = useRoute()
23
4+
const { data: post } = await useAsyncData(route.path, () => queryCollection('posts').path(route.path).first())
5+
if (!post.value) {
6+
throw createError({ statusCode: 404, statusMessage: 'Post not found', fatal: true })
7+
}
8+
9+
const { data: surround } = await useAsyncData(`${route.path}-surround`, () => {
10+
return queryCollectionItemSurroundings('posts', route.path, {
11+
fields: ['description']
12+
})
13+
})
14+
15+
const title = post.value.seo?.title || post.value.title
16+
const description = post.value.seo?.description || post.value.description
17+
18+
useSeoMeta({
19+
title,
20+
ogTitle: title,
21+
description,
22+
ogDescription: description
23+
})
24+
25+
if (post.value.image?.src) {
26+
defineOgImage({
27+
url: post.value.image.src
28+
})
29+
} else {
30+
defineOgImageComponent('myOgImage', {
31+
headline: 'Blog'
32+
})
33+
}
334
</script>
435

536
<template>
6-
<div>
7-
<!-- -->
8-
</div>
37+
<UContainer v-if="post">
38+
<UPageHeader
39+
:title="post.title"
40+
:description="post.description"
41+
>
42+
<template #headline>
43+
<UBadge
44+
v-bind="post.badge"
45+
variant="subtle"
46+
/>
47+
<span class="text-muted">&middot;</span>
48+
<time class="text-muted">{{ new Date(post.date).toLocaleDateString('en', { year: 'numeric', month: 'short', day: 'numeric' }) }}</time>
49+
</template>
50+
51+
<div class="flex flex-wrap items-center gap-3 mt-4">
52+
<UButton
53+
v-for="(author, index) in post.authors"
54+
:key="index"
55+
:to="author.to"
56+
color="neutral"
57+
variant="subtle"
58+
target="_blank"
59+
size="sm"
60+
>
61+
<UAvatar
62+
v-bind="author.avatar"
63+
alt="Author avatar"
64+
size="2xs"
65+
/>
66+
67+
{{ author.name }}
68+
</UButton>
69+
</div>
70+
</UPageHeader>
71+
72+
<UPage>
73+
<UPageBody>
74+
<ContentRenderer
75+
v-if="post"
76+
:value="post"
77+
/>
78+
79+
<USeparator v-if="surround?.length" />
80+
81+
<UContentSurround :surround="surround" />
82+
</UPageBody>
83+
84+
<template
85+
v-if="post?.body?.toc?.links?.length"
86+
#right
87+
>
88+
<UContentToc :links="post.body.toc.links" />
89+
</template>
90+
</UPage>
91+
</UContainer>
992
</template>

app/pages/blog/index.vue

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,50 @@
11
<script setup lang="ts">
2+
const route = useRoute()
23
4+
const { data: page } = await useAsyncData('page-blog', () => queryCollection('blog').first())
5+
const { data: posts } = await useAsyncData(route.path, () => queryCollection('posts').all())
6+
7+
const title = page.value?.seo?.title || page.value?.title
8+
const description = page.value?.seo?.description || page.value?.description
9+
10+
useSeoMeta({
11+
title,
12+
ogTitle: title,
13+
description,
14+
ogDescription: description
15+
})
16+
17+
if (import.meta.client) defineOgImageComponent('myOgImage')
318
</script>
419

520
<template>
6-
<div>
7-
<!-- -->
8-
</div>
21+
<UContainer>
22+
<UPageHeader
23+
v-bind="page"
24+
class="py-[50px]"
25+
/>
26+
27+
<UPageBody>
28+
<UBlogPosts>
29+
<UBlogPost
30+
v-for="(post, index) in posts"
31+
:key="index"
32+
:to="post.path"
33+
:icon="post.icon"
34+
:title="post.title"
35+
:description="post.description"
36+
:image="post.image"
37+
:date="new Date(post.date).toLocaleDateString('en', { year: 'numeric', month: 'short', day: 'numeric' })"
38+
:authors="post.authors"
39+
:badge="post.badge"
40+
:orientation="index === 0 ? 'horizontal' : 'vertical'"
41+
:class="[index === 0 && 'col-span-full']"
42+
variant="naked"
43+
:ui="{
44+
description: 'line-clamp-2'
45+
}"
46+
/>
47+
</UBlogPosts>
48+
</UPageBody>
49+
</UContainer>
950
</template>

content.config.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,8 +155,25 @@ const collections = {
155155
}),
156156
blog: defineCollection({
157157
type: 'page',
158-
source: '4.blog/**/*',
158+
source: '4.blog.yml',
159159
schema: z.object({})
160+
}),
161+
posts: defineCollection({
162+
type: 'page',
163+
source: '4.blog/**/*',
164+
schema: z.object({
165+
icon: z.string().optional(),
166+
image: z.object({ src: z.string().nonempty().editor({ input: 'media' }) }),
167+
authors: z.array(
168+
z.object({
169+
name: z.string().nonempty(),
170+
to: z.string().nonempty(),
171+
avatar: z.object({ src: z.string().nonempty().editor({ input: 'media' }) })
172+
})
173+
),
174+
date: z.date(),
175+
badge: z.object({ label: z.string().nonempty() })
176+
})
160177
})
161178
}
162179

content/4.blog.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
icon: i-lucide-newspaper
2+
title: Blog
3+
description: Latest articles and updates
4+
navigation.icon: i-lucide-newspaper

content/4.blog/.navigation.yml

Lines changed: 0 additions & 1 deletion
This file was deleted.

content/4.blog/1.getting-started.md

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
---
2+
title: Our New Website
3+
description: "We are excited to announce the launch of our new website, designed to enhance your experience and provide better access to our resources."
4+
image:
5+
src: /assets/images/blog/website-example.png
6+
date: 2025-06-15
7+
badge:
8+
label: New
9+
---
10+
11+
## Welcome to Our New Website
12+
13+
We’re thrilled to officially unveil our brand-new website—a central hub built with purpose, clarity, and accessibility in mind. Whether you're discovering our work for the first time or you've been with us from the beginning, this site was designed to provide a better experience for everyone.
14+
15+
## Why a New Site?
16+
17+
Over time, our projects and resources have grown significantly. From open-source tools and creative experiments to research and documentation, it became clear that we needed a unified platform to:
18+
19+
- Organize our growing body of work
20+
- Share updates and announcements more efficiently
21+
- Offer easy access to downloads, source code, and documentation
22+
- Support contributors and collaborators
23+
24+
This new website brings all of that into one cohesive space.
25+
26+
## What’s Inside
27+
28+
Here’s a quick overview of what you’ll find:
29+
30+
### 🚀 Projects
31+
32+
A curated showcase of our active and past projects, with direct links to GitHub repositories, live demos, and changelogs.
33+
34+
### 📚 Resources
35+
36+
Useful guides, API references, and helpful links for developers, designers, and contributors. We aim to make it easier than ever to get started.
37+
38+
### 📰 Blog
39+
40+
You’re reading it! This blog is where we’ll post updates, behind-the-scenes insights, release notes, and other content to keep you informed.
41+
42+
### 🤝 Get Involved
43+
44+
We’ve made it easier to contribute—whether it’s reporting bugs, submitting pull requests, or helping with documentation. Our new site includes clear contribution guidelines and collaboration tips.
45+
46+
## What’s Next?
47+
48+
This launch is just the beginning. We have plans to roll out:
49+
50+
- A searchable archive of past releases 🗂️
51+
- Deeper integration with our GitHub activity 📦
52+
53+
## Feedback Welcome
54+
55+
We’d love to hear what you think! If you encounter any bugs or have suggestions for improvement, feel free to open an issue or contact us directly.
56+
57+
Thank you for being part of this journey—we’re excited for what’s ahead!
58+
59+
---
60+
Stay connected, stay curious.

content/app.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ links:
2525
- label: Blog
2626
icon: i-lucide-pencil
2727
to: /blog
28-
disabled: true
28+
disabled: false
2929
- label: GitHub
3030
icon: i-simple-icons-github
3131
to: https://github.com/projectm-visualizer

0 commit comments

Comments
 (0)