-
Notifications
You must be signed in to change notification settings - Fork 1
/
[...slug].astro
142 lines (135 loc) · 5.77 KB
/
[...slug].astro
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
---
import BlogBase from '@/layouts/BlogBase.astro';
import { getCollection, getEntry} from 'astro:content';
import type { CollectionEntry } from 'astro:content';
import TagsList from '@/components/post/TagsList.astro';
import CategoryList from '@/components/post/CategoryList.astro';
import Utteranc from '@/components/app/Utteranc.astro';
import PostJSONLD from '@/components/app/head/PostJSONLD.astro';
import PostImage from '@/components/post/PostImage.astro';
import PostBlockquote from '@/components/post/PostBlockquote.astro';
import Info from '@/components/post/Info.astro'
import Video from '@/components/post/Video.astro'
import PostTableOfContent from '@/components/post/PostTableOfContent.astro';
import { Icon } from 'astro-icon/components'
import globalConfig from '@/globalConfig.ts';
import PostSeries from '@/components/post/PostSeries.astro'
export interface Props {
post: CollectionEntry<'post'>;
postsInSeries: CollectionEntry<'post'>[];
}
export async function getStaticPaths() {
function getTargetSeriesPosts(posts: CollectionEntry<'post'>[], targetSeries?: string) {
return targetSeries ? posts.filter((post) => post.data.series === targetSeries) : [];
}
const publishedPosts = await getCollection('post', (post) => (import.meta.env.PROD ? !post.data.isDraft : true));
const dateSortedPublishedPosts = publishedPosts.sort(
(a, b) => b.data.publishDate.getTime() - a.data.publishDate.getTime(),
)
return dateSortedPublishedPosts.map((post) => {
const postsInSeries = getTargetSeriesPosts(dateSortedPublishedPosts, post.data.series);
return ({
params: { slug: post.slug },
props: { post, postsInSeries },
})});
}
const { post, postsInSeries } = Astro.props;
const { icon, title, titleTC, publishDate, excerpt, themeColor, tags, category, lastModifiedDate } = post.data;
const { slug } = post;
const { Content, headings } = await post.render();
const author = post.data.author && (await getEntry('character', post.data.author?.id));
const tagHrefs = tags.map((tag) => `/post/tags/${tag}/`);
const rehypeAutoLinkStyle = '[&>h2:hover>.rehype-auto-link]:opacity-100 [&>h3:hover>.rehype-auto-link]:opacity-100 [&>h4:hover>.rehype-auto-link]:opacity-100 [&>h5:hover>.rehype-auto-link]:opacity-100 [&>h6:hover>.rehype-auto-link]:opacity-100'
---
<BlogBase title={titleTC} description={excerpt} themeColor={themeColor} thumbnail={{ src: `/post/${slug}`, alt: `${titleTC}` }}>
<PostJSONLD
slot="head"
headline={post.data.titleTC}
description={post.data.excerpt}
publishDate={post.data.publishDate}
keywords={post.data.tags}
articleSection={post.data.category}
author={author && {
nameTC: author.data.nameTC,
url: author.data?.social?.url,
}}
/>
<main class="mt-0 pt-8 sm:mt-[var(--mainNav-height)]">
<article
data-pagefind-body
data-article
class=`article-grid [grid-template-columns:1fr_min(65ch,_100%)_1fr] lg:px-auto prose mb-16 block w-full max-w-none px-8 dark:prose-invert md:prose-xl lg:grid ${rehypeAutoLinkStyle}`
>
<header class="not-prose mb-16 col-start-2">
{
icon && (
<div data-pagefind-ignore="all" class="mb-8 size-16 flex justify-center items-center rounded-lg" style={`background-color: ${themeColor}`}>
<Icon class="text-black" name={icon.name} size={32} />
</div>
)
}
<div class="relative mx-auto">
<div class="text-surface-inverse">
<div data-pagefind-weight="2" class="mb-2">{title}</div>
<h1 data-pagefind-meta="title" data-pagefind-meta={`themeColor:${themeColor}`} class="mb-4 text-4xl font-black md:text-6xl">
{titleTC}
</h1>
</div>
<div class="flex justify-between">
<div class="flex md:block">
<CategoryList categoryHref={`/post/categories/${category}/`} {category} />
<TagsList {tagHrefs} {tags} />
</div>
</div>
</div>
</header>
<aside
style="top: var(--mainNav-height);" class="col-start-3 sticky row-start-2 ml-4 hidden xl:block">
<div class="absolute top-0 divide-y divide-primary-200 dark:divide-primary-800">
<PostTableOfContent {headings} />
<!-- Post Date Info -->
<div class="inline-flex w-full flex-col gap-2 p-4">
<div class="inline-flex items-center gap-2 text-sm opacity-40 hover:opacity-100">
發布日期:
<time data-pagefind-sort="date">
{
publishDate
.toLocaleDateString('zh-TW', { year: 'numeric', month: '2-digit', day: '2-digit' })
.replace(/\//g, '-')
}
</time>
</div>
<div class="inline-flex items-center gap-2 text-sm opacity-40 hover:opacity-100">
<span>最後更新:</span>
<a
data-pagefind-ignore="all"
href={`${globalConfig.setting.postLastModifiedDateUrl}/${post.slug}.mdx`}
class=""
>
<span>
{
lastModifiedDate ?
lastModifiedDate
.toLocaleDateString('zh-TW', { year: 'numeric', month: '2-digit', day: '2-digit' })
.replace(/\//g, '-')
: '查看更新紀錄'
}
</span>
</a>
</div>
</div>
</div>
</aside>
<Content components={{ Info, Video, img: PostImage, blockquote: PostBlockquote }} />
{
postsInSeries.length ?
<div class="col-start-2">
<PostSeries currentPost={post}
postsInSeries={postsInSeries} />
</div>
: ''
}
<Utteranc />
</article>
</main>
</BlogBase>