优化结构
@@ -1,4 +1,4 @@
|
|||||||
name: 自动部署
|
name: 鑷姩閮ㄧ讲
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
@@ -13,11 +13,11 @@ jobs:
|
|||||||
deploy:
|
deploy:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: 检查分支
|
- name: 妫€鏌ュ垎鏀?
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
ref: master
|
ref: master
|
||||||
- name: 缓存项目 npm 包
|
- name: 缂撳瓨椤圭洰 npm 鍖?
|
||||||
id: cache-node-modules
|
id: cache-node-modules
|
||||||
uses: actions/cache@v3
|
uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
@@ -25,32 +25,29 @@ jobs:
|
|||||||
key: ${{ runner.os }}-nodeModules-${{ hashFiles('package-lock.json') }}-${{ hashFiles('package.json') }}
|
key: ${{ runner.os }}-nodeModules-${{ hashFiles('package-lock.json') }}-${{ hashFiles('package.json') }}
|
||||||
restore-keys: |
|
restore-keys: |
|
||||||
${{ runner.os }}-nodeModules-
|
${{ runner.os }}-nodeModules-
|
||||||
- name: 安装 Node
|
- name: 瀹夎 Node
|
||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: "22.x"
|
node-version: "22.x"
|
||||||
- name: 安装 Hexo
|
- name: 瀹夎渚濊禆
|
||||||
run: |
|
|
||||||
npm install hexo-cli --global
|
|
||||||
- name: 安装依赖
|
|
||||||
if: steps.cache-node-modules.outputs.cache-hit != 'true'
|
if: steps.cache-node-modules.outputs.cache-hit != 'true'
|
||||||
run: |
|
run: |
|
||||||
npm install
|
npm install
|
||||||
- name: 清理文件树
|
- name: 娓呯悊鏂囦欢鏍?
|
||||||
run: |
|
run: |
|
||||||
npm run clean
|
npm run clean
|
||||||
- name: 生成静态文件并压缩
|
- name: 鐢熸垚闈欐€佹枃浠跺苟鍘嬬缉
|
||||||
run: |
|
run: |
|
||||||
npm run build
|
npm run build
|
||||||
- name: 部署
|
- name: 閮ㄧ讲
|
||||||
run: |
|
run: |
|
||||||
cd ./public
|
cd ./dist
|
||||||
git init
|
git init
|
||||||
git config user.name "${{ gitea.actor }}"
|
git config user.name "${{ gitea.actor }}"
|
||||||
git config user.email "${{ gitea.actor }}@noreply.gitea.io"
|
git config user.email "${{ gitea.actor }}@noreply.gitea.io"
|
||||||
git add .
|
git add .
|
||||||
git commit -m "${{ gitea.event.head_commit.message }}··[$(date +"%Z %Y-%m-%d %A %H:%M:%S")]"
|
git commit -m "${{ gitea.event.head_commit.message }}路路[$(date +"%Z %Y-%m-%d %A %H:%M:%S")]"
|
||||||
git push --force --quiet "https://${{ gitea.actor }}:${{ secrets.DEPLOY_TOKEN }}@git.biss.click/biss/blog.git" master:page
|
git push --force --quiet "https://${{ gitea.actor }}:${{ secrets.DEPLOY_TOKEN }}@git.biss.click/biss/blog.git" master:page
|
||||||
- name: Deploy to Server
|
- name: Deploy to Server
|
||||||
run: |
|
run: |
|
||||||
curl -k -X POST "https://panel.biss.click/hook?access_key=1XJG8IvYTSZVvD5dpm86GYIpQxgxBcucULnX1MFskZSKayXU"
|
curl -k -X POST "https://panel.biss.click/hook?access_key=1XJG8IvYTSZVvD5dpm86GYIpQxgxBcucULnX1MFskZSKayXU"
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ db.json
|
|||||||
*.log
|
*.log
|
||||||
node_modules/
|
node_modules/
|
||||||
.astro/
|
.astro/
|
||||||
public/
|
dist/
|
||||||
.deploy*/
|
.deploy*/
|
||||||
_multiconfig.yml
|
_multiconfig.yml
|
||||||
.hintrc
|
.hintrc
|
||||||
|
|||||||
@@ -8,8 +8,6 @@ import remarkHexoLinkCards from './src/lib/remarkHexoLinkCards.mjs';
|
|||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
site: 'https://blog.biss.click',
|
site: 'https://blog.biss.click',
|
||||||
output: 'static',
|
output: 'static',
|
||||||
outDir: './public',
|
|
||||||
publicDir: './static',
|
|
||||||
integrations: [sitemap()],
|
integrations: [sitemap()],
|
||||||
markdown: {
|
markdown: {
|
||||||
processor: unified({
|
processor: unified({
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 457 KiB After Width: | Height: | Size: 457 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 269 KiB After Width: | Height: | Size: 269 KiB |
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 35 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 64 KiB |
@@ -1,7 +1,7 @@
|
|||||||
import { readdir, readFile, writeFile } from 'node:fs/promises';
|
import { readdir, readFile, writeFile } from 'node:fs/promises';
|
||||||
import { basename, extname, join, relative } from 'node:path';
|
import { basename, extname, join, relative } from 'node:path';
|
||||||
|
|
||||||
const POSTS_DIR = join(process.cwd(), 'posts');
|
const POSTS_DIR = join(process.cwd(), 'src', 'content', 'posts');
|
||||||
|
|
||||||
const CRC32_TABLE = new Uint32Array(256);
|
const CRC32_TABLE = new Uint32Array(256);
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
import { defineCollection, z } from 'astro:content';
|
||||||
|
import { glob } from 'astro/loaders';
|
||||||
|
|
||||||
|
const posts = defineCollection({
|
||||||
|
loader: glob({ pattern: '**/*.md', base: './src/content/posts' }),
|
||||||
|
schema: z.object({
|
||||||
|
title: z.any().optional(),
|
||||||
|
date: z.any().optional(),
|
||||||
|
abbrlink: z.any().optional(),
|
||||||
|
tags: z.any().optional(),
|
||||||
|
categories: z.any().optional(),
|
||||||
|
summary: z.any().optional(),
|
||||||
|
description: z.any().optional(),
|
||||||
|
comments: z.any().optional(),
|
||||||
|
cover: z.any().optional(),
|
||||||
|
}).passthrough(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const collections = { posts };
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
type PageModule = {
|
|
||||||
frontmatter: Record<string, unknown>;
|
|
||||||
Content: unknown;
|
|
||||||
rawContent?: () => string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type SitePage = PageModule & {
|
|
||||||
title: string;
|
|
||||||
slug: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
const modules = import.meta.glob<PageModule>('/source/**/index.md', { eager: true });
|
|
||||||
|
|
||||||
export function getSitePages(): SitePage[] {
|
|
||||||
return Object.entries(modules)
|
|
||||||
.filter(([path]) => {
|
|
||||||
if (path.includes('/_posts/') || path.includes('/_drafts/')) return false;
|
|
||||||
return ![
|
|
||||||
'/source/about/index.md',
|
|
||||||
'/source/cc/index.md',
|
|
||||||
'/source/cookie/index.md',
|
|
||||||
'/source/link/index.md',
|
|
||||||
'/source/privacy/index.md',
|
|
||||||
'/source/categories/index.md',
|
|
||||||
'/source/tags/index.md',
|
|
||||||
'/source/shuoshuo/index.md',
|
|
||||||
].includes(path);
|
|
||||||
})
|
|
||||||
.map(([path, module]) => {
|
|
||||||
const slug = path.replace('/source/', '').replace('/index.md', '');
|
|
||||||
return {
|
|
||||||
...module,
|
|
||||||
title: String(module.frontmatter.title ?? slug),
|
|
||||||
slug,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@@ -1,11 +1,8 @@
|
|||||||
type MarkdownModule = {
|
import type { CollectionEntry } from 'astro:content';
|
||||||
frontmatter: Record<string, unknown>;
|
import { getCollection } from 'astro:content';
|
||||||
Content: unknown;
|
|
||||||
rawContent?: () => string;
|
|
||||||
file?: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type BlogPost = MarkdownModule & {
|
export type BlogPost = {
|
||||||
|
entry: CollectionEntry<'posts'>;
|
||||||
title: string;
|
title: string;
|
||||||
slug: string;
|
slug: string;
|
||||||
date: Date;
|
date: Date;
|
||||||
@@ -16,10 +13,9 @@ export type BlogPost = MarkdownModule & {
|
|||||||
comments: boolean;
|
comments: boolean;
|
||||||
cover?: string;
|
cover?: string;
|
||||||
href: string;
|
href: string;
|
||||||
|
body: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
const modules = import.meta.glob<MarkdownModule>('/posts/**/*.md', { eager: true });
|
|
||||||
|
|
||||||
function asArray(value: unknown): string[] {
|
function asArray(value: unknown): string[] {
|
||||||
if (Array.isArray(value)) return value.map(String).filter(Boolean);
|
if (Array.isArray(value)) return value.map(String).filter(Boolean);
|
||||||
if (typeof value === 'string' && value.trim()) return [value.trim()];
|
if (typeof value === 'string' && value.trim()) return [value.trim()];
|
||||||
@@ -43,20 +39,19 @@ function formatDate(date: Date): string {
|
|||||||
}).format(date);
|
}).format(date);
|
||||||
}
|
}
|
||||||
|
|
||||||
function fallbackSlug(path: string): string {
|
function fallbackSlug(id: string): string {
|
||||||
return path
|
return id
|
||||||
.split('/')
|
.split('/')
|
||||||
.pop()
|
.pop()
|
||||||
?.replace(/\.md$/, '')
|
?.replace(/\.md$/, '')
|
||||||
.toLowerCase() ?? 'post';
|
.toLowerCase() ?? 'post';
|
||||||
}
|
}
|
||||||
|
|
||||||
function makeSummary(module: MarkdownModule): string {
|
function makeSummary(entry: CollectionEntry<'posts'>): string {
|
||||||
const explicit = module.frontmatter.summary ?? module.frontmatter.description;
|
const explicit = entry.data.summary ?? entry.data.description;
|
||||||
if (typeof explicit === 'string' && explicit.trim()) return explicit.trim();
|
if (typeof explicit === 'string' && explicit.trim()) return explicit.trim();
|
||||||
|
|
||||||
const raw = module.rawContent?.() ?? '';
|
return entry.body
|
||||||
return raw
|
|
||||||
.replace(/```[\s\S]*?```/g, '')
|
.replace(/```[\s\S]*?```/g, '')
|
||||||
.replace(/<[^>]+>/g, '')
|
.replace(/<[^>]+>/g, '')
|
||||||
.replace(/[#>*_`~\-\[\]\(\)]/g, '')
|
.replace(/[#>*_`~\-\[\]\(\)]/g, '')
|
||||||
@@ -65,34 +60,37 @@ function makeSummary(module: MarkdownModule): string {
|
|||||||
.slice(0, 120);
|
.slice(0, 120);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getAllPosts(): BlogPost[] {
|
export async function getAllPosts(): Promise<BlogPost[]> {
|
||||||
return Object.entries(modules)
|
const entries = await getCollection('posts');
|
||||||
.map(([path, module]) => {
|
|
||||||
const date = toDate(module.frontmatter.date);
|
return entries
|
||||||
const slug = String(module.frontmatter.abbrlink ?? fallbackSlug(path));
|
.map((entry) => {
|
||||||
const title = String(module.frontmatter.title ?? slug);
|
const date = toDate(entry.data.date);
|
||||||
|
const slug = String(entry.data.abbrlink ?? fallbackSlug(entry.id));
|
||||||
|
const title = String(entry.data.title ?? slug);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...module,
|
entry,
|
||||||
title,
|
title,
|
||||||
slug,
|
slug,
|
||||||
date,
|
date,
|
||||||
dateText: formatDate(date),
|
dateText: formatDate(date),
|
||||||
tags: asArray(module.frontmatter.tags),
|
tags: asArray(entry.data.tags),
|
||||||
categories: asArray(module.frontmatter.categories),
|
categories: asArray(entry.data.categories),
|
||||||
summary: makeSummary(module),
|
summary: makeSummary(entry),
|
||||||
comments: module.frontmatter.comments !== false,
|
comments: entry.data.comments !== false,
|
||||||
cover: typeof module.frontmatter.cover === 'string' ? module.frontmatter.cover : undefined,
|
cover: typeof entry.data.cover === 'string' ? entry.data.cover : undefined,
|
||||||
href: `/posts/${slug}/`,
|
href: `/posts/${slug}/`,
|
||||||
|
body: entry.body,
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
.sort((a, b) => b.date.valueOf() - a.date.valueOf());
|
.sort((a, b) => b.date.valueOf() - a.date.valueOf());
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getAllTags(): string[] {
|
export async function getAllTags(): Promise<string[]> {
|
||||||
return [...new Set(getAllPosts().flatMap((post) => post.tags))].sort((a, b) => a.localeCompare(b, 'zh-CN'));
|
return [...new Set((await getAllPosts()).flatMap((post) => post.tags))].sort((a, b) => a.localeCompare(b, 'zh-CN'));
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getAllCategories(): string[] {
|
export async function getAllCategories(): Promise<string[]> {
|
||||||
return [...new Set(getAllPosts().flatMap((post) => post.categories))].sort((a, b) => a.localeCompare(b, 'zh-CN'));
|
return [...new Set((await getAllPosts()).flatMap((post) => post.categories))].sort((a, b) => a.localeCompare(b, 'zh-CN'));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,26 +0,0 @@
|
|||||||
---
|
|
||||||
import BaseLayout from '@/layouts/BaseLayout.astro';
|
|
||||||
import PageHeaderCard from '@/components/PageHeaderCard.astro';
|
|
||||||
import { getSitePages } from '@/lib/pages';
|
|
||||||
|
|
||||||
export function getStaticPaths() {
|
|
||||||
return getSitePages().map((page) => ({
|
|
||||||
params: { slug: page.slug },
|
|
||||||
props: { page },
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
const { page } = Astro.props;
|
|
||||||
const { Content } = page;
|
|
||||||
---
|
|
||||||
|
|
||||||
<BaseLayout title={page.title}>
|
|
||||||
<section class="content-wrap narrow page-with-card">
|
|
||||||
<PageHeaderCard title={page.title} />
|
|
||||||
</section>
|
|
||||||
<article class="article page-article">
|
|
||||||
<div class="prose">
|
|
||||||
<Content />
|
|
||||||
</div>
|
|
||||||
</article>
|
|
||||||
</BaseLayout>
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import { getAllPosts } from '@/lib/posts';
|
import { getAllPosts } from '@/lib/posts';
|
||||||
|
|
||||||
export function GET() {
|
export async function GET() {
|
||||||
const posts = getAllPosts().map((post) => ({
|
const posts = (await getAllPosts()).map((post) => ({
|
||||||
title: post.title,
|
title: post.title,
|
||||||
href: post.href,
|
href: post.href,
|
||||||
}));
|
}));
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import PageHeaderCard from '@/components/PageHeaderCard.astro';
|
|||||||
import { getAllPosts } from '@/lib/posts';
|
import { getAllPosts } from '@/lib/posts';
|
||||||
import { getPageSlice } from '@/lib/pagination';
|
import { getPageSlice } from '@/lib/pagination';
|
||||||
|
|
||||||
const posts = getAllPosts();
|
const posts = await getAllPosts();
|
||||||
const pageData = getPageSlice(posts, 1);
|
const pageData = getPageSlice(posts, 1);
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ import PageHeaderCard from '@/components/PageHeaderCard.astro';
|
|||||||
import { getAllPosts } from '@/lib/posts';
|
import { getAllPosts } from '@/lib/posts';
|
||||||
import { getPageSlice, getPaginationPaths } from '@/lib/pagination';
|
import { getPageSlice, getPaginationPaths } from '@/lib/pagination';
|
||||||
|
|
||||||
export function getStaticPaths() {
|
export async function getStaticPaths() {
|
||||||
const posts = getAllPosts();
|
const posts = await getAllPosts();
|
||||||
|
|
||||||
return getPaginationPaths(posts).map((page) => ({
|
return getPaginationPaths(posts).map((page) => ({
|
||||||
params: { page: String(page) },
|
params: { page: String(page) },
|
||||||
@@ -15,7 +15,7 @@ export function getStaticPaths() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const { page } = Astro.props;
|
const { page } = Astro.props;
|
||||||
const posts = getAllPosts();
|
const posts = await getAllPosts();
|
||||||
const pageData = getPageSlice(posts, page);
|
const pageData = getPageSlice(posts, page);
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -4,15 +4,15 @@ import PageHeaderCard from '@/components/PageHeaderCard.astro';
|
|||||||
import PostCard from '@/components/PostCard.astro';
|
import PostCard from '@/components/PostCard.astro';
|
||||||
import { getAllCategories, getAllPosts } from '@/lib/posts';
|
import { getAllCategories, getAllPosts } from '@/lib/posts';
|
||||||
|
|
||||||
export function getStaticPaths() {
|
export async function getStaticPaths() {
|
||||||
return getAllCategories().map((category) => ({
|
return (await getAllCategories()).map((category) => ({
|
||||||
params: { category },
|
params: { category },
|
||||||
props: { category },
|
props: { category },
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
const { category } = Astro.props;
|
const { category } = Astro.props;
|
||||||
const posts = getAllPosts().filter((post) => post.categories.includes(category));
|
const posts = (await getAllPosts()).filter((post) => post.categories.includes(category));
|
||||||
---
|
---
|
||||||
|
|
||||||
<BaseLayout title={category}>
|
<BaseLayout title={category}>
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ import BaseLayout from '@/layouts/BaseLayout.astro';
|
|||||||
import PageHeaderCard from '@/components/PageHeaderCard.astro';
|
import PageHeaderCard from '@/components/PageHeaderCard.astro';
|
||||||
import { getAllCategories, getAllPosts } from '@/lib/posts';
|
import { getAllCategories, getAllPosts } from '@/lib/posts';
|
||||||
|
|
||||||
const posts = getAllPosts();
|
const posts = await getAllPosts();
|
||||||
const categories = getAllCategories();
|
const categories = await getAllCategories();
|
||||||
---
|
---
|
||||||
|
|
||||||
<BaseLayout title="分类">
|
<BaseLayout title="分类">
|
||||||
|
|||||||
@@ -6,9 +6,9 @@ import PostCard from '@/components/PostCard.astro';
|
|||||||
import { getAllCategories, getAllPosts, getAllTags } from '@/lib/posts';
|
import { getAllCategories, getAllPosts, getAllTags } from '@/lib/posts';
|
||||||
import { getPageSlice } from '@/lib/pagination';
|
import { getPageSlice } from '@/lib/pagination';
|
||||||
|
|
||||||
const posts = getAllPosts();
|
const posts = await getAllPosts();
|
||||||
const tags = getAllTags();
|
const tags = await getAllTags();
|
||||||
const categories = getAllCategories();
|
const categories = await getAllCategories();
|
||||||
const pageData = getPageSlice(posts, 1);
|
const pageData = getPageSlice(posts, 1);
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ import BaseLayout from '@/layouts/BaseLayout.astro';
|
|||||||
import { getAllCategories, getAllPosts, getAllTags } from '@/lib/posts';
|
import { getAllCategories, getAllPosts, getAllTags } from '@/lib/posts';
|
||||||
import { getPageSlice, getPaginationPaths } from '@/lib/pagination';
|
import { getPageSlice, getPaginationPaths } from '@/lib/pagination';
|
||||||
|
|
||||||
export function getStaticPaths() {
|
export async function getStaticPaths() {
|
||||||
const posts = getAllPosts();
|
const posts = await getAllPosts();
|
||||||
|
|
||||||
return getPaginationPaths(posts).map((page) => ({
|
return getPaginationPaths(posts).map((page) => ({
|
||||||
params: { page: String(page) },
|
params: { page: String(page) },
|
||||||
@@ -16,9 +16,9 @@ export function getStaticPaths() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const { page } = Astro.props;
|
const { page } = Astro.props;
|
||||||
const posts = getAllPosts();
|
const posts = await getAllPosts();
|
||||||
const tags = getAllTags();
|
const tags = await getAllTags();
|
||||||
const categories = getAllCategories();
|
const categories = await getAllCategories();
|
||||||
const pageData = getPageSlice(posts, page);
|
const pageData = getPageSlice(posts, page);
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -3,19 +3,20 @@ import ArticleSidebar from '@/components/ArticleSidebar.astro';
|
|||||||
import PostCopyrightCard from '@/components/PostCopyrightCard.astro';
|
import PostCopyrightCard from '@/components/PostCopyrightCard.astro';
|
||||||
import TwikooComments from '@/components/TwikooComments.astro';
|
import TwikooComments from '@/components/TwikooComments.astro';
|
||||||
import BaseLayout from '@/layouts/BaseLayout.astro';
|
import BaseLayout from '@/layouts/BaseLayout.astro';
|
||||||
|
import { render } from 'astro:content';
|
||||||
import { getAllPosts } from '@/lib/posts';
|
import { getAllPosts } from '@/lib/posts';
|
||||||
|
|
||||||
export function getStaticPaths() {
|
export async function getStaticPaths() {
|
||||||
return getAllPosts().map((post) => ({
|
return (await getAllPosts()).map((post) => ({
|
||||||
params: { slug: post.slug },
|
params: { slug: post.slug },
|
||||||
props: { post },
|
props: { post },
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
const { post } = Astro.props;
|
const { post } = Astro.props;
|
||||||
const { Content } = post;
|
const { Content } = await render(post.entry);
|
||||||
const allPosts = getAllPosts();
|
const allPosts = await getAllPosts();
|
||||||
const rawContent = post.rawContent?.() ?? '';
|
const rawContent = post.body;
|
||||||
const textContent = rawContent
|
const textContent = rawContent
|
||||||
.replace(/```[\s\S]*?```/g, '')
|
.replace(/```[\s\S]*?```/g, '')
|
||||||
.replace(/<[^>]+>/g, '')
|
.replace(/<[^>]+>/g, '')
|
||||||
@@ -69,7 +70,7 @@ function makeToc(raw: string) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const toc = makeToc(post.rawContent?.() ?? '');
|
const toc = makeToc(post.body);
|
||||||
const relatedPosts = allPosts
|
const relatedPosts = allPosts
|
||||||
.filter((item) => item.slug !== post.slug)
|
.filter((item) => item.slug !== post.slug)
|
||||||
.filter((item) => item.categories.some((category) => post.categories.includes(category)))
|
.filter((item) => item.categories.some((category) => post.categories.includes(category)))
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import rss from '@astrojs/rss';
|
import rss from '@astrojs/rss';
|
||||||
import { getAllPosts } from '@/lib/posts';
|
import { getAllPosts } from '@/lib/posts';
|
||||||
|
|
||||||
export function GET(context) {
|
export async function GET(context) {
|
||||||
const posts = getAllPosts();
|
const posts = await getAllPosts();
|
||||||
|
|
||||||
return rss({
|
return rss({
|
||||||
title: "Bi's Blog",
|
title: "Bi's Blog",
|
||||||
|
|||||||
@@ -4,15 +4,15 @@ import PageHeaderCard from '@/components/PageHeaderCard.astro';
|
|||||||
import PostCard from '@/components/PostCard.astro';
|
import PostCard from '@/components/PostCard.astro';
|
||||||
import { getAllPosts, getAllTags } from '@/lib/posts';
|
import { getAllPosts, getAllTags } from '@/lib/posts';
|
||||||
|
|
||||||
export function getStaticPaths() {
|
export async function getStaticPaths() {
|
||||||
return getAllTags().map((tag) => ({
|
return (await getAllTags()).map((tag) => ({
|
||||||
params: { tag },
|
params: { tag },
|
||||||
props: { tag },
|
props: { tag },
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
const { tag } = Astro.props;
|
const { tag } = Astro.props;
|
||||||
const posts = getAllPosts().filter((post) => post.tags.includes(tag));
|
const posts = (await getAllPosts()).filter((post) => post.tags.includes(tag));
|
||||||
---
|
---
|
||||||
|
|
||||||
<BaseLayout title={tag}>
|
<BaseLayout title={tag}>
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ import BaseLayout from '@/layouts/BaseLayout.astro';
|
|||||||
import PageHeaderCard from '@/components/PageHeaderCard.astro';
|
import PageHeaderCard from '@/components/PageHeaderCard.astro';
|
||||||
import { getAllPosts, getAllTags } from '@/lib/posts';
|
import { getAllPosts, getAllTags } from '@/lib/posts';
|
||||||
|
|
||||||
const posts = getAllPosts();
|
const posts = await getAllPosts();
|
||||||
const tags = getAllTags();
|
const tags = await getAllTags();
|
||||||
---
|
---
|
||||||
|
|
||||||
<BaseLayout title="标签">
|
<BaseLayout title="标签">
|
||||||
|
|||||||