起因:obsidian 目前最完美的免费发布方案 - 渐进式教程 — 🌱 oldwinter の数字花园在看了个这个文章后想把自己的知识库发布,但又想拥有一般的静态博客的样式,仅仅支持在文章中双链到我自己的知识库笔记,同时又可以限定权限,而且本地 ob 同步操作也要快。

以下是几个备选:

名称链接简介
PerliteGitHub - secure-77/Perlite: A web-based markdown viewer optimized for Obsidian和 Ob 界面相当相似,但没有权限校验
Quartz 4 (选用)Welcome to Quartz 4很酷

目前感觉 Quartz 是最优解,故选用,参考这个教程

一些配置

链接原 Obsidian 仓库

跟着教程配置完后就可以在本地和 Cloudflare 跑起来一个空网站了,接下来是加入自己已经积累过的文档,这里推荐使用硬链接的方式绑定过去,免得浪费空间(我仓库得有 1GB+):

mklink /D "E://study/quartz/content" "E://study/myObsidian"
  • 第一个路径为目标路径,第二个为被链接过去的路径
  • 注意提前把 index.md 文件在 myObsidian 中创建好,然后把 quartz/content 文件夹删掉,因为硬链接会重新创建一个 content 文件夹

不过在使用 npx quartz sync 发布时候会自动进行去链接引用,实际上也就是重新复制文件过去然后提交,或者直接在原本的obsidian库的父目录进行安装 quartz,但我自己是在 onedrive 文件夹,所以就不整了。

限制访问

Quartz 给了两种白名单和黑名单两种方案,我文件特别多,一方面怕有啥隐私文件忘了设置,另一方面是减少发布文件数量,所以选用白名单方案,也就是只有配置了 publish: true 属性的文件才会可以访问。

具体来说是修改 quartz.config.ts 文件:

filters: [Plugin.ExplicitPublish()],

filters 选项中配置 ExplicitPublish 插件,注意默认是选用 RemoveDrafts 插件,需要删掉,具体文档查看这个页面

之后首先得把 index.md 设置为发布,直接在文件开头这么写:

---
publish: true
---

注意冒号后要有一个空格,新版 Obsidian 对配置项做了美化:

当然我估计你也会有和我一样的需求,也就是想要把一个文件夹内的原子笔记都发布,这样就不需要手动一个一个添加标签了,为此以下 python 脚本可以实现:

import os
 
def process_markdown_files(directory):
    print(f"📂 正在扫描目录: {directory}")
 
    for root, _, files in os.walk(directory):
        print(f"\n📁 进入文件夹: {root}")
 
        for filename in files:
            if filename.endswith(".md"):  # 只处理 Markdown 文件
                file_path = os.path.join(root, filename)
                print(f"🔍 发现 Markdown 文件: {file_path}")
 
                try:
                    with open(file_path, "r", encoding="utf-8") as file:
                        content = file.readlines()  # 逐行读取,保持换行符
 
                    # 检查文件是否已有 "publish: true"
                    if any(line.strip() == "publish: true" for line in content):
                        print(f"✅ {filename} 已包含 'publish: true',跳过修改。")
                        continue
 
                    # 找到 YAML 头部插入位置(位于 "---" 之间)
                    yaml_start = None
                    yaml_end = None
 
                    for i, line in enumerate(content):
                        if line.strip() == "---":
                            if yaml_start is None:
                                yaml_start = i  # 记录 YAML 头部起始位置
                            elif yaml_end is None:
                                yaml_end = i  # 记录 YAML 头部结束位置
                                break
 
                    # 如果找到 YAML 头部,则在其中添加 "publish: true"
                    if yaml_start is not None and yaml_end is not None:
                        print(f"✏️  {filename} 发现 YAML 头部,插入 'publish: true'")
                        content.insert(yaml_end, "publish: true\n")
 
                        with open(file_path, "w", encoding="utf-8") as file:
                            file.writelines(content)  # 重新写入文件
 
                    else:
                        # 如果没有 YAML 头部,则创建一个
                        print(f"⚠️  {filename} 没有 YAML 头部,创建新的 YAML 头部")
                        new_content = ["---\n", "publish: true\n", "---\n\n"] + content
 
                        with open(file_path, "w", encoding="utf-8") as file:
                            file.writelines(new_content)
 
                    print(f"✅ {filename} 处理完成!")
 
                except Exception as e:
                    print(f"❌ 处理 {filename} 时发生错误: {e}")
 
    print("\n🎉 所有 Markdown 文件处理完成!")
 
 
if __name__ == "__main__":
    current_directory = os.getcwd()  # 获取当前运行目录
    process_markdown_files(current_directory)

在需要公布的文件夹中运行该 py 文件即可一次全部发布,这样之后再进行双链就很方便了。

不过在写新的笔记时候大多数也是公开的,而我本身又喜欢在文件命名中加入时间戳(看着很好看),故可以使用 Obsidian 的官方插件 Unique Note 来实现自定义模板

去掉左侧资源管理和双链图

我的目录组织实在太烂了,故还是隐藏比较好(

quartz.layout.ts 删除或注释以下插件即可:

// components for pages that display a single page (e.g. a single note)
export const defaultContentPageLayout: PageLayout = {
  beforeBody: [
    // Component.Breadcrumbs(), // 每个page中顶端的面包屑导航
    Component.ArticleTitle(),
    Component.ContentMeta(),
    Component.TagList(),
  ],
  left: [
    Component.PageTitle(),
    Component.MobileOnly(Component.Spacer()),
    Component.Search(),
    Component.Darkmode(),
    // Component.Explorer(), // 每个 page 中的左侧任务管理器
    Component.DesktopOnly(Component.TableOfContents()), // 这里把 right 中的文章目录组件给移动到左边代替任务管理器的位置
  ],
  right: [
    // Component.Graph(), // 每个 page 中的右侧双链图
    Component.Backlinks(),
  ],
}
 
// components for pages that display lists of pages  (e.g. tags or folders)
export const defaultListPageLayout: PageLayout = {
  beforeBody: [Component.Breadcrumbs(), Component.ArticleTitle(), Component.ContentMeta()],
  left: [
    Component.PageTitle(),
    Component.MobileOnly(Component.Spacer()),
    Component.Search(),
    Component.Darkmode(),
    // Component.Explorer(), // 空页面的左侧资源浏览器
  ],
  right: [],
}

当然这样也不能完全隐藏,因为浏览器的连接地址还是会漏出来的,所以得注意好发布权限管理。

美化

TODO 未来可能会参考这几位的知识花园样式:

标题描述
jzhao.xyz蓝色风格,很酷
Math Wiki非常精简
Matt Dunn’s Second Brain简洁好看
Garden’s Gate好看
🪴 Read Me多彩链接很有意思
Data Glossary 🧠蓝色主题,好看
Second Brain: Crafted, Curated, Connected, Compounded红色主题,好看
Site Unreachable首页很棒,好看