@levino/shipyard-blog 0.7.4 → 0.7.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/astro/BlogArchive.astro +16 -22
- package/astro/BlogAuthorPage.astro +19 -139
- package/astro/BlogAuthorsIndex.astro +15 -37
- package/astro/BlogEntry.astro +14 -84
- package/astro/BlogIndex.astro +31 -40
- package/astro/BlogIndexPaginated.astro +23 -56
- package/astro/BlogTagPage.astro +17 -66
- package/astro/BlogTagsIndex.astro +17 -22
- package/astro/Layout.astro +10 -3
- package/astro/pages/BlogArchive.astro +22 -0
- package/astro/pages/BlogAuthorPage.astro +30 -0
- package/astro/pages/BlogAuthorsIndex.astro +23 -0
- package/astro/pages/BlogEntry.astro +36 -0
- package/astro/pages/BlogIndex.astro +22 -0
- package/astro/pages/BlogIndexPaginated.astro +29 -0
- package/astro/pages/BlogTagPage.astro +24 -0
- package/astro/pages/BlogTagsIndex.astro +22 -0
- package/astro/pages/feeds/atom.xml.ts +28 -0
- package/astro/pages/feeds/feed.json.ts +28 -0
- package/astro/pages/feeds/rss.xml.ts +28 -0
- package/package.json +5 -3
- package/src/feeds.ts +286 -0
- package/src/index.ts +82 -72
- package/src/staticPaths.ts +299 -0
- package/src/virtual.d.ts +6 -0
|
@@ -1,69 +1,36 @@
|
|
|
1
1
|
---
|
|
2
2
|
import { Image } from 'astro:assets'
|
|
3
3
|
import { i18n } from 'astro:config/server'
|
|
4
|
-
import { getCollection } from 'astro:content'
|
|
5
|
-
import
|
|
6
|
-
import type { GetStaticPaths } from 'astro'
|
|
4
|
+
import { type CollectionKey, getCollection } from 'astro:content'
|
|
5
|
+
import blogConfigDefault from 'virtual:shipyard-blog/config'
|
|
7
6
|
import Layout from './Layout.astro'
|
|
8
7
|
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
const allPosts = await getCollection('blog')
|
|
13
|
-
|
|
14
|
-
if (i18n) {
|
|
15
|
-
const paths: Array<{ params: { locale: string; page: string } }> = []
|
|
16
|
-
|
|
17
|
-
for (const locale of i18n.locales) {
|
|
18
|
-
if (typeof locale !== 'string') {
|
|
19
|
-
throw new Error('shipyard does only support strings as locales.')
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const localePosts = allPosts.filter(({ id }) => {
|
|
23
|
-
const [postLocale] = id.split('/')
|
|
24
|
-
return postLocale === locale
|
|
25
|
-
})
|
|
26
|
-
|
|
27
|
-
const totalPages = Math.ceil(localePosts.length / blogConfig.postsPerPage)
|
|
28
|
-
|
|
29
|
-
// Generate pages 2+ only (page 1 is handled by BlogIndex.astro)
|
|
30
|
-
for (let pageNum = 2; pageNum <= totalPages; pageNum++) {
|
|
31
|
-
paths.push({ params: { locale, page: String(pageNum) } })
|
|
32
|
-
}
|
|
33
|
-
}
|
|
8
|
+
const blogConfig = Astro.props.blogConfig ?? blogConfigDefault
|
|
9
|
+
const collectionName =
|
|
10
|
+
Astro.props.collectionName ?? blogConfigDefault.collectionName
|
|
34
11
|
|
|
35
|
-
|
|
36
|
-
} else {
|
|
37
|
-
const totalPages = Math.ceil(allPosts.length / blogConfig.postsPerPage)
|
|
38
|
-
const paths: Array<{ params: { page: string } }> = []
|
|
39
|
-
|
|
40
|
-
// Generate pages 2+ only
|
|
41
|
-
for (let pageNum = 2; pageNum <= totalPages; pageNum++) {
|
|
42
|
-
paths.push({ params: { page: String(pageNum) } })
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
return paths
|
|
46
|
-
}
|
|
47
|
-
}) satisfies GetStaticPaths
|
|
12
|
+
const { postsPerPage, routeBasePath } = blogConfig
|
|
48
13
|
|
|
49
14
|
// Get current page from URL params
|
|
50
15
|
const pageParam = Astro.params.page
|
|
51
16
|
const currentPage = parseInt(pageParam, 10)
|
|
52
17
|
|
|
53
|
-
const entries = await getCollection(
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
}
|
|
18
|
+
const entries = await getCollection(collectionName as CollectionKey).then(
|
|
19
|
+
(posts) => {
|
|
20
|
+
if (i18n) {
|
|
21
|
+
return posts
|
|
22
|
+
.filter(({ id }) => {
|
|
23
|
+
const [postLocale] = id.split('/')
|
|
24
|
+
return postLocale === Astro.currentLocale
|
|
25
|
+
})
|
|
26
|
+
.toSorted((a, b) => b.data.date.getTime() - a.data.date.getTime())
|
|
27
|
+
} else {
|
|
28
|
+
return posts.toSorted(
|
|
29
|
+
(a, b) => b.data.date.getTime() - a.data.date.getTime(),
|
|
30
|
+
)
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
)
|
|
67
34
|
|
|
68
35
|
// Calculate pagination
|
|
69
36
|
const totalPosts = entries.length
|
|
@@ -114,7 +81,7 @@ const showRightEllipsis =
|
|
|
114
81
|
adjacentPages[adjacentPages.length - 1] < totalPages - 1
|
|
115
82
|
---
|
|
116
83
|
|
|
117
|
-
<Layout title="Blog">
|
|
84
|
+
<Layout title="Blog" blogConfig={blogConfig} collectionName={collectionName}>
|
|
118
85
|
<div class="max-w-7xl mx-auto">
|
|
119
86
|
<div class="space-y-6">
|
|
120
87
|
{
|
package/astro/BlogTagPage.astro
CHANGED
|
@@ -3,78 +3,29 @@
|
|
|
3
3
|
* Individual tag page - shows all posts with a specific tag.
|
|
4
4
|
*/
|
|
5
5
|
import { i18n } from 'astro:config/server'
|
|
6
|
-
import { type CollectionEntry, getCollection } from 'astro:content'
|
|
7
|
-
import blogConfig from 'virtual:shipyard-blog/config'
|
|
8
|
-
import tagsMap from 'virtual:shipyard-blog/tags'
|
|
9
|
-
import type { GetStaticPaths } from 'astro'
|
|
10
6
|
import {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
uniq,
|
|
19
|
-
} from 'ramda'
|
|
7
|
+
type CollectionEntry,
|
|
8
|
+
type CollectionKey,
|
|
9
|
+
getCollection,
|
|
10
|
+
} from 'astro:content'
|
|
11
|
+
import blogConfigDefault from 'virtual:shipyard-blog/config'
|
|
12
|
+
import tagsMapDefault from 'virtual:shipyard-blog/tags'
|
|
13
|
+
import { filter, includes, map, pipe, reverse, sortBy, toLower } from 'ramda'
|
|
20
14
|
import { getReadingTime, getTagDescription, getTagLabel } from '../src/index'
|
|
21
15
|
import BlogReadingTime from './BlogReadingTime.astro'
|
|
22
16
|
import BlogTags from './BlogTags.astro'
|
|
23
17
|
import Layout from './Layout.astro'
|
|
24
18
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
// Filter out draft and unlisted posts - defined inside getStaticPaths
|
|
31
|
-
const shouldIncludePost = (post: CollectionEntry<'blog'>) => {
|
|
32
|
-
if (post.data.unlisted) return false
|
|
33
|
-
if (post.data.draft && !(isDev && includeDraftsInDev)) return false
|
|
34
|
-
return true
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
// Get all unique tags across all posts
|
|
38
|
-
const getAllTags = pipe(
|
|
39
|
-
filter(shouldIncludePost),
|
|
40
|
-
(posts: CollectionEntry<'blog'>[]) =>
|
|
41
|
-
posts.flatMap((post) => post.data.tags ?? []),
|
|
42
|
-
map(toLower),
|
|
43
|
-
uniq,
|
|
44
|
-
) as (posts: CollectionEntry<'blog'>[]) => string[]
|
|
45
|
-
|
|
46
|
-
const allTags = getAllTags(allPosts)
|
|
47
|
-
|
|
48
|
-
if (i18n) {
|
|
49
|
-
// Generate paths for each locale + tag combination
|
|
50
|
-
const paths: Array<{ params: { locale: string; tag: string } }> = []
|
|
51
|
-
|
|
52
|
-
for (const locale of i18n.locales) {
|
|
53
|
-
if (typeof locale !== 'string') continue
|
|
54
|
-
|
|
55
|
-
// Get tags for this locale's posts
|
|
56
|
-
const localePosts = allPosts.filter((post) => {
|
|
57
|
-
const [postLocale] = post.id.split('/')
|
|
58
|
-
return postLocale === locale
|
|
59
|
-
})
|
|
60
|
-
const localeTags = getAllTags(localePosts)
|
|
61
|
-
|
|
62
|
-
for (const tag of localeTags) {
|
|
63
|
-
paths.push({ params: { locale, tag } })
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
return paths
|
|
68
|
-
} else {
|
|
69
|
-
return allTags.map((tag) => ({ params: { tag } }))
|
|
70
|
-
}
|
|
71
|
-
}) satisfies GetStaticPaths
|
|
19
|
+
const blogConfig = Astro.props.blogConfig ?? blogConfigDefault
|
|
20
|
+
const collectionName =
|
|
21
|
+
Astro.props.collectionName ?? blogConfigDefault.collectionName
|
|
22
|
+
const tagsMap = Astro.props.tagsMap ?? tagsMapDefault
|
|
72
23
|
|
|
73
24
|
const { includeDraftsInDev, showReadingTime, routeBasePath } = blogConfig
|
|
74
25
|
|
|
75
26
|
// Filter out draft and unlisted posts for runtime use
|
|
76
27
|
const isDev = import.meta.env.DEV
|
|
77
|
-
const shouldIncludePost = (post: CollectionEntry<
|
|
28
|
+
const shouldIncludePost = (post: CollectionEntry<CollectionKey>) => {
|
|
78
29
|
if (post.data.unlisted) return false
|
|
79
30
|
if (post.data.draft && !(isDev && includeDraftsInDev)) return false
|
|
80
31
|
return true
|
|
@@ -82,10 +33,10 @@ const shouldIncludePost = (post: CollectionEntry<'blog'>) => {
|
|
|
82
33
|
|
|
83
34
|
const { tag } = Astro.params
|
|
84
35
|
|
|
85
|
-
const allPosts = await getCollection(
|
|
36
|
+
const allPosts = await getCollection(collectionName as CollectionKey)
|
|
86
37
|
const posts = pipe(
|
|
87
38
|
filter(shouldIncludePost),
|
|
88
|
-
filter((post: CollectionEntry<
|
|
39
|
+
filter((post: CollectionEntry<CollectionKey>) => {
|
|
89
40
|
// Filter by locale if i18n is enabled
|
|
90
41
|
if (i18n) {
|
|
91
42
|
const [postLocale] = post.id.split('/')
|
|
@@ -95,9 +46,9 @@ const posts = pipe(
|
|
|
95
46
|
const postTags = post.data.tags ?? []
|
|
96
47
|
return includes(tag.toLowerCase(), map(toLower, postTags))
|
|
97
48
|
}),
|
|
98
|
-
sortBy((post: CollectionEntry<
|
|
49
|
+
sortBy((post: CollectionEntry<CollectionKey>) => post.data.date.getTime()),
|
|
99
50
|
reverse,
|
|
100
|
-
)(allPosts) as CollectionEntry<
|
|
51
|
+
)(allPosts) as CollectionEntry<CollectionKey>[]
|
|
101
52
|
|
|
102
53
|
const formatDate = new Intl.DateTimeFormat(Astro.currentLocale || 'en', {
|
|
103
54
|
year: 'numeric',
|
|
@@ -122,7 +73,7 @@ const tagLabel = getTagLabel(tagsMap, tag)
|
|
|
122
73
|
const tagDescription = getTagDescription(tagsMap, tag)
|
|
123
74
|
---
|
|
124
75
|
|
|
125
|
-
<Layout title={`Posts tagged "${tagLabel}"`}>
|
|
76
|
+
<Layout title={`Posts tagged "${tagLabel}"`} blogConfig={blogConfig} collectionName={collectionName}>
|
|
126
77
|
<div class="max-w-4xl mx-auto">
|
|
127
78
|
<div class="mb-8">
|
|
128
79
|
<a
|
|
@@ -3,38 +3,33 @@
|
|
|
3
3
|
* Blog tags index page - lists all tags with post counts.
|
|
4
4
|
*/
|
|
5
5
|
import { i18n } from 'astro:config/server'
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
import {
|
|
7
|
+
type CollectionEntry,
|
|
8
|
+
type CollectionKey,
|
|
9
|
+
getCollection,
|
|
10
|
+
} from 'astro:content'
|
|
11
|
+
import blogConfigDefault from 'virtual:shipyard-blog/config'
|
|
12
|
+
import tagsMapDefault from 'virtual:shipyard-blog/tags'
|
|
10
13
|
import { groupBy, map, pipe, prop, reverse, sortBy, toPairs } from 'ramda'
|
|
11
14
|
import { getTagDescription, getTagLabel, getTagPermalink } from '../src/index'
|
|
12
15
|
import Layout from './Layout.astro'
|
|
13
16
|
|
|
17
|
+
const blogConfig = Astro.props.blogConfig ?? blogConfigDefault
|
|
18
|
+
const collectionName =
|
|
19
|
+
Astro.props.collectionName ?? blogConfigDefault.collectionName
|
|
20
|
+
const tagsMap = Astro.props.tagsMap ?? tagsMapDefault
|
|
21
|
+
|
|
14
22
|
const { includeDraftsInDev, routeBasePath } = blogConfig
|
|
15
23
|
|
|
16
24
|
// Filter out draft and unlisted posts
|
|
17
25
|
const isDev = import.meta.env.DEV
|
|
18
|
-
const shouldIncludePost = (post: CollectionEntry<
|
|
26
|
+
const shouldIncludePost = (post: CollectionEntry<CollectionKey>) => {
|
|
19
27
|
if (post.data.unlisted) return false
|
|
20
28
|
if (post.data.draft && !(isDev && includeDraftsInDev)) return false
|
|
21
29
|
return true
|
|
22
30
|
}
|
|
23
31
|
|
|
24
|
-
|
|
25
|
-
if (i18n) {
|
|
26
|
-
return i18n.locales.map((locale) => {
|
|
27
|
-
if (typeof locale !== 'string') {
|
|
28
|
-
throw new Error('shipyard does only support strings as locales.')
|
|
29
|
-
}
|
|
30
|
-
return { params: { locale } }
|
|
31
|
-
})
|
|
32
|
-
} else {
|
|
33
|
-
return [{ params: {} }]
|
|
34
|
-
}
|
|
35
|
-
}) satisfies GetStaticPaths
|
|
36
|
-
|
|
37
|
-
const allPosts = await getCollection('blog')
|
|
32
|
+
const allPosts = await getCollection(collectionName as CollectionKey)
|
|
38
33
|
const posts = allPosts.filter(shouldIncludePost).filter(({ id }) => {
|
|
39
34
|
if (i18n) {
|
|
40
35
|
const [postLocale] = id.split('/')
|
|
@@ -47,7 +42,7 @@ const posts = allPosts.filter(shouldIncludePost).filter(({ id }) => {
|
|
|
47
42
|
type TagCount = { tag: string; count: number }
|
|
48
43
|
|
|
49
44
|
const getTagCounts = pipe(
|
|
50
|
-
(posts: CollectionEntry<
|
|
45
|
+
(posts: CollectionEntry<CollectionKey>[]) =>
|
|
51
46
|
posts.flatMap((post) => post.data.tags ?? []),
|
|
52
47
|
groupBy((tag: string) => tag.toLowerCase()),
|
|
53
48
|
map((tags: string[]) => tags.length),
|
|
@@ -55,7 +50,7 @@ const getTagCounts = pipe(
|
|
|
55
50
|
map(([tag, count]): TagCount => ({ tag, count: count as number })),
|
|
56
51
|
sortBy(prop('count')),
|
|
57
52
|
reverse,
|
|
58
|
-
) as (posts: CollectionEntry<
|
|
53
|
+
) as (posts: CollectionEntry<CollectionKey>[]) => TagCount[]
|
|
59
54
|
|
|
60
55
|
const tagCounts = getTagCounts(posts)
|
|
61
56
|
|
|
@@ -76,7 +71,7 @@ const tagCountsWithMeta = tagCounts.map(({ tag, count }) => ({
|
|
|
76
71
|
}))
|
|
77
72
|
---
|
|
78
73
|
|
|
79
|
-
<Layout title="Tags">
|
|
74
|
+
<Layout title="Tags" blogConfig={blogConfig} collectionName={collectionName}>
|
|
80
75
|
<div class="max-w-4xl mx-auto">
|
|
81
76
|
<h1 class="text-4xl font-bold mb-8">Tags</h1>
|
|
82
77
|
|
package/astro/Layout.astro
CHANGED
|
@@ -1,21 +1,28 @@
|
|
|
1
1
|
---
|
|
2
2
|
import { i18n } from 'astro:config/server'
|
|
3
|
-
import { getCollection } from 'astro:content'
|
|
4
|
-
import
|
|
3
|
+
import { type CollectionKey, getCollection } from 'astro:content'
|
|
4
|
+
import blogConfigDefault from 'virtual:shipyard-blog/config'
|
|
5
5
|
import type { NavigationTree } from '@levino/shipyard-base'
|
|
6
6
|
import { Page as BaseLayout } from '@levino/shipyard-base/layouts'
|
|
7
|
+
import type { BlogConfig } from '../src/index'
|
|
7
8
|
|
|
8
9
|
type Props = {
|
|
9
10
|
title: string
|
|
10
11
|
canonicalUrl?: string
|
|
12
|
+
blogConfig?: BlogConfig
|
|
13
|
+
collectionName?: string
|
|
11
14
|
}
|
|
12
15
|
|
|
16
|
+
const blogConfig = Astro.props.blogConfig ?? blogConfigDefault
|
|
17
|
+
const collectionName =
|
|
18
|
+
Astro.props.collectionName ?? blogConfigDefault.collectionName
|
|
19
|
+
|
|
13
20
|
const locale = Astro.currentLocale
|
|
14
21
|
const { title, canonicalUrl } = Astro.props
|
|
15
22
|
const { blogSidebarCount, blogSidebarTitle, routeBasePath } = blogConfig
|
|
16
23
|
|
|
17
24
|
// Get and filter posts by locale
|
|
18
|
-
const allPosts = await getCollection(
|
|
25
|
+
const allPosts = await getCollection(collectionName as CollectionKey)
|
|
19
26
|
const filteredPosts = i18n
|
|
20
27
|
? allPosts.filter(({ id }) => {
|
|
21
28
|
const [postLocale] = id.split('/')
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { i18n } from 'astro:config/server'
|
|
3
|
+
import registry from 'virtual:shipyard-blog/registry'
|
|
4
|
+
import type { GetStaticPaths } from 'astro'
|
|
5
|
+
import { getInstanceConfig, getLocalePaths } from '../../src/staticPaths'
|
|
6
|
+
import BlogArchive from '../BlogArchive.astro'
|
|
7
|
+
|
|
8
|
+
export const getStaticPaths = (({ routePattern }) => {
|
|
9
|
+
const instance = getInstanceConfig(routePattern, registry)
|
|
10
|
+
return getLocalePaths(i18n).map((p) => ({
|
|
11
|
+
...p,
|
|
12
|
+
props: instance,
|
|
13
|
+
}))
|
|
14
|
+
}) satisfies GetStaticPaths
|
|
15
|
+
|
|
16
|
+
const instance = getInstanceConfig(Astro.routePattern, registry)
|
|
17
|
+
const blogConfig = Astro.props.blogConfig ?? instance.blogConfig
|
|
18
|
+
const tagsMap = Astro.props.tagsMap ?? instance.tagsMap
|
|
19
|
+
const collectionName = Astro.props.collectionName ?? instance.collectionName
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
<BlogArchive blogConfig={blogConfig} tagsMap={tagsMap} collectionName={collectionName} />
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { i18n } from 'astro:config/server'
|
|
3
|
+
import { type CollectionKey, getCollection } from 'astro:content'
|
|
4
|
+
import registry from 'virtual:shipyard-blog/registry'
|
|
5
|
+
import type { GetStaticPaths } from 'astro'
|
|
6
|
+
import {
|
|
7
|
+
computeBlogAuthorPaths,
|
|
8
|
+
getInstanceConfig,
|
|
9
|
+
} from '../../src/staticPaths'
|
|
10
|
+
import BlogAuthorPage from '../BlogAuthorPage.astro'
|
|
11
|
+
|
|
12
|
+
export const getStaticPaths = (async ({ routePattern }) => {
|
|
13
|
+
const instance = getInstanceConfig(routePattern, registry)
|
|
14
|
+
const allPosts = await getCollection(instance.collectionName as CollectionKey)
|
|
15
|
+
return computeBlogAuthorPaths(allPosts, instance.blogConfig, i18n).map(
|
|
16
|
+
(p) => ({
|
|
17
|
+
...p,
|
|
18
|
+
props: { ...p.props, ...instance },
|
|
19
|
+
}),
|
|
20
|
+
)
|
|
21
|
+
}) satisfies GetStaticPaths
|
|
22
|
+
|
|
23
|
+
const instance = getInstanceConfig(Astro.routePattern, registry)
|
|
24
|
+
const author = Astro.props.author
|
|
25
|
+
const blogConfig = Astro.props.blogConfig ?? instance.blogConfig
|
|
26
|
+
const tagsMap = Astro.props.tagsMap ?? instance.tagsMap
|
|
27
|
+
const collectionName = Astro.props.collectionName ?? instance.collectionName
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
<BlogAuthorPage author={author} blogConfig={blogConfig} tagsMap={tagsMap} collectionName={collectionName} />
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { i18n } from 'astro:config/server'
|
|
3
|
+
import registry from 'virtual:shipyard-blog/registry'
|
|
4
|
+
import type { GetStaticPaths } from 'astro'
|
|
5
|
+
import { getInstanceConfig, getLocalePaths } from '../../src/staticPaths'
|
|
6
|
+
import BlogAuthorsIndex from '../BlogAuthorsIndex.astro'
|
|
7
|
+
|
|
8
|
+
export const getStaticPaths = (({ routePattern }) => {
|
|
9
|
+
const instance = getInstanceConfig(routePattern, registry)
|
|
10
|
+
if (!instance.blogConfig.authorsEnabled) return []
|
|
11
|
+
return getLocalePaths(i18n).map((p) => ({
|
|
12
|
+
...p,
|
|
13
|
+
props: instance,
|
|
14
|
+
}))
|
|
15
|
+
}) satisfies GetStaticPaths
|
|
16
|
+
|
|
17
|
+
const instance = getInstanceConfig(Astro.routePattern, registry)
|
|
18
|
+
const blogConfig = Astro.props.blogConfig ?? instance.blogConfig
|
|
19
|
+
const tagsMap = Astro.props.tagsMap ?? instance.tagsMap
|
|
20
|
+
const collectionName = Astro.props.collectionName ?? instance.collectionName
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
<BlogAuthorsIndex blogConfig={blogConfig} tagsMap={tagsMap} collectionName={collectionName} />
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { i18n } from 'astro:config/server'
|
|
3
|
+
import { type CollectionKey, getCollection } from 'astro:content'
|
|
4
|
+
import registry from 'virtual:shipyard-blog/registry'
|
|
5
|
+
import type { GetStaticPaths } from 'astro'
|
|
6
|
+
import { computeBlogEntryPaths, getInstanceConfig } from '../../src/staticPaths'
|
|
7
|
+
import BlogEntry from '../BlogEntry.astro'
|
|
8
|
+
|
|
9
|
+
export const getStaticPaths = (async ({ routePattern }) => {
|
|
10
|
+
const instance = getInstanceConfig(routePattern, registry)
|
|
11
|
+
const allPosts = await getCollection(instance.collectionName as CollectionKey)
|
|
12
|
+
return computeBlogEntryPaths(allPosts, instance.blogConfig, i18n).map(
|
|
13
|
+
(p) => ({
|
|
14
|
+
...p,
|
|
15
|
+
props: { ...p.props, ...instance },
|
|
16
|
+
}),
|
|
17
|
+
)
|
|
18
|
+
}) satisfies GetStaticPaths
|
|
19
|
+
|
|
20
|
+
const instance = getInstanceConfig(Astro.routePattern, registry)
|
|
21
|
+
const entry = Astro.props.entry
|
|
22
|
+
const older = Astro.props.older
|
|
23
|
+
const newer = Astro.props.newer
|
|
24
|
+
const blogConfig = Astro.props.blogConfig ?? instance.blogConfig
|
|
25
|
+
const tagsMap = Astro.props.tagsMap ?? instance.tagsMap
|
|
26
|
+
const collectionName = Astro.props.collectionName ?? instance.collectionName
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
<BlogEntry
|
|
30
|
+
entry={entry}
|
|
31
|
+
older={older}
|
|
32
|
+
newer={newer}
|
|
33
|
+
collectionName={collectionName}
|
|
34
|
+
blogConfig={blogConfig}
|
|
35
|
+
tagsMap={tagsMap}
|
|
36
|
+
/>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { i18n } from 'astro:config/server'
|
|
3
|
+
import registry from 'virtual:shipyard-blog/registry'
|
|
4
|
+
import type { GetStaticPaths } from 'astro'
|
|
5
|
+
import { getInstanceConfig, getLocalePaths } from '../../src/staticPaths'
|
|
6
|
+
import BlogIndex from '../BlogIndex.astro'
|
|
7
|
+
|
|
8
|
+
export const getStaticPaths = (({ routePattern }) => {
|
|
9
|
+
const instance = getInstanceConfig(routePattern, registry)
|
|
10
|
+
return getLocalePaths(i18n).map((p) => ({
|
|
11
|
+
...p,
|
|
12
|
+
props: instance,
|
|
13
|
+
}))
|
|
14
|
+
}) satisfies GetStaticPaths
|
|
15
|
+
|
|
16
|
+
const instance = getInstanceConfig(Astro.routePattern, registry)
|
|
17
|
+
const blogConfig = Astro.props.blogConfig ?? instance.blogConfig
|
|
18
|
+
const tagsMap = Astro.props.tagsMap ?? instance.tagsMap
|
|
19
|
+
const collectionName = Astro.props.collectionName ?? instance.collectionName
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
<BlogIndex blogConfig={blogConfig} tagsMap={tagsMap} collectionName={collectionName} />
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { i18n } from 'astro:config/server'
|
|
3
|
+
import { type CollectionKey, getCollection } from 'astro:content'
|
|
4
|
+
import registry from 'virtual:shipyard-blog/registry'
|
|
5
|
+
import type { GetStaticPaths } from 'astro'
|
|
6
|
+
import {
|
|
7
|
+
computeBlogPaginatedPaths,
|
|
8
|
+
getInstanceConfig,
|
|
9
|
+
} from '../../src/staticPaths'
|
|
10
|
+
import BlogIndexPaginated from '../BlogIndexPaginated.astro'
|
|
11
|
+
|
|
12
|
+
export const getStaticPaths = (async ({ routePattern }) => {
|
|
13
|
+
const instance = getInstanceConfig(routePattern, registry)
|
|
14
|
+
const allPosts = await getCollection(instance.collectionName as CollectionKey)
|
|
15
|
+
return computeBlogPaginatedPaths(allPosts, instance.blogConfig, i18n).map(
|
|
16
|
+
(p) => ({
|
|
17
|
+
...p,
|
|
18
|
+
props: instance,
|
|
19
|
+
}),
|
|
20
|
+
)
|
|
21
|
+
}) satisfies GetStaticPaths
|
|
22
|
+
|
|
23
|
+
const instance = getInstanceConfig(Astro.routePattern, registry)
|
|
24
|
+
const blogConfig = Astro.props.blogConfig ?? instance.blogConfig
|
|
25
|
+
const tagsMap = Astro.props.tagsMap ?? instance.tagsMap
|
|
26
|
+
const collectionName = Astro.props.collectionName ?? instance.collectionName
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
<BlogIndexPaginated blogConfig={blogConfig} tagsMap={tagsMap} collectionName={collectionName} />
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { i18n } from 'astro:config/server'
|
|
3
|
+
import { type CollectionKey, getCollection } from 'astro:content'
|
|
4
|
+
import registry from 'virtual:shipyard-blog/registry'
|
|
5
|
+
import type { GetStaticPaths } from 'astro'
|
|
6
|
+
import { computeBlogTagPaths, getInstanceConfig } from '../../src/staticPaths'
|
|
7
|
+
import BlogTagPage from '../BlogTagPage.astro'
|
|
8
|
+
|
|
9
|
+
export const getStaticPaths = (async ({ routePattern }) => {
|
|
10
|
+
const instance = getInstanceConfig(routePattern, registry)
|
|
11
|
+
const allPosts = await getCollection(instance.collectionName as CollectionKey)
|
|
12
|
+
return computeBlogTagPaths(allPosts, instance.blogConfig, i18n).map((p) => ({
|
|
13
|
+
...p,
|
|
14
|
+
props: instance,
|
|
15
|
+
}))
|
|
16
|
+
}) satisfies GetStaticPaths
|
|
17
|
+
|
|
18
|
+
const instance = getInstanceConfig(Astro.routePattern, registry)
|
|
19
|
+
const blogConfig = Astro.props.blogConfig ?? instance.blogConfig
|
|
20
|
+
const tagsMap = Astro.props.tagsMap ?? instance.tagsMap
|
|
21
|
+
const collectionName = Astro.props.collectionName ?? instance.collectionName
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
<BlogTagPage blogConfig={blogConfig} tagsMap={tagsMap} collectionName={collectionName} />
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { i18n } from 'astro:config/server'
|
|
3
|
+
import registry from 'virtual:shipyard-blog/registry'
|
|
4
|
+
import type { GetStaticPaths } from 'astro'
|
|
5
|
+
import { getInstanceConfig, getLocalePaths } from '../../src/staticPaths'
|
|
6
|
+
import BlogTagsIndex from '../BlogTagsIndex.astro'
|
|
7
|
+
|
|
8
|
+
export const getStaticPaths = (({ routePattern }) => {
|
|
9
|
+
const instance = getInstanceConfig(routePattern, registry)
|
|
10
|
+
return getLocalePaths(i18n).map((p) => ({
|
|
11
|
+
...p,
|
|
12
|
+
props: instance,
|
|
13
|
+
}))
|
|
14
|
+
}) satisfies GetStaticPaths
|
|
15
|
+
|
|
16
|
+
const instance = getInstanceConfig(Astro.routePattern, registry)
|
|
17
|
+
const blogConfig = Astro.props.blogConfig ?? instance.blogConfig
|
|
18
|
+
const tagsMap = Astro.props.tagsMap ?? instance.tagsMap
|
|
19
|
+
const collectionName = Astro.props.collectionName ?? instance.collectionName
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
<BlogTagsIndex blogConfig={blogConfig} tagsMap={tagsMap} collectionName={collectionName} />
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { i18n } from 'astro:config/server'
|
|
2
|
+
import { type CollectionKey, getCollection } from 'astro:content'
|
|
3
|
+
import registry from 'virtual:shipyard-blog/registry'
|
|
4
|
+
import type { APIContext, GetStaticPaths } from 'astro'
|
|
5
|
+
import { createAtomResponse } from '../../../src/feeds'
|
|
6
|
+
import { getInstanceConfig, getLocalePaths } from '../../../src/staticPaths'
|
|
7
|
+
|
|
8
|
+
export const getStaticPaths = (({ routePattern }) => {
|
|
9
|
+
const { blogConfig } = getInstanceConfig(routePattern, registry)
|
|
10
|
+
if (!blogConfig.feedOptions?.atom) return []
|
|
11
|
+
return getLocalePaths(i18n)
|
|
12
|
+
}) satisfies GetStaticPaths
|
|
13
|
+
|
|
14
|
+
export const GET = async (context: APIContext) => {
|
|
15
|
+
const { blogConfig, collectionName } = getInstanceConfig(
|
|
16
|
+
context.routePattern,
|
|
17
|
+
registry,
|
|
18
|
+
)
|
|
19
|
+
const allPosts = await getCollection(collectionName as CollectionKey)
|
|
20
|
+
return createAtomResponse({
|
|
21
|
+
allPosts,
|
|
22
|
+
blogConfig,
|
|
23
|
+
site: context.site,
|
|
24
|
+
currentLocale: context.currentLocale,
|
|
25
|
+
i18n,
|
|
26
|
+
isDev: import.meta.env.DEV,
|
|
27
|
+
})
|
|
28
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { i18n } from 'astro:config/server'
|
|
2
|
+
import { type CollectionKey, getCollection } from 'astro:content'
|
|
3
|
+
import registry from 'virtual:shipyard-blog/registry'
|
|
4
|
+
import type { APIContext, GetStaticPaths } from 'astro'
|
|
5
|
+
import { createJsonFeedResponse } from '../../../src/feeds'
|
|
6
|
+
import { getInstanceConfig, getLocalePaths } from '../../../src/staticPaths'
|
|
7
|
+
|
|
8
|
+
export const getStaticPaths = (({ routePattern }) => {
|
|
9
|
+
const { blogConfig } = getInstanceConfig(routePattern, registry)
|
|
10
|
+
if (!blogConfig.feedOptions?.json) return []
|
|
11
|
+
return getLocalePaths(i18n)
|
|
12
|
+
}) satisfies GetStaticPaths
|
|
13
|
+
|
|
14
|
+
export const GET = async (context: APIContext) => {
|
|
15
|
+
const { blogConfig, collectionName } = getInstanceConfig(
|
|
16
|
+
context.routePattern,
|
|
17
|
+
registry,
|
|
18
|
+
)
|
|
19
|
+
const allPosts = await getCollection(collectionName as CollectionKey)
|
|
20
|
+
return createJsonFeedResponse({
|
|
21
|
+
allPosts,
|
|
22
|
+
blogConfig,
|
|
23
|
+
site: context.site,
|
|
24
|
+
currentLocale: context.currentLocale,
|
|
25
|
+
i18n,
|
|
26
|
+
isDev: import.meta.env.DEV,
|
|
27
|
+
})
|
|
28
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { i18n } from 'astro:config/server'
|
|
2
|
+
import { type CollectionKey, getCollection } from 'astro:content'
|
|
3
|
+
import registry from 'virtual:shipyard-blog/registry'
|
|
4
|
+
import type { APIContext, GetStaticPaths } from 'astro'
|
|
5
|
+
import { createRssResponse } from '../../../src/feeds'
|
|
6
|
+
import { getInstanceConfig, getLocalePaths } from '../../../src/staticPaths'
|
|
7
|
+
|
|
8
|
+
export const getStaticPaths = (({ routePattern }) => {
|
|
9
|
+
const { blogConfig } = getInstanceConfig(routePattern, registry)
|
|
10
|
+
if (!blogConfig.feedOptions?.rss) return []
|
|
11
|
+
return getLocalePaths(i18n)
|
|
12
|
+
}) satisfies GetStaticPaths
|
|
13
|
+
|
|
14
|
+
export const GET = async (context: APIContext) => {
|
|
15
|
+
const { blogConfig, collectionName } = getInstanceConfig(
|
|
16
|
+
context.routePattern,
|
|
17
|
+
registry,
|
|
18
|
+
)
|
|
19
|
+
const allPosts = await getCollection(collectionName as CollectionKey)
|
|
20
|
+
return createRssResponse({
|
|
21
|
+
allPosts,
|
|
22
|
+
blogConfig,
|
|
23
|
+
site: context.site,
|
|
24
|
+
currentLocale: context.currentLocale,
|
|
25
|
+
i18n,
|
|
26
|
+
isDev: import.meta.env.DEV,
|
|
27
|
+
})
|
|
28
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@levino/shipyard-blog",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.5",
|
|
4
4
|
"description": "Blog plugin for shipyard with pagination, sidebar, and git metadata",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.ts",
|
|
@@ -12,7 +12,9 @@
|
|
|
12
12
|
},
|
|
13
13
|
"./index.css": "./index.css",
|
|
14
14
|
"./astro": "./src/astro.ts",
|
|
15
|
-
"./astro/*": "./astro/*"
|
|
15
|
+
"./astro/*": "./astro/*",
|
|
16
|
+
"./staticPaths": "./src/staticPaths.ts",
|
|
17
|
+
"./feeds": "./src/feeds.ts"
|
|
16
18
|
},
|
|
17
19
|
"files": [
|
|
18
20
|
"astro",
|
|
@@ -31,7 +33,7 @@
|
|
|
31
33
|
"license": "MIT",
|
|
32
34
|
"homepage": "https://shipyard.levinkeller.de",
|
|
33
35
|
"dependencies": {
|
|
34
|
-
"@levino/shipyard-base": "^0.7.
|
|
36
|
+
"@levino/shipyard-base": "^0.7.5",
|
|
35
37
|
"ramda": "^0.31",
|
|
36
38
|
"yaml": "^2.0.0"
|
|
37
39
|
},
|