diff --git a/src/routes/+layout.server.ts b/src/routes/+layout.server.ts index e31b21c..9fc531f 100644 --- a/src/routes/+layout.server.ts +++ b/src/routes/+layout.server.ts @@ -1,9 +1,11 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ + import type { LayoutServerLoad } from './$types'; export const load: LayoutServerLoad = async ({ platform }) => { const db = platform?.env?.DB; - - let aliases = { + + const aliases = { post: '文章', page: '页面', category: '分类', @@ -11,7 +13,7 @@ export const load: LayoutServerLoad = async ({ platform }) => { series: '系列' }; - let site = { + const site = { title: 'BlogFlare', description: 'A high-performance blog powered by Cloudflare D1, R2, and KV.', avatar_enabled: 'true', @@ -20,10 +22,10 @@ export const load: LayoutServerLoad = async ({ platform }) => { if (db) { try { - const { results } = await db.prepare( - "SELECT key, value FROM settings WHERE key LIKE 'alias.%' OR key LIKE 'site.%'" - ).all(); - + const { results } = await db + .prepare("SELECT key, value FROM settings WHERE key LIKE 'alias.%' OR key LIKE 'site.%'") + .all(); + if (results && results.length > 0) { results.forEach((row: any) => { if (row.key.startsWith('alias.')) { @@ -39,8 +41,8 @@ export const load: LayoutServerLoad = async ({ platform }) => { } }); } - } catch (e) { - console.error('Failed to load settings', e); + } catch (err: any) { + console.error('Failed to load settings', err); } } diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index e0ba08a..b0955dd 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -1,9 +1,10 @@ - {$page.data.site?.title || 'BlogFlare'} - {$page.data.site?.description || 'A Pure Cloudflare Blog'} + {$page.data.site?.title || 'BlogFlare'} - {$page.data.site?.description || + 'A Pure Cloudflare Blog'} {#if $page.url.pathname.startsWith('/admin')} {@render children()} {:else} -
-
- -
- {#if $page.url.pathname === '/'} -
- {#if $page.data.site?.avatar_enabled !== 'false'} -
- -
+
+
+ +
+ {#if $page.url.pathname === '/'} +
+ {#if $page.data.site?.avatar_enabled !== 'false'} +
+ +

+ {$page.data.site?.description || + 'A high-performance blog powered by Cloudflare D1, R2, and KV.'} +

+
{/if} -

{$page.data.site?.title || 'BlogFlare'}

-

{$page.data.site?.description || 'A high-performance blog powered by Cloudflare D1, R2, and KV.'}

+ +
+
+ {@render children()} +
+
+ +
+
+
+

+ © {new Date().getFullYear()} + {$page.data.site?.title || 'BlogFlare'} +

+

感谢陪伴:

+
+
+

+ Powered by SvelteKit & + Cloudflare +

+

+ Theme inspired by VOID & + DoIt +

+
+
+
+ + +
- {/if} - -
-
- {@render children()} -
-
- -
-
-
-

© {new Date().getFullYear()} {$page.data.site?.title || 'BlogFlare'}

-

感谢陪伴:

-
-
-

Powered by SvelteKit & Cloudflare

-

Theme inspired by VOID & DoIt

-
-
-
- - - -
{/if} diff --git a/src/routes/+page.server.ts b/src/routes/+page.server.ts index 2b8b5b6..301cfcb 100644 --- a/src/routes/+page.server.ts +++ b/src/routes/+page.server.ts @@ -1,8 +1,10 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ + import type { PageServerLoad } from './$types'; export const load: PageServerLoad = async ({ platform }) => { const db = platform?.env?.DB; - + if (!db) { // Fallback data if DB is not available (e.g. during dev without wrangler, or missing bindings) return { @@ -10,60 +12,68 @@ export const load: PageServerLoad = async ({ platform }) => { { id: 1, title: 'Hello, BlogFlare! (Fallback)', - excerpt: 'This is my first post on BlogFlare. Welcome to my new blog powered by SvelteKit.', + excerpt: + 'This is my first post on BlogFlare. Welcome to my new blog powered by SvelteKit.', date: 'Jul 12, 2026', - slug: 'hello-world' + slug: 'hello-world', + cover: null }, { id: 2, title: 'The Beauty of Typecho Theme VOID', - excerpt: 'VOID is a minimalist, typography-oriented theme that brings elegance to your reading experience.', + excerpt: + 'VOID is a minimalist, typography-oriented theme that brings elegance to your reading experience.', date: 'Jul 11, 2026', - slug: 'beauty-of-void' + slug: 'beauty-of-void', + cover: null } ] }; } try { - const { results } = await db.prepare( - `SELECT p.id, p.slug, p.title, p.content, p.cover, p.published_at as date + const { results } = await db + .prepare( + `SELECT p.id, p.slug, p.title, p.content, p.cover, p.published_at as date FROM posts p ORDER BY p.published_at DESC LIMIT 10` - ).all(); + ) + .all(); // Convert date to string for serialization - const formattedPosts = results.map(post => { + const formattedPosts = results.map((post) => { const d = new Date(post.date as string); const month = d.toLocaleString('en-US', { month: 'short' }); const day = d.getDate(); const year = d.getFullYear(); - - let excerpt = ''; - let contentStr = post.content as string || ''; - + + let excerpt; + let contentStr = (post.content as string) || ''; + // Filter out Hugo shortcodes like {{< admonition abstract "标题" >}} contentStr = contentStr.replace(/\{\{<[\s\S]*?>\}\}/g, ''); - + const parts = contentStr.split(''); if (parts.length > 1) { excerpt = parts[0].trim(); } else { // Strip basic markdown syntax for the automatic excerpt - let plainText = contentStr.replace(/[#*\`>~\\[\\]\\(\\)\\-]/g, '').trim(); + const plainText = contentStr.replace(/[#*`>~[\]()-]/g, '').trim(); excerpt = plainText.substring(0, 150).trim(); } - + // Append ... to indicate there is more to read if (excerpt && !excerpt.endsWith('...')) { excerpt += '...'; } - + // Do not send full content to the list view to save bandwidth - const { content, ...restPost } = post as any; - + return { - ...restPost, + id: post.id as number, + title: post.title as string, + slug: post.slug as string, + cover: post.cover as string | null, date: `${month} ${day}, ${year}`, excerpt }; @@ -72,7 +82,7 @@ export const load: PageServerLoad = async ({ platform }) => { return { posts: formattedPosts }; - } catch (err) { + } catch (err: any) { console.error('Error fetching posts from D1:', err); return { posts: [] }; } diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index 678ec4e..425b839 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -1,17 +1,21 @@ - {$page.data.site?.title || 'BlogFlare'} - {$page.data.site?.description || 'A Pure Cloudflare Blog'} + {$page.data.site?.title || 'BlogFlare'} - {$page.data.site?.description || + 'A Pure Cloudflare Blog'}
- {#each data.posts as post} - + {#each data.posts as post (post.id || post)} +
{#if post.cover}
diff --git a/src/routes/[slug]/+page.server.ts b/src/routes/[slug]/+page.server.ts index a39c8df..bdd099a 100644 --- a/src/routes/[slug]/+page.server.ts +++ b/src/routes/[slug]/+page.server.ts @@ -1,3 +1,5 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ + import { error } from '@sveltejs/kit'; import type { PageServerLoad } from './$types'; @@ -10,11 +12,20 @@ export const load: PageServerLoad = async ({ params, platform }) => { } try { - const page = await db.prepare( - `SELECT title, slug, content, published_at, updated_at + const page = await db + .prepare( + `SELECT title, slug, content, published_at, updated_at FROM pages WHERE slug = ?` - ).bind(slug).first<{ title: string; slug: string; content: string; published_at: string; updated_at: string }>(); + ) + .bind(slug) + .first<{ + title: string; + slug: string; + content: string; + published_at: string; + updated_at: string; + }>(); if (!page) { throw error(404, '该页面不存在'); @@ -23,8 +34,8 @@ export const load: PageServerLoad = async ({ params, platform }) => { return { page }; - } catch (err: any) { - if (err?.status === 404) throw err; + } catch (err: unknown) { + if ((err as any)?.status === 404) throw err; console.error('Error loading page:', err); throw error(500, '加载页面失败'); } diff --git a/src/routes/[slug]/+page.svelte b/src/routes/[slug]/+page.svelte index 99d0887..b603d84 100644 --- a/src/routes/[slug]/+page.svelte +++ b/src/routes/[slug]/+page.svelte @@ -2,7 +2,7 @@ import { page } from '$app/stores'; import type { PageData } from './$types'; import MarkdownRenderer from '$lib/components/MarkdownRenderer.svelte'; - + let { data }: { data: PageData } = $props(); @@ -16,10 +16,8 @@ - +
- - diff --git a/src/routes/archive/+page.server.ts b/src/routes/archive/+page.server.ts index 056ac0c..7c2d940 100644 --- a/src/routes/archive/+page.server.ts +++ b/src/routes/archive/+page.server.ts @@ -9,21 +9,25 @@ export const load: PageServerLoad = async ({ platform }) => { try { // Fetch all posts, ordered by published_at descending - const result = await db.prepare(` + const result = await db + .prepare( + ` SELECT slug, title, published_at FROM posts ORDER BY published_at DESC - `).all(); + ` + ) + .all(); const posts = result.results as Array<{ slug: string; title: string; published_at: string }>; // Group posts by year const archives: Record = {}; - - posts.forEach(post => { + + posts.forEach((post) => { const date = new Date(post.published_at); const year = date.getFullYear().toString(); - + if (!archives[year]) { archives[year] = []; } @@ -37,7 +41,7 @@ export const load: PageServerLoad = async ({ platform }) => { archives, years }; - } catch (err: any) { + } catch (err: unknown) { console.error('Error fetching archives:', err); throw error(500, 'Failed to fetch archives'); } diff --git a/src/routes/archive/+page.svelte b/src/routes/archive/+page.svelte index a60792b..20a3660 100644 --- a/src/routes/archive/+page.svelte +++ b/src/routes/archive/+page.svelte @@ -1,6 +1,7 @@ @@ -83,7 +90,9 @@ {#if data.series && data.seriesPosts.length > 0}

- {$page.data.aliases?.series || '系列'}:{data.series.name} + {$page.data.aliases?.series || '系列'}:{data.series.name}

    {#each data.seriesPosts as seriesPost (seriesPost.id)} @@ -91,7 +100,9 @@ {#if seriesPost.id === data.post.id} {seriesPost.title} {:else} - {seriesPost.title} + {seriesPost.title} {/if} {/each} @@ -99,22 +110,28 @@ {#if previousSeriesPost || nextSeriesPost} {/if}
{/if} - + {#if data.tags && data.tags.length > 0}
{#each data.tags as tag (tag.id)} - + {/each}
{/if} @@ -122,19 +139,31 @@
{#if hasToc} - - - -
sidebarShow = false}>
-
-
-
+ + + +
(sidebarShow = false)}>
+
+
+
- - -
sidebarShow = !sidebarShow}> - -
+ + +
(sidebarShow = !sidebarShow)}> + +
{/if} @@ -194,7 +223,11 @@ } @media (max-width: 640px) { - .series-prev-next { grid-template-columns: 1fr; } - .series-prev-next a:last-child { text-align: left; } + .series-prev-next { + grid-template-columns: 1fr; + } + .series-prev-next a:last-child { + text-align: left; + } } diff --git a/src/routes/series/+page.server.ts b/src/routes/series/+page.server.ts index feb930e..dc4b24b 100644 --- a/src/routes/series/+page.server.ts +++ b/src/routes/series/+page.server.ts @@ -1,10 +1,11 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ + import { error } from '@sveltejs/kit'; import type { PageServerLoad } from './$types'; export const load: PageServerLoad = async ({ platform }) => { const db = platform?.env?.DB; if (!db) throw error(500, '数据库未连接'); - try { const { results } = await db .prepare( @@ -24,7 +25,7 @@ export const load: PageServerLoad = async ({ platform }) => { post_count: number; }> }; - } catch (err) { + } catch (err: any) { console.error('Error fetching public series list:', err); throw error(500, '读取系列列表失败'); } diff --git a/src/routes/series/[slug]/+page.server.ts b/src/routes/series/[slug]/+page.server.ts index 2a3d3fb..6ad4bc1 100644 --- a/src/routes/series/[slug]/+page.server.ts +++ b/src/routes/series/[slug]/+page.server.ts @@ -4,14 +4,12 @@ import type { PageServerLoad } from './$types'; export const load: PageServerLoad = async ({ platform, params }) => { const db = platform?.env?.DB; if (!db) throw error(500, '数据库未连接'); - try { const series = await db .prepare('SELECT id, name, slug, description FROM series WHERE slug = ?') .bind(params.slug) .first<{ id: number; name: string; slug: string; description: string | null }>(); if (!series) throw error(404, '系列不存在'); - const { results } = await db .prepare( `SELECT id, slug, title, series_weight, published_at