ساخت پلتفرم کامل وبلاگ: جستجو، فیلترینگ، هایلایت کد و فید RSS
این پست معماری و پیادهسازی پلتفرم وبلاگ که همین سایت را تامین میکند پوشش میدهد — ساختهشده با Next.js 15، Drizzle ORM، SQLite و Shiki.
استک فناوری
| کامپوننت | فناوری |
|---|---|
| فریمورک | Next.js 15 (App Router) |
| پایگاهداده | SQLite + Drizzle ORM |
| جستجو | جستجوی متن کامل از طریق SQLite FTS5 |
| هایلایت کد | Shiki (سمت سرور) |
| RSS | تولیدکننده XML اختصاصی |
| استایل | Tailwind CSS |
اسکیمای پایگاهداده
TYPESCRIPT
export const blogPosts = sqliteTable('blog_posts', {
id: integer('id').primaryKey({ autoIncrement: true }),
slug: text('slug').notNull().unique(),
titleEn: text('title_en').notNull(),
titleFa: text('title_fa').notNull(),
contentEn: text('content_en'),
contentFa: text('content_fa'),
status: text('status').default('draft'),
})جستجوی متن کامل با SQLite FTS5
SQL
CREATE VIRTUAL TABLE blog_fts USING fts5(
slug UNINDEXED,
title_en, title_fa,
excerpt_en, excerpt_fa,
content_en, content_fa,
content='blog_posts',
content_rowid='id'
);هایلایت کد با Shiki
TYPESCRIPT
import { codeToHtml } from 'shiki'
const html = await codeToHtml(node.value, {
lang: node.lang || 'text',
theme: 'github-dark',
})تولید فید RSS
TYPESCRIPT
// app/rss.xml/route.ts
export async function GET() {
const posts = db.prepare(`
SELECT * FROM blog_posts WHERE status = 'published' ORDER BY id DESC LIMIT 50
`).all()
const rss = `<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
<channel>
<title>وبلاگ HBZ — مهندسی زیرساخت</title>
${posts.map(p => `<item>
<title>${p.title_fa}</title>
<link>https://habibazar.ir/fa/blog/${p.slug}</link>
</item>`).join('')}
</channel>
</rss>`
return new Response(rss, {
headers: { 'Content-Type': 'application/rss+xml; charset=utf-8' }
})
}این پلتفرم این وبلاگ را به هر دو زبان انگلیسی و فارسی ارائه میدهد، با پشتیبانی کامل RTL، ذخیرهسازی محتوای مشترک و یک رابط مدیریتی واحد.
