项目专题 · 内容发布流程
同步可发布的博客正文
明确选择 Obsidian 原笔记同步博客正文,同时保留既有文章地址与站点技术字段。
问题
写作工作区里同时存在私人记录、过程材料与准备公开的文章。站点需要接收可发布正文,但不能把整个 Obsidian 空间当作公开内容源。
同一篇文章进入站点后,还会拥有面向公开页面维护的 frontmatter。后续同步正文时,如果直接覆盖整个文件,这些站点元数据也会被源笔记一并替换。
目的
原笔记保留在自然目录,通过 Admin 明确选择公开。默认目录与待确认扫描排除“博客发布”和 picture,来源目录与网站专题可以不同。
已有文章通过作者确认重新绑定原笔记,保留目标文件名、URL、mediaId 和其他技术字段;旧绑定在明确迁移前继续使用,不自动替换路径。
解决方案
Admin 按文件名或标题的大小写、Unicode 与空白规范化结果提示候选,排除历史发布副本;唯一候选也不自动绑定。可能重复的新导入会被拒绝,提示明确绑定已有文章。
原笔记与旧副本可能各有修改,作者应比较并选择继续维护的原笔记内容;迁移不自动覆盖笔记,也不删除私人副本。
博客同步不再进入 prebuild,起源同步与其他内容准备保留。脚本不传 --file 时只输出说明,不扫描历史目录或写入;手动兜底使用 npm run sync:blog -- --file "<原笔记路径>",加 --dry-run 可先预览。
脚本代码展示
sync-obsidian-blog.mjs
import { existsSync, mkdirSync, readFileSync, statSync, writeFileSync } from 'node:fs';
import { basename, join, relative } from 'node:path';
import { mergeBlogSource } from '../src/shared/content/frontmatter.mjs';
const root = process.cwd();
const isDryRun = process.argv.includes('--dry-run');
const fileOption = process.argv.indexOf('--file');
const explicitFile = fileOption < 0 ? null : process.argv[fileOption + 1];
if (fileOption >= 0 && (!explicitFile || explicitFile.startsWith('--') || !/\.md$/i.test(explicitFile))) {
throw new TypeError('--file requires one existing Markdown file.');
}
if (!explicitFile) {
console.log('已停用“博客发布”目录自动同步。请在 Admin 纳入或绑定原文;手动同步单篇可使用 --file <原文完整路径>。');
process.exit(0);
}
if (!existsSync(explicitFile) || !statSync(explicitFile).isFile())
throw new TypeError(`Markdown source does not exist: ${explicitFile}`);
const destination = join(root, 'src', 'content', 'blog');
const destinationFile = join(destination, basename(explicitFile));
const sourceContent = readFileSync(explicitFile, 'utf8');
const destinationContent = existsSync(destinationFile) ? readFileSync(destinationFile, 'utf8') : '';
const nextContent = mergeBlogSource(sourceContent, destinationContent, explicitFile);
if (!isDryRun) {
mkdirSync(destination, { recursive: true });
if (nextContent !== destinationContent) writeFileSync(destinationFile, nextContent, 'utf8');
}
console.log(isDryRun ? 'Obsidian blog markdown files that would be synced:' : 'Synced Obsidian blog markdown files:');
console.log(`- ${relative(root, destinationFile)}`);