<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>GitHub-Pages on dongxiaoqi's Blog</title><link>https://notion.dongxiaoqi.top/tags/github-pages/</link><description>Recent content in GitHub-Pages on dongxiaoqi's Blog</description><generator>Hugo -- gohugo.io</generator><language>zh-CN</language><copyright>CC BY-NC-SA 4.0</copyright><lastBuildDate>Thu, 13 Aug 2026 12:21:00 +0800</lastBuildDate><atom:link href="https://notion.dongxiaoqi.top/tags/github-pages/index.xml" rel="self" type="application/rss+xml"/><item><title>Stack 主题个性化定制实录</title><link>https://notion.dongxiaoqi.top/p/stack-%E4%B8%BB%E9%A2%98%E4%B8%AA%E6%80%A7%E5%8C%96%E5%AE%9A%E5%88%B6%E5%AE%9E%E5%BD%95/</link><pubDate>Thu, 13 Aug 2026 11:12:00 +0800</pubDate><guid>https://notion.dongxiaoqi.top/p/stack-%E4%B8%BB%E9%A2%98%E4%B8%AA%E6%80%A7%E5%8C%96%E5%AE%9A%E5%88%B6%E5%AE%9E%E5%BD%95/</guid><description>&lt;h2 id="一背景"&gt;一、背景
&lt;/h2&gt;&lt;p&gt;Stack 主题切换上线后（见《博客主题从 MemE 切换到 Stack 实录》），博客外观与基础链路就绪。此后围绕头像、导航、视觉细节、字体、评论与社交做了一系列个性化定制，本文记录这些改动及其背后的取舍与踩坑。整个过程延续「无本地 hugo、直接靠 CI 验证」的工作方式，每个改动都是一次 push → 触发构建 → curl 线上确认的闭环。&lt;/p&gt;
&lt;h2 id="二改动清单"&gt;二、改动清单
&lt;/h2&gt;&lt;h3 id="1-博客头像"&gt;1. 博客头像
&lt;/h3&gt;&lt;p&gt;用户提供了一张《猫和老鼠》指挥家横图（1102×689）。Stack 侧边栏头像经 helper/image.html 的 .Resources.Get 解析，而 .site-logo 的 CSS 没有 object-fit（默认 fill 会拉伸），直接用横图会被拉变形。&lt;/p&gt;
&lt;p&gt;处理：用 Pillow 把原图中心裁成正方形 689×689，存 assets/img/avatar.jpeg，config 里 [params.sidebar] avatar = &amp;quot;img/avatar.jpeg&amp;quot;，原图备份为 avatar-source.jpeg。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;PIL&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Image&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;img&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Image&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;avatar-source.jpeg&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;crop&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;avatar.jpeg&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;关键点：头像必须在 assets/ 下（Stack 用 Hugo Resources 解析，不是 static/），且文件扩展名要与实际文件一致，否则 .Resources.Get 匹配不到。&lt;/p&gt;
&lt;h3 id="2-分类菜单-404-修复"&gt;2. 分类菜单 404 修复
&lt;/h3&gt;&lt;p&gt;切换后点侧边栏「技术 / 随笔 / 关于」全跳 404。排查发现菜单 url 配的是 /categories/tech/（categoryMap 的小写英文 key），但 Notion Action 把文章的 Notion Category（中文 select 名「技术/随笔/关于」）原样写进 front matter 的 categories: 字段——categoryMap 只决定 content/zh 下的子目录名，不影响 front matter。Hugo 按 front matter 的 categories 生成分类页，实际路径是中文 /categories/技术/，与菜单对不上。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 实测验证&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;curl /categories/tech/ -&amp;gt; &lt;span class="m"&gt;404&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;curl /categories/技术/ -&amp;gt; &lt;span class="m"&gt;200&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;修复：把菜单三个 url 改成 Hugo 实际生成的中文路径 /categories/技术/、/categories/随笔/、/categories/关于/。随笔暂无文章，/categories/随笔/ 仍 404，等有文章后自动出现，保留菜单项占位。&lt;/p&gt;
&lt;p&gt;教训：Notion→Hugo 链路里，分类页 URL 由 front matter 的 categories 决定，不由文件目录决定；改菜单前先 curl 确认 Hugo 实际生成的路径。&lt;/p&gt;
&lt;h3 id="3-页脚跳动的心"&gt;3. 页脚跳动的心
&lt;/h3&gt;&lt;p&gt;参考 guanqr.com，在版权行末尾加一颗 Font Awesome 实心心形，用 fa-heartbeat 双跳动画（1.3s 循环）。通过覆盖主题 partial 实现，不动 submodule：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;layouts/_partials/footer/footer.html：版权行追加 &lt;svg class="heart-icon"&gt;（FA 心形路径）&lt;/li&gt;
&lt;li&gt;layouts/_partials/footer/custom.html：注入心跳 @keyframes CSS（主题留空的扩展点）&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="k"&gt;keyframes&lt;/span&gt; &lt;span class="nt"&gt;heartbeat&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;0&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;14&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;1.3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;28&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;42&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;1.3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;70&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;100&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;细节：心形红色 #ff4d4f，1em 尺寸随字号缩放，vertical-align 对齐基线；加 @media (prefers-reduced-motion: reduce) 守卫，系统开了「减少动态效果」时停止动画（无障碍）。&lt;/p&gt;
&lt;h3 id="4-字体中文霞鹜文楷--代码-jetbrains-mono"&gt;4. 字体：中文霞鹜文楷 + 代码 JetBrains Mono
&lt;/h3&gt;&lt;p&gt;目标是中文用霞鹜文楷、代码用 JetBrains Mono。采用混合方案：JetBrains Mono 走 Google Fonts CDN，霞鹜文楷只设 font-family 名走系统回退——用户本地装了才显示，省去几 MB webfont 的网络开销。&lt;/p&gt;
&lt;p&gt;Stack 主题的字体由三个 CSS 变量控制（在 variables.scss）：--base-font-family（界面）、--article-font-family（正文，继承 base）、--code-font-family（代码）。覆盖方式：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;layouts/_partials/head/custom-font.html：把加载的 Google Fonts 从 Lato 换成 JetBrains Mono&lt;/li&gt;
&lt;li&gt;assets/scss/custom.scss：重定义三个 CSS 变量&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nd"&gt;root&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;--base-font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;LXGW WenKai Screen&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;LXGW WenKai&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;霞鹜文楷&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;apple-system&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;PingFang SC&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Microsoft YaHei&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;sans-serif&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;--article-font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;font&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;family&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;--code-font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;JetBrains Mono&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;LXGW WenKai Mono&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Menlo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Monaco&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Consolas&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;monospace&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;生效原理：style.scss 里 @import &amp;quot;custom.scss&amp;quot; 在 variables.scss 之后，我的 :root 重定义排在主题默认值之后，CSS 变量后者覆盖前者。霞鹜文楷回退链：LXGW WenKai Screen → LXGW WenKai → 霞鹜文楷 → 系统无衬线，未装则回退 PingFang SC / 微软雅黑。&lt;/p&gt;
&lt;p&gt;踩坑：custom.scss 是静态资源，不经过 Hugo 模板引擎，只能用 CSS 注释，不能写 {{}}（否则 SCSS 编译报错）。&lt;/p&gt;
&lt;h3 id="5-评论系统-giscus--社交链接"&gt;5. 评论系统 Giscus + 社交链接
&lt;/h3&gt;&lt;p&gt;评论选 Giscus（基于 GitHub Discussions，与 GitHub Pages 技术栈契合，免费无广告）。社交在原有 GitHub + RSS 基础上加 CSDN 和 Email。&lt;/p&gt;
&lt;p&gt;Giscus 需要 repo-id 和 category-id。这两个不必走 giscus.app 配置页，直接用 GitHub API 取：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 启用 Discussions（REST PATCH）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;curl -X PATCH -H &lt;span class="s2"&gt;&amp;#34;Authorization: token &lt;/span&gt;&lt;span class="nv"&gt;$TOKEN&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; https://api.github.com/repos/vamViolet/notion-hugo-meme &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -d &lt;span class="s1"&gt;&amp;#39;{&amp;#34;has_discussions&amp;#34;: true}&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 取 repo-id 和 category-id（GraphQL）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# query: repository(owner,name){ id, discussionCategories(first:20){ nodes{ id name slug } } }&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;拿到 repo-id R_kgDOTllGGw、Announcements 分类 id DIC_kwDOTllGG84DDR7I，写入 config [params.comments.giscus]。mapping=title 按标题关联 discussion，文章 URL 变了也不丢评论；lightTheme/darkTheme 跟随博客明暗主题。&lt;/p&gt;
&lt;p&gt;关键点：Stack 单篇文章的 comments front matter 字段会覆盖全局 [params.comments.enabled]。所以光开全局不够，还要把 archetype 和现有文章的 comments: false 全改成 true（9 篇批量 sed）。&lt;/p&gt;
&lt;p&gt;社交：Stack 侧边栏图标经 helper/icon.html 的 resources.GetMatch &amp;quot;icons/&lt;name&gt;.svg&amp;quot; 解析，主题内置图标没有 email/csdn，于是自己画了 assets/icons/email.svg（Tabler mail 风格）和 assets/icons/csdn.svg，在 [menu.social] 引用。&lt;/p&gt;
&lt;h2 id="三踩坑记录"&gt;三、踩坑记录
&lt;/h2&gt;&lt;h3 id="坑-1docker-action-生成文件的权限"&gt;坑 1：Docker Action 生成文件的权限
&lt;/h3&gt;&lt;p&gt;某次同步新文章，fix-tags 步骤报 PermissionError: [Errno 13] Permission denied。根因：rxrw/notion-blog 是 Docker action，在容器内以 root 生成 content/zh、static/images 文件，归 root 所有；后续 fix-tags / fix-dates 以 runner 用户运行，写或删这些文件就失败。这个潜在 bug 只有在需要改新文件时才暴露——只读的步骤会蒙混过去，所以前面几次构建一直没发现。&lt;/p&gt;
&lt;p&gt;修复：在 notion-blog 步骤之后、cleanup 之前加 chmod -R a+rwX content/zh static/images，一次性放开权限。&lt;/p&gt;
&lt;h3 id="坑-2notion-created_time-不可控迁移文章日期全变成今天"&gt;坑 2：Notion created_time 不可控，迁移文章日期全变成今天
&lt;/h3&gt;&lt;p&gt;迁移 9 篇 Gridea 老文章时，Notion Action 用页面 created_time 作为文章 date。但 created_time 是只读系统字段，API 创建时自动设为 now，无法覆盖。结果 2021/2023 的老文章同步后全变成今天的日期，堆在归档页顶部当「最新」。&lt;/p&gt;
&lt;p&gt;解法：加自愈 workflow 步骤——scripts/migrated-dates.json（title→原日期映射）+ scripts/fix-migrated-dates.py，每次 sync 在 fix-tags 之后、commit 之前重写匹配文章的 date/lastmod 回原日期。幂等，每次同步都跑，文件已在正确日期则不动。&lt;/p&gt;
&lt;h3 id="坑-3notion-链接必须是绝对-url"&gt;坑 3：Notion 链接必须是绝对 URL
&lt;/h3&gt;&lt;p&gt;创建 Notion 页面时，两篇文章 block append 报 Invalid URL for link。排查是源 HTML 里有相对锚点（#fn1 脚注、%E7%9B%AE%E5%BD%95 编码的「目录」TOC 链接）。Notion 的 link 字段只接受绝对 http(s) URL。修复：在转换器 text_seg 里加 valid_url 校验，非法链接保留文字、丢弃 link，避免阻断整批 block 写入。&lt;/p&gt;
&lt;h3 id="坑-4mybatisplus-图片-404"&gt;坑 4：mybatisplus 图片 404
&lt;/h3&gt;&lt;p&gt;2 张 mybatisplus 图片原图在 vamViolet.github.io/post-images/，Action 的 getImage 把文件存到 static/images/post-images/ 子目录时 os.Create 失败（子目录不存在），回退写出裸路径 /post-images/X.png 导致 404。解法：Hugo 把 static/ 全部映射到站点根，直接把图放到 static/post-images/X.png 即可让 /post-images/X.png 解析。文章 Status=Published 不会再被 Action 覆盖，此补丁持久。&lt;/p&gt;
&lt;h2 id="四验证方法"&gt;四、验证方法
&lt;/h2&gt;&lt;p&gt;全程无本地 hugo，靠 CI 验证：改完 push → workflow_dispatch 触发 → 轮询 run 状态 → 成功后 curl 线上页面抓 HTML/CSS 确认元素和变量生效。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 触发构建（用 git credential 里的 token，无需 gh CLI）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;TOKEN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;protocol=https\nhost=github.com\n\n&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; git credential fill &lt;span class="p"&gt;|&lt;/span&gt; sed -n &lt;span class="s2"&gt;&amp;#34;s/^password=//p&amp;#34;&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;curl -X POST -H &lt;span class="s2"&gt;&amp;#34;Authorization: token &lt;/span&gt;&lt;span class="nv"&gt;$TOKEN&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; https://api.github.com/repos/vamViolet/notion-hugo-meme/actions/workflows/notion-blog.yml/dispatches &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -d &lt;span class="s1"&gt;&amp;#39;{&amp;#34;ref&amp;#34;:&amp;#34;master&amp;#34;}&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 验证字体变量在编译后 CSS 里（minify 后有两个 :root 定义，后者覆盖前者）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;curl https://notion.dongxiaoqi.top/scss/style.min.&amp;lt;hash&amp;gt;.css &lt;span class="p"&gt;|&lt;/span&gt; grep -o &lt;span class="s1"&gt;&amp;#39;JetBrains Mono&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="五最终效果"&gt;五、最终效果
&lt;/h2&gt;&lt;p&gt;线上 &lt;a class="link" href="https://notion.dongxiaoqi.top/" target="_blank" rel="noopener"
 &gt;https://notion.dongxiaoqi.top/&lt;/a&gt; 已确认：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;侧边栏头像（Tom &amp;amp; Jerry 指挥家，正方形裁剪不拉伸）&lt;/li&gt;
&lt;li&gt;技术 / 关于 菜单可正常打开（中文分类页），随笔待文章&lt;/li&gt;
&lt;li&gt;页脚版权行末尾跳动的心（红色，1.3s 双跳）&lt;/li&gt;
&lt;li&gt;中文霞鹜文楷（系统装了才显示）、代码 JetBrains Mono&lt;/li&gt;
&lt;li&gt;文章页 Giscus 评论框（参数齐全，待装 App）、侧边栏 CSDN / Email / GitHub / RSS 四图标&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="六遗留事项"&gt;六、遗留事项
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;Giscus App 待手动安装：https://github.com/apps/giscus → Install → 授权 notion-hugo-meme 仓库，否则评论框报错&lt;/li&gt;
&lt;li&gt;Notion token 在对话历史明文出现过，建议轮换并更新 GitHub NOTION_TOKEN secret&lt;/li&gt;
&lt;li&gt;随笔分类待补文章，/categories/随笔/ 目前 404&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>notion-hugo-meme 操作手册</title><link>https://notion.dongxiaoqi.top/p/notion-hugo-meme-%E6%93%8D%E4%BD%9C%E6%89%8B%E5%86%8C/</link><pubDate>Wed, 29 Jul 2026 03:05:00 +0800</pubDate><guid>https://notion.dongxiaoqi.top/p/notion-hugo-meme-%E6%93%8D%E4%BD%9C%E6%89%8B%E5%86%8C/</guid><description>&lt;h1 id="notion-hugo-meme-操作手册"&gt;notion-hugo-meme 操作手册
&lt;/h1&gt;&lt;p&gt;本项目把 Notion 数据库作为内容源，通过 GitHub Actions 自动同步为 Markdown，再用 Hugo 构建成静态博客并部署到 GitHub Pages。本文档梳理项目结构，并给出从「写文章」到「上线/下线」的完整操作流程。&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;仓库地址：https://github.com/vamViolet/notion-hugo-meme 博客地址：https://notion.dongxiaoqi.top/&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;h2 id="一整体架构"&gt;一、整体架构
&lt;/h2&gt;&lt;p&gt;数据流是单向的、全自动的（每 2 小时触发一次，也可手动触发）：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Notion 数据库 ──(rxrw/notion-blog Action)──&amp;gt; content/zh/*.md ──(Hugo build)──&amp;gt; GitHub Pages
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │ │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └─ 把 Status=Finished 的文章拉成 md └─ https://notion.dongxiaoqi.top/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └─ 同步成功后把 Status 改成 Published
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └─ 清理步骤：删除已下线文章的 md
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;三个关键角色：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Notion 数据库&lt;/strong&gt;：唯一的内容编辑入口。每篇文章是一条记录，&lt;code&gt;Status&lt;/code&gt; 控制是否上线。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GitHub 仓库&lt;/strong&gt;：存放 Hugo 站点源码、同步出来的 md、以及自动化工作流。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GitHub Pages&lt;/strong&gt;：托管构建产物，对外提供博客访问。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="二项目结构"&gt;二、项目结构
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;notion-hugo-meme/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├── .github/workflows/notion-blog.yml # 核心：同步 + 清理 + 构建 + 部署 的工作流
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├── config.toml # Hugo 站点配置（站名、域名、主题、菜单等）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├── notionblog.config.json # notion-blog Action 的配置（数据库 ID、字段映射、过滤规则）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├── archetypes/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ├── default.md # `hugo new` 默认模板
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ └── notion.md # Notion 同步时套用的 front matter 模板
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├── content/zh/ # 同步出来的文章 md（按 Category 分子目录）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ └── 建筑服务能力开发.md
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├── static/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ ├── CNAME # 自定义域名（notion.dongxiaoqi.top）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;│ └── images/ # 文章图片（Action 自动下载到这里）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├── themes/meme/ # MemE 主题（git submodule，指向 rxrw/hugo-theme-meme）
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├── resources/ # Hugo 构建缓存
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;└── README.md
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="关键配置文件"&gt;关键配置文件
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;notionblog.config.json&lt;/code&gt;&lt;/strong&gt; —— 决定 Action 怎么从 Notion 拉文章：&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;字段&lt;/th&gt;
					&lt;th&gt;含义&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;filterProp&lt;/code&gt; / &lt;code&gt;filterValue&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;只同步 &lt;code&gt;Status&lt;/code&gt; 为 &lt;code&gt;Finished&lt;/code&gt; 的文章&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;publishedValue&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;同步成功后把 Status 改成 &lt;code&gt;Published&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;propertyCategories&lt;/code&gt; / &lt;code&gt;categoryMap&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;Category&lt;/code&gt; 字段映射：技术→tech、随笔→essay、关于→about，首页→根目录&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;contentFolder&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;同步到的目录：&lt;code&gt;content/zh&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;imagesFolder&lt;/code&gt; / &lt;code&gt;imagesLink&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;图片下载到 &lt;code&gt;static/images/&lt;/code&gt;，链接前缀 &lt;code&gt;/images&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;config.toml&lt;/code&gt;&lt;/strong&gt; —— Hugo 站点配置要点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;baseURL = &amp;quot;https://notion.dongxiaoqi.top/&amp;quot;&lt;/code&gt;：自定义域名，构建时不能用 github.io URL 覆盖，否则内链全 404。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;title = &amp;quot;dongxiaoqi's Blog&amp;quot;&lt;/code&gt;：站点名。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;theme = &amp;quot;meme&amp;quot;&lt;/code&gt;：使用 MemE 主题（submodule，v5.0.0，2022 年版）。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;.github/workflows/notion-blog.yml&lt;/code&gt;&lt;/strong&gt; —— 两个 Job：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;auto-sync-from-notion-to-github&lt;/code&gt;：checkout → 跑 notion-blog Action 拉文章 → 清理已下线文章 → 提交推送。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;build-and-deploy&lt;/code&gt;：拉最新提交 → Hugo 0.112.7 extended 构建 → 部署到 GitHub Pages。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="三notion-数据库字段"&gt;三、Notion 数据库字段
&lt;/h2&gt;&lt;p&gt;每篇文章（一条记录）需要这些属性：&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;属性&lt;/th&gt;
					&lt;th&gt;类型&lt;/th&gt;
					&lt;th&gt;作用&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;Status&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;状态（status）&lt;/td&gt;
					&lt;td&gt;控制上线：&lt;code&gt;Finished&lt;/code&gt;/&lt;code&gt;Published&lt;/code&gt; = 在线，其余 = 下线&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;Category&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;单选（select）&lt;/td&gt;
					&lt;td&gt;分类目录：&lt;code&gt;首页&lt;/code&gt;/&lt;code&gt;技术&lt;/code&gt;/&lt;code&gt;随笔&lt;/code&gt;/&lt;code&gt;关于&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;Tags&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;多选（multi_select）&lt;/td&gt;
					&lt;td&gt;标签&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;Created by&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;创建者（created_by）&lt;/td&gt;
					&lt;td&gt;Action 读取作者名（硬编码依赖，缺了会报错）&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="status-状态机"&gt;Status 状态机
&lt;/h3&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Status&lt;/th&gt;
					&lt;th&gt;含义&lt;/th&gt;
					&lt;th&gt;博客上是否可见&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;In progress&lt;/code&gt;（进行中）&lt;/td&gt;
					&lt;td&gt;写到一半&lt;/td&gt;
					&lt;td&gt;否&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;Finished&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;写完待发布 → 下次同步会拉取并上线&lt;/td&gt;
					&lt;td&gt;是（同步后）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;Published&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;已上线（同步后 Action 自动置为此状态）&lt;/td&gt;
					&lt;td&gt;是&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;Offline&lt;/code&gt;（已下线）&lt;/td&gt;
					&lt;td&gt;主动下线 → 清理步骤会删掉对应 md&lt;/td&gt;
					&lt;td&gt;否&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;

 &lt;blockquote&gt;
 &lt;p&gt;注意：博客是纯静态站点，没有登录鉴权，所以「私密」等价于「下线」——只要 Status 不是 Finished/Published，文章就不会出现在博客上。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;h2 id="四日常操作"&gt;四、日常操作
&lt;/h2&gt;&lt;h3 id="41-发布一篇新文章"&gt;4.1 发布一篇新文章
&lt;/h3&gt;&lt;ol&gt;
&lt;li&gt;在 Notion 数据库里 &lt;strong&gt;New&lt;/strong&gt; 一条记录，填好 &lt;code&gt;Name&lt;/code&gt;（标题）、&lt;code&gt;Category&lt;/code&gt;、&lt;code&gt;Tags&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;在正文里写内容（支持 Markdown 风格、代码块、表格、图片）。&lt;/li&gt;
&lt;li&gt;把 &lt;code&gt;Status&lt;/code&gt; 设为 &lt;strong&gt;&lt;code&gt;Finished&lt;/code&gt;&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;等待下次 workflow 触发（最多 2 小时），或去 GitHub 仓库 Actions 页面手动 &lt;code&gt;Run workflow&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;同步成功后，文章出现在博客，Status 自动变成 &lt;code&gt;Published&lt;/code&gt;。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="42-修改已发布文章"&gt;4.2 修改已发布文章
&lt;/h3&gt;&lt;p&gt;直接在 Notion 改正文/标题/分类，保持 &lt;code&gt;Status&lt;/code&gt; 为 &lt;code&gt;Finished&lt;/code&gt; 或 &lt;code&gt;Published&lt;/code&gt;，下次同步会更新对应 md。&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;想立即触发同步，又不想等 2 小时：GitHub 仓库 → Actions → &lt;code&gt;notion-blog&lt;/code&gt; → &lt;code&gt;Run workflow&lt;/code&gt;。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;h3 id="43-下线一篇文章"&gt;4.3 下线一篇文章
&lt;/h3&gt;&lt;p&gt;把 &lt;code&gt;Status&lt;/code&gt; 从 &lt;code&gt;Finished&lt;/code&gt;/&lt;code&gt;Published&lt;/code&gt; 改成 &lt;strong&gt;&lt;code&gt;Offline&lt;/code&gt;&lt;/strong&gt;（或 &lt;code&gt;Todo&lt;/code&gt;/&lt;code&gt;In progress&lt;/code&gt;）即可。下次 run 的清理步骤会自动 &lt;code&gt;git rm&lt;/code&gt; 掉对应 md，文章从博客消失。&lt;/p&gt;
&lt;h3 id="44-改分类--改标题"&gt;4.4 改分类 / 改标题
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;改分类&lt;/strong&gt;：在 Notion 改 &lt;code&gt;Category&lt;/code&gt;。注意：旧分类目录下的旧 md 不会自动删除，需手动清理或等清理步骤处理（清理是按「当前 Notion 里 Finished/Published 的文章」对账的）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;改标题&lt;/strong&gt;：会生成新文件名的 md，旧文件名的 md 会成为孤儿，下次清理步骤会自动删除。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="五首次部署--排错清单"&gt;五、首次部署 / 排错清单
&lt;/h2&gt;&lt;p&gt;如果同步或部署出问题，按这个顺序排查：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Notion 数据库是否关联了 Integration&lt;/strong&gt;：数据库右上角 &lt;code&gt;...&lt;/code&gt; → &lt;code&gt;Connections&lt;/code&gt; → 添加你创建的 Integration。没关联会 404。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GitHub Secret 是否正确&lt;/strong&gt;：仓库 Settings → Secrets and variables → Actions，需有 &lt;code&gt;NOTION_TOKEN&lt;/code&gt;（值是 Notion Integration token，&lt;code&gt;ntn_&lt;/code&gt; 开头）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Notion 字段是否齐全&lt;/strong&gt;：&lt;code&gt;Name&lt;/code&gt;/&lt;code&gt;Status&lt;/code&gt;/&lt;code&gt;Category&lt;/code&gt;/&lt;code&gt;Created by&lt;/code&gt; 必须存在且类型正确，缺了 Action 会报错（但 Action 会吞掉错误、显示成功，要看 Actions 日志才能发现）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GitHub Pages 源是否设为 Actions&lt;/strong&gt;：仓库 Settings → Pages → Source 选 &lt;code&gt;GitHub Actions&lt;/code&gt;（不是 gh-pages 分支）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;域名/CNAME&lt;/strong&gt;：&lt;code&gt;static/CNAME&lt;/code&gt; 必须是裸域名 &lt;code&gt;notion.dongxiaoqi.top&lt;/code&gt;，不能带 &lt;code&gt;http://&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Hugo 版本&lt;/strong&gt;：工作流固定用 &lt;code&gt;0.112.7 extended&lt;/code&gt;。MemE v5.0.0 与新版 Hugo 的 &lt;code&gt;resources.ToCSS&lt;/code&gt; 不兼容，&lt;strong&gt;不要升到 latest&lt;/strong&gt;，除非先升主题 submodule。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="六已知限制"&gt;六、已知限制
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Action 只增不删&lt;/strong&gt;：rxrw/notion-blog 只会新增/更新 md，不会删除。下线靠本仓库自加的清理步骤实现。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;正文只取前 100 个 block&lt;/strong&gt;：Action 不做 block 分页，超长文章（&amp;gt;100 个 Notion block）会被截断。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;错误被吞&lt;/strong&gt;：Action 内部出错只 &lt;code&gt;log.Println&lt;/code&gt; 后 &lt;code&gt;exit 0&lt;/code&gt;，永远显示「成功」。排查要看 Actions 的完整日志。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;属性名硬编码&lt;/strong&gt;：Action 代码里写死了 &lt;code&gt;Name&lt;/code&gt;/&lt;code&gt;Category&lt;/code&gt;/&lt;code&gt;Created by&lt;/code&gt; 等英文字段名，改不了。&lt;/li&gt;
&lt;li&gt;**Tags 渲染缺陷：**rxrw/notion-blog 用 &lt;strong&gt;tags : {{.Tags}}&lt;/strong&gt; 渲染多选标签，Go 切片默认输出 &lt;strong&gt;[a b c]&lt;/strong&gt;（空格分隔无逗号），Hugo 会当成一个名为 “a b c” 的畸形标签。本仓库工作流加了 Fix tags front-matter format 步骤，同步后自动改成逗号分隔 &lt;strong&gt;[a, b, c]&lt;/strong&gt;，博客 /tags/ 页和文章页才能正确显示多个独立标签。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tag 命名约束：&lt;strong&gt;Notion 的 tag 名&lt;/strong&gt;不要含空格&lt;/strong&gt;（如用 GitHub-Pages 而非 GitHub Pages）。Action 输出端是空格分隔，含空格的标签名无法无损还原，会被错误拆成多个。中文标签不受影响（如 生产力）。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="七相关链接"&gt;七、相关链接
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;仓库：https://github.com/vamViolet/notion-hugo-meme&lt;/li&gt;
&lt;li&gt;博客：https://notion.dongxiaoqi.top/&lt;/li&gt;
&lt;li&gt;主题：https://github.com/rxrw/hugo-theme-meme&lt;/li&gt;
&lt;li&gt;Action：https://github.com/rxrw/notion-blog&lt;/li&gt;
&lt;/ul&gt;</description></item></channel></rss>