<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>紜清的个人笔记</title><description>个人随笔与技术分享</description><link>https://www.kukie.cn/</link><language>zh_CN</language><item><title>Ciallo～ (∠・ω&lt; )⌒★</title><link>https://www.kukie.cn/posts/pin/</link><guid isPermaLink="true">https://www.kukie.cn/posts/pin/</guid><description>下载保存背景图，顺便加下群吧。</description><pubDate>Sat, 24 May 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;群组&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://t.me/nmervb&quot;&gt;Telegram&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://qun.qq.com/universal-share/share?ac=1&amp;amp;authKey=w6XoulXva7BC2KoO6wvAstjaHD53gcNUta/MAluMhpy%2Bj9pUFr0s7dGelQZV19kq&amp;amp;busi_data=eyJncm91cENvZGUiOiI5NDY2MTA4MzgiLCJ0b2tlbiI6IkticXhVZnNmaDluVWpBbzBtWUtXaFF6MXdTUEJNNDlIMDU0SlZ6L1RNK2VEZnpiaHMzZ0p2Q3ArVUk5U1MyNFUiLCJ1aW4iOiIxODMwOTk4Mjc0In0=&amp;amp;data=_FNMG1eaNxlO5xk24LG6rpzfg_fYJ11wgwTBwwCzq-V5J_8sWUPZTHaASLn3RTuwyXTRwWddLiEYiJn4eafYiQ&amp;amp;svctype=4&amp;amp;tempid=h5_group_info&quot;&gt;QQ群&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://discord.gg/fk3a6FJMu&quot;&gt;Discord&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;其他&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;mailto:xik@xn--gmz590d.cn&quot;&gt;邮箱&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>告别手动调 API：我写了一个 Cloudflare Tunnel 可视化管理面板</title><link>https://www.kukie.cn/posts/tunnels/</link><guid isPermaLink="true">https://www.kukie.cn/posts/tunnels/</guid><description>通过可视化面板管理 Cloudflare Tunnel，自动完成域名绑定、Ingress 配置与 SaaS 接入。</description><pubDate>Sat, 11 Jul 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;前言&lt;/h2&gt;
&lt;p&gt;去年折腾 Cloudflare Tunnel 的时候，我自己照着网上的方案给网站搭了一套 Tunnel + SaaS Custom Hostname + 优选 CNAME 的方案。&lt;/p&gt;
&lt;p&gt;对于个人站点而言，这是我用过最省心的一套组合。&lt;/p&gt;
&lt;p&gt;Tunnel 负责隐藏源站，无需开放公网端口；SaaS 配合优选 CNAME，可以把访问流量引导到更合适的线路上。对只有一台低配 VPS 的个人站长来说，它既省去了配置防火墙和反向代理的麻烦，又能获得不错的访问体验。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;真正麻烦的不是搭建，而是后续的维护。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;每上线一个新站点，我都要在 Cloudflare 控制台 里重复同一套流程：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;打开 Tunnel 页面，修改 Public Hostname；&lt;/li&gt;
&lt;li&gt;打开 DNS 页面，分别创建主域名和辅助域名的解析记录；&lt;/li&gt;
&lt;li&gt;切换到 SSL/TLS，为域名申请 Custom Hostname；&lt;/li&gt;
&lt;li&gt;设置 Fallback Origin；&lt;/li&gt;
&lt;li&gt;最后等待 Cloudflare 同步配置、签发证书。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;第一次配置的时候还挺有意思，但站点一多，这套流程就开始变成重复劳动。&lt;/p&gt;
&lt;p&gt;我第一反应其实是去 GitHub 找现成的。找了一圈，可能是我没找到，也可能确实没人做。&lt;/p&gt;
&lt;p&gt;既然没有，那就自己写一个。&lt;/p&gt;
&lt;p&gt;其实一开始只是打算写给自己用，后来觉得整理一下，也许其他人也能用得上。&lt;/p&gt;
&lt;p&gt;于是就有了 &lt;strong&gt;Cloudflare Tunnel Manager&lt;/strong&gt;。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;📦 Cloudflare Tunnel Manager&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;一个用于管理 Cloudflare Tunnel 的可视化面板。&lt;/p&gt;
&lt;p&gt;它将 Tunnel、DNS、SaaS Custom Hostname 等原本分散在不同页面的配置整合到一起，只需要填写几个参数，就能完成整套绑定流程。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;::github{repo=&quot;qiuyuxc/tunnel-manager&quot;}&lt;/p&gt;
&lt;h2&gt;它解决的不是 Tunnel，而是整套配置流程&lt;/h2&gt;
&lt;p&gt;如果只是把本地服务暴露到公网，Cloudflare Tunnel 的链路其实非常清晰：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;graph LR
    A[本地服务] --&amp;gt; B[cloudflared]
    B --&amp;gt; C[Cloudflare Edge]
    C --&amp;gt; D[访客]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;真正让这套方案变得复杂的，是当你把 SaaS 和优选 CNAME 也纳入进来之后。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;一个请求从用户发起，到最终抵达本地服务，实际上要经过下面这几层配置：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;graph TD
    A[用户访问&amp;lt;br/&amp;gt;blog.example.com]
    --&amp;gt;|优选 CNAME| B[Custom Hostname]

    B --&amp;gt; C[Fallback Origin]

    C --&amp;gt; D[Tunnel]

    D --&amp;gt; E[Ingress]

    E --&amp;gt; F[localhost:3000]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这些配置虽然最终组成了一条完整的访问链路，但却分散在 Cloudflare 控制台的不同页面，由不同的 API 分别负责。这意味着，每新增一个站点，你都需要在不同页面之间来回切换，按照正确的顺序完成这些配置，才能把整条链路连接起来。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Cloudflare Tunnel Manager 做的事情其实很简单，就是把这套分散的配置流程串联起来，并交给程序自动完成。&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;现在绑定一个站点，只需要几步&lt;/h2&gt;
&lt;p&gt;以前绑定一个站点，大概要花五六分钟。&lt;/p&gt;
&lt;p&gt;现在整个流程被压缩成了几个输入框：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;选择 Tunnel&lt;/li&gt;
&lt;li&gt;输入主域名&lt;/li&gt;
&lt;li&gt;输入辅助域名&lt;/li&gt;
&lt;li&gt;输入服务地址&lt;/li&gt;
&lt;li&gt;点击绑定&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;剩下的事情全部交给程序完成。真正需要等待的，只有 Cloudflare 自己同步配置和签发证书的那段时间。&lt;/p&gt;
&lt;p&gt;对于经常新增项目或者维护多个 Tunnel 的人来说，便捷性带来的体验还是很明显的。&lt;/p&gt;
&lt;h2&gt;点击一次绑定，后台到底做了什么？&lt;/h2&gt;
&lt;p&gt;面板里只有一个「绑定」按钮，但后台其实会依次完成下面几件事：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;查询 Zone ID&lt;/strong&gt;：根据主域名和辅助域名，自动查找对应的 Zone ID，支持子域名到根域名的最长匹配；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;更新 Tunnel Ingress&lt;/strong&gt;：将主域名和辅助域名加入路由，并确保 &lt;code&gt;http_status:404&lt;/code&gt; 的兜底规则始终位于末尾；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Upsert DNS 记录&lt;/strong&gt;：对主域名和辅助域名执行先查后写。辅助域名创建 CNAME 指向 &lt;code&gt;{tunnelID}.cfargotunnel.com&lt;/code&gt; 并开启 Cloudflare 代理；主域名创建 CNAME 指向优选地址（如 &lt;code&gt;cf.090227.xyz&lt;/code&gt;），不开启代理；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;设置 Fallback Origin&lt;/strong&gt;：在辅助域名所在 Zone 注册回退源；&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;创建 Custom Hostname&lt;/strong&gt;：在辅助域名所在 Zone 提交主域名作为 Custom Hostname，等待 Cloudflare 自动完成证书签发。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;所以绑定流程并不是简单地连续调几个接口，而是按照正确的顺序，一步一步完成。只有先设置好 Fallback Origin，Custom Hostname 的回源链路才能正确建立；而 DNS 记录的 Upsert 策略（先查询再更新或创建）则避免了重复提交导致的冲突。&lt;/p&gt;
&lt;p&gt;只要 API 返回成功，这条访问链路基本就已经配置完毕。相比手动配置，最大的好处不是节省那几分钟，而是&lt;strong&gt;再也不用担心自己漏掉其中某一步，或者把顺序搞错&lt;/strong&gt;。&lt;/p&gt;
&lt;h2&gt;实现时需要注意的几个细节&lt;/h2&gt;
&lt;p&gt;整个项目的开发其实比预想中顺利不少。在这之前，我已经写过基于 Cloudflare API 的 Go CLI 和 Workers，对 Tunnel、DNS、SaaS 这些接口都比较熟悉。因此，这个 Web 面板更多是在将现有的逻辑拼接起来。&lt;/p&gt;
&lt;p&gt;真正需要注意的，反而是一些很容易被忽略的小细节。&lt;/p&gt;
&lt;h3&gt;Catch-all Rule 不能放错位置&lt;/h3&gt;
&lt;p&gt;Cloudflare Tunnel 的 Ingress 是按照数组顺序匹配的。&lt;/p&gt;
&lt;p&gt;每个 Tunnel 都会有一条 Cloudflare 自动生成的兜底规则：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
    &quot;service&quot;: &quot;http_status:404&quot;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;它始终位于整个 Ingress 的最后。&lt;/p&gt;
&lt;p&gt;很多人第一次修改 Ingress 时，会下意识地把新规则追加到数组末尾。但如果直接追加到数组末尾，新规则就会排在 Catch-all Rule 后面，导致无法按预期匹配。&lt;/p&gt;
&lt;p&gt;因此，更新 Ingress 时必须先把最后一条兜底规则取出来，插入新的 Hostname 规则后，再把它放回数组末尾。&lt;/p&gt;
&lt;p&gt;项目里的处理方式如下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;newRules := []models.IngressRule{
    {
        Hostname: req.MainDomain,
        Service: cfg.ServiceURL,
    },
    {
        Hostname: req.AuxDomain,
        Service: cfg.ServiceURL,
    },
}

ingress := tunnelCfg.Result.Config.Ingress
lastRule := ingress[len(ingress)-1]

ingress = append(
    ingress[:len(ingress)-1],
    newRules...,
)

ingress = append(ingress, lastRule)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;虽然只是几行代码，但它保证了每次新增路由时，都不会破坏已有的匹配顺序。否则，请求可能无法匹配到新增的 Hostname，最终无法正常访问对应服务。&lt;/p&gt;
&lt;h3&gt;Fallback Origin 为什么要先于 Custom Hostname？&lt;/h3&gt;
&lt;p&gt;除了 Ingress，第一次接触 SaaS 时还容易忽略 &lt;strong&gt;Fallback Origin&lt;/strong&gt; 与 &lt;strong&gt;Custom Hostname&lt;/strong&gt; 之间的依赖关系。&lt;/p&gt;
&lt;p&gt;很多人会误以为，只要调用 Custom Hostname 接口把主域名提交给 Cloudflare，就算完成了。但实际上，Cloudflare 必须先知道这个域名最终应该回源到哪里，因此必须先把辅助域名注册为当前 Zone 的 Fallback Origin。&lt;/p&gt;
&lt;p&gt;项目内部严格按照这个顺序处理：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Fallback Origin
        │
        ▼
Custom Hostname
        │
        ▼
等待证书签发
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;先调用 &lt;code&gt;PUT /zones/{zone_id}/custom_hostnames/fallback_origin&lt;/code&gt; 设置回退源，随后再调用 &lt;code&gt;POST /zones/{zone_id}/custom_hostnames&lt;/code&gt; 创建对外访问的 Custom Hostname。&lt;/p&gt;
&lt;p&gt;如果顺序颠倒，Cloudflare 往往无法按预期完成证书申请。所以绑定流程并不是简单地连续调几个接口，而是&lt;strong&gt;按照 Cloudflare 的配置依赖关系，一步一步完成&lt;/strong&gt;。&lt;/p&gt;
&lt;h2&gt;比绑定域名更常用的，其实是在线管理 Tunnel 路由&lt;/h2&gt;
&lt;p&gt;如果让我选整个项目最满意的功能，不是自动绑定，而是在线管理 Tunnel 路由。&lt;/p&gt;
&lt;p&gt;最开始写这个项目时，我只是想把绑定域名这件事自动化掉。&lt;/p&gt;
&lt;p&gt;真正开始使用以后，我才发现，自己最常用的反而不是绑定功能，而是路由管理。&lt;/p&gt;
&lt;p&gt;因为一个 Tunnel 往往会承载多个服务。比如：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Hostname&lt;/th&gt;
&lt;th&gt;Service&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;blog.example.com&lt;/td&gt;
&lt;td&gt;http://localhost:3000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;status.example.com&lt;/td&gt;
&lt;td&gt;http://localhost:3001&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;api.example.com&lt;/td&gt;
&lt;td&gt;http://localhost:8080&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;随着项目增多，经常需要修改端口、删除某个服务，新增一条路由进行测试，以前只能进入 Cloudflare 控制台的 Public Hostname（公共主机名）页面操作，现在可以直接在面板里完成。&lt;/p&gt;
&lt;p&gt;页面会读取当前 Tunnel 的 Ingress 配置，以列表形式展示当前 Tunnel 的所有路由，支持查看、新增、编辑和删除。&lt;/p&gt;
&lt;p&gt;唯一不允许手动修改的是那条 Cloudflare 自动生成的 Catch-all Rule——因为它始终应该留在最后，处理未匹配到任何规则的请求。&lt;/p&gt;
&lt;p&gt;这也是整个项目目前我自己最常使用的功能。很多时候只是改一个端口，或者临时起一个测试服务，不需要再打开 Cloudflare 控制台。&lt;/p&gt;
&lt;h2&gt;除了 Web 面板，也支持 Telegram Bot&lt;/h2&gt;
&lt;p&gt;除了浏览器，这个项目还集成了 Telegram Bot，主要是为了方便远程管理。&lt;/p&gt;
&lt;p&gt;比如服务器放在家里，或者人在外面时，不用登录面板，直接打开 Telegram 就能完成一些常用操作。&lt;/p&gt;
&lt;p&gt;目前支持：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;查看 Tunnel 状态&lt;/li&gt;
&lt;li&gt;查看当前配置&lt;/li&gt;
&lt;li&gt;设置优选 CNAME&lt;/li&gt;
&lt;li&gt;设置回退源&lt;/li&gt;
&lt;li&gt;域名绑定&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果只是偶尔新增一个站点，通过 Bot 直接操作往往比打开浏览器更快。&lt;/p&gt;
&lt;h2&gt;项目结构&lt;/h2&gt;
&lt;p&gt;在技术选型上，我刻意避开了重型方案。&lt;/p&gt;
&lt;p&gt;更希望它能跑在各种低配置 VPS 上，所以整体保持简单：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;┌──────────────┐
│ Vue 3 Frontend │
└──────┬───────┘
       │ HTTP API
┌──────▼───────┐
│ Go Backend   │
└──────┬───────┘
       │
┌──────▼────────────────┐
│ Cloudflare REST API   │
└───────────────────────┘
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;前端使用 Vue 3 + TypeScript + Naive UI + Pinia，负责页面展示和交互。&lt;/p&gt;
&lt;p&gt;后端使用 Go + chi Router，所有配置直接保存在 JSON 文件中，不依赖 MySQL 或 PostgreSQL。&lt;/p&gt;
&lt;p&gt;对于这个场景来说，这种方式已经足够，也降低了部署门槛。&lt;/p&gt;
&lt;h2&gt;针对国内服务器做了一些优化&lt;/h2&gt;
&lt;p&gt;很多使用 Tunnel 的用户，本身就是因为服务器线路一般，或者公网环境不太方便。因此部署时，我也顺手做了一些针对国内环境的优化。&lt;/p&gt;
&lt;h3&gt;镜像源自动切换&lt;/h3&gt;
&lt;p&gt;安装脚本会先检测 &lt;code&gt;ghcr.io&lt;/code&gt; 能否正常访问。如果超时，则自动切换到国内镜像，避免 Docker 拉取镜像速度过慢。&lt;/p&gt;
&lt;h3&gt;自动生成管理员密码&lt;/h3&gt;
&lt;p&gt;第一次启动时，如果没有指定管理员密码，程序会自动生成一个随机密码并输出到日志中，避免部署后直接使用默认密码的风险。&lt;/p&gt;
&lt;h3&gt;一键部署&lt;/h3&gt;
&lt;p&gt;复制以下命令即可一键安装：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;curl -sO https://raw.githubusercontent.com/qiuyuxc/tunnel-manager/main/install.sh &amp;amp;&amp;amp; bash install.sh
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;脚本会自动检查 Docker、创建配置、引导填写 Cloudflare Token、构建镜像并启动容器，整个过程基本不需要手动修改配置文件。&lt;/p&gt;
&lt;h2&gt;API Token 权限&lt;/h2&gt;
&lt;p&gt;这个项目只需要几个最小权限的 Cloudflare API Token 即可运行：&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;Tunnel&lt;/td&gt;
&lt;td&gt;Edit&lt;/td&gt;
&lt;td&gt;修改 Ingress、查询 Tunnel&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DNS&lt;/td&gt;
&lt;td&gt;Edit&lt;/td&gt;
&lt;td&gt;创建 DNS 记录&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Zone&lt;/td&gt;
&lt;td&gt;Read&lt;/td&gt;
&lt;td&gt;获取 Zone ID&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SSL and Certificates&lt;/td&gt;
&lt;td&gt;Edit&lt;/td&gt;
&lt;td&gt;设置 Fallback Origin、创建 Custom Hostname&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;不需要使用全局 API Key，也不需要给账号授予更多权限。如果部署在第三方服务器，这样会更安全一些。&lt;/p&gt;
&lt;h2&gt;写在最后&lt;/h2&gt;
&lt;p&gt;说到底，这个面板并没有创造什么新的能力，只是把原本需要手动完成的操作，交给程序去调用 Cloudflare API 自动完成。&lt;/p&gt;
&lt;p&gt;现在新增一个站点，不需要再反复打开 Tunnel、DNS、SSL/TLS 几个页面来回切换。填写几个参数，点击一次按钮，剩下的事情交给程序完成。&lt;/p&gt;
&lt;p&gt;对于偶尔新增一个站点的人来说，可能只是节省了几分钟。但如果长期维护多个 Tunnel、多套服务，或者经常折腾新项目，这种重复操作很快就会变成一种负担。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;至少以后再新增一个站点的时候，我不用再打开四五个 Cloudflare 页面，把同样的操作再重复一遍了。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;如果你也经常使用 Cloudflare Tunnel，希望这个项目能帮你省下一点时间。如果觉得有用，欢迎到 GitHub 点个 Star，或者一起交流、提出新的想法。&lt;/p&gt;
</content:encoded></item><item><title>免费领取阿里云 ESA 套餐以及实物周边</title><link>https://www.kukie.cn/posts/aiyunaq/</link><guid isPermaLink="true">https://www.kukie.cn/posts/aiyunaq/</guid><description>2026 年阿里云安全专享权益可免费领取两个额外的 ESA 套餐，以及定制台历和帆布包。</description><pubDate>Wed, 28 Jan 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;最近看到阿里云这边有个安全专享权益活动，能免费领一些小东西，顺手记一下。&lt;/p&gt;
&lt;h2&gt;活动参与链接&lt;/h2&gt;
&lt;p&gt;https://yundun.console.aliyun.com/?p=scnew#/overviewNew&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.kukie.cn/assets/image/aliyunaq3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;这次能领到什么&lt;/h2&gt;
&lt;p&gt;这次送的东西主要有：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;两个额外的免费 ESA 套餐&lt;/li&gt;
&lt;li&gt;定制台历&lt;/li&gt;
&lt;li&gt;帆布包&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;对经常折腾阿里云相关服务的人来说，这种活动顺手领一下还是挺香的。&lt;br /&gt;
实物周边倒不一定多值钱，但拿来收藏也还不错。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.kukie.cn/assets/image/aliyunaq1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;领取条件补充&lt;/h2&gt;
&lt;p&gt;这里稍微提一下：&lt;/p&gt;
&lt;p&gt;帆布包的领取需要有 &lt;strong&gt;ECS 实例&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;如果你手头没有现成实例，也可以考虑：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;先去领免费的三个月试用&lt;/li&gt;
&lt;li&gt;或者按量计费开一个实例&lt;/li&gt;
&lt;li&gt;等领取完成后再把实例删除&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这样成本不会太高。&lt;/p&gt;
&lt;h2&gt;领取后怎么看记录&lt;/h2&gt;
&lt;p&gt;领取完成之后，可以点击权益页面右上角的 &lt;strong&gt;领取记录&lt;/strong&gt; 查看当前状态。&lt;/p&gt;
&lt;p&gt;如果后续发货了，一般会收到短信提醒。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.kukie.cn/assets/image/aliyunaq2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;其他说明&lt;/h2&gt;
&lt;p&gt;如果过程中遇到问题，也可以去钉钉群问客服：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;钉钉群号：&lt;code&gt;81920030922&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;至于这篇为什么要专门记一下……&lt;/p&gt;
&lt;p&gt;大概是因为这波活动看着还行，但 &lt;strong&gt;阿里云确实没给广告费&lt;/strong&gt;。&lt;br /&gt;
所以，阿里云打钱，V 我 50。&lt;code&gt;[dog]&lt;/code&gt;&lt;/p&gt;
</content:encoded></item><item><title>Cloudflare Tunnel 的优选实践</title><link>https://www.kukie.cn/posts/tunnel/</link><guid isPermaLink="true">https://www.kukie.cn/posts/tunnel/</guid><description>通过 Cloudflare Tunnel + SaaS 优化 Tunnel 站点访问体验</description><pubDate>Wed, 14 Jan 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;前言&lt;/h2&gt;
&lt;p&gt;Cloudflare Tunnel 的确很好用，尤其适合个人服务和轻量站点。
但它也有一个比较常见的问题：&lt;strong&gt;默认线路在国内访问体验并不理想&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;尤其是在晚高峰时段，延迟升高、丢包、打开慢，都是比较常见的情况。&lt;/p&gt;
&lt;p&gt;这篇文章主要分享一种我自己在用的思路：通过 &lt;strong&gt;Cloudflare Tunnel + SaaS&lt;/strong&gt; 的组合方式，配合社区优选 CNAME，实现对 Tunnel 站点的访问优化。&lt;/p&gt;
&lt;h2&gt;准备阶段&lt;/h2&gt;
&lt;p&gt;在开始之前，需要准备以下内容：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;两个域名（付费或免费均可）&lt;/li&gt;
&lt;li&gt;海外借记卡或 PayPal（用于验证并开通 SaaS）&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;先理解整体思路&lt;/h2&gt;
&lt;p&gt;假设你有两个域名：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;xik.com&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;cf.com&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果你最终想访问的是 &lt;code&gt;*.xik.com&lt;/code&gt;，那么可以使用 &lt;code&gt;cf.com&lt;/code&gt; 作为配置 SaaS 的辅助域名；反过来也一样。&lt;/p&gt;
&lt;p&gt;也就是说，这里需要区分两个角色：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;主域名&lt;/strong&gt;：最终给用户访问的域名&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;辅助域名&lt;/strong&gt;：用于配置 SaaS、自定义主机名以及回退源的域名&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果你只有一个域名，也可以用子域名来代替辅助域名，例如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;主域名：&lt;code&gt;cf.com&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;辅助域名：&lt;code&gt;saas.cf.com&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;理解这两个角色之后，后面的配置就会清楚很多。&lt;/p&gt;
&lt;h2&gt;配置思路概览&lt;/h2&gt;
&lt;p&gt;这套方案的核心逻辑可以简单理解为：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;在 Tunnel 中同时绑定 &lt;strong&gt;主域名&lt;/strong&gt; 和 &lt;strong&gt;辅助域名&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;辅助域名保持走 Cloudflare，作为实际回源所使用的源站域名&lt;/li&gt;
&lt;li&gt;主域名不直接指向 Tunnel 默认目标，而是改为指向 &lt;strong&gt;社区优选 CNAME&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;再通过 Cloudflare SaaS 的自定义主机名功能，把主域名流量正确交给辅助域名处理&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这样做的结果是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;主域名负责“优选访问”&lt;/li&gt;
&lt;li&gt;辅助域名负责“真实回源”&lt;/li&gt;
&lt;li&gt;Tunnel 负责你的内网穿透&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;开始实操&lt;/h2&gt;
&lt;h3&gt;1. 在 Tunnel 中绑定两个域名&lt;/h3&gt;
&lt;p&gt;先在你的 Cloudflare Tunnel 中，为同一个站点绑定两个不同的域名：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;一个主域名&lt;/li&gt;
&lt;li&gt;一个辅助域名&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.kukie.cn/blog/Tunnel1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;这一步的目的，是让同一个 Tunnel 服务同时拥有“用户访问入口”和“回源入口”两个地址。&lt;/p&gt;
&lt;h3&gt;2. 给辅助域名添加一条走 Cloudflare 的解析记录&lt;/h3&gt;
&lt;p&gt;接下来，打开 &lt;strong&gt;辅助域名&lt;/strong&gt; 的 DNS 解析，添加任意一条记录：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A&lt;/li&gt;
&lt;li&gt;AAAA&lt;/li&gt;
&lt;li&gt;CNAME&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;记录值本身不重要，重点是：&lt;strong&gt;必须开启小黄云&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;这条记录的用途，是让辅助域名成为后续 SaaS 配置里的回退源。这一步必须先加，否则后面无法继续添加自定义主机名。&lt;/p&gt;
&lt;p&gt;例如，我这里把子域名指向了 &lt;code&gt;8.8.8.8&lt;/code&gt;。
只要小黄云开启，流量实际仍然会经过 Cloudflare，这样就可以满足后续 SaaS 的回退源要求。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.kukie.cn/blog/Tunnel2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;3. 为辅助域名添加社区优选 CNAME&lt;/h3&gt;
&lt;p&gt;接着，再添加一条指向社区优选的 CNAME 记录。&lt;/p&gt;
&lt;p&gt;常见的优选来源可以从下面这些站点获取：&lt;/p&gt;
&lt;p&gt;https://cf.090227.xyz/&lt;/p&gt;
&lt;p&gt;https://www.byoip.top/&lt;/p&gt;
&lt;p&gt;获取到可用优选后，先把它配置在辅助域名下的某个子域名上。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.kukie.cn/blog/Tunnelp.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;4. 修改主域名解析到优选子域名&lt;/h3&gt;
&lt;p&gt;然后切换到 &lt;strong&gt;主域名&lt;/strong&gt; 的 DNS 页面，找到你在 Tunnel 中绑定的那个子域名解析记录，把它的记录值修改为刚刚配置好的“优选子域名”，并关闭小黄云。&lt;/p&gt;
&lt;p&gt;这里要注意：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;主域名 &lt;strong&gt;不是直接指向优选站点给出的目标&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;而是先指向你在辅助域名下配置好的那个优选子域名&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;例如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;y.cf.com -&amp;gt; cf.090227.xyz&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;那么主域名应该指向 &lt;code&gt;y.cf.com&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;而不是直接写 &lt;code&gt;cf.090227.xyz&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这样做一方面是为了让 Cloudflare 正确识别访问目标，另一方面也更方便后续维护。&lt;/p&gt;
&lt;p&gt;例如当你配置了多个优选时，只要统一通过 &lt;code&gt;y.cf.com&lt;/code&gt; 这一个子域名来处理，后续更换优选域名时，只需要修改 &lt;code&gt;y.cf.com&lt;/code&gt; 的解析记录，而不必直接改动每个主域名的解析。&lt;/p&gt;
&lt;h3&gt;5. 在辅助域名中配置 SaaS 自定义主机&lt;/h3&gt;
&lt;p&gt;完成上面的 DNS 配置后，回到辅助域名对应的 Cloudflare 控制台。&lt;/p&gt;
&lt;p&gt;进入侧边栏中的：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;SSL/TLS → 自定义主机&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;先添加一个 &lt;strong&gt;回源域名&lt;/strong&gt;，也就是你刚刚用于 SaaS 回退源的那个辅助域名子域名。&lt;/p&gt;
&lt;p&gt;然后继续添加 &lt;strong&gt;自定义主机名&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.kukie.cn/blog/Tunnel5.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;这里有两个关键点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;自定义主机名&lt;/strong&gt;：填写你最终要给用户访问的主域名&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;源站&lt;/strong&gt;：填写你在 Tunnel 中绑定的辅助域名（也就是没有改过 Tunnel 指向的那个地址）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;验证方式可以自行选择，这里更推荐使用 HTTP 验证。&lt;/p&gt;
&lt;p&gt;这里以TXT为例&lt;/p&gt;
&lt;p&gt;添加完成后，Cloudflare 会给出一条 TXT 验证记录，把它添加到对应域名的 DNS 中，等待验证生效即可。&lt;/p&gt;
&lt;h2&gt;测试是否生效&lt;/h2&gt;
&lt;p&gt;当全部配置完成并生效后，就可以使用 &lt;code&gt;itdog&lt;/code&gt; 等站点测试工具进行检查。&lt;/p&gt;
&lt;p&gt;重点看两件事：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;是否已经正确命中优选线路&lt;/li&gt;
&lt;li&gt;晚高峰下延迟与丢包是否有改善&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;晚高峰效果对比&lt;/h2&gt;
&lt;h3&gt;未优选&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.kukie.cn/blog/Tunnel3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;优选后&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.kukie.cn/blog/Tunnel4.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;从测试结果来看，优选后的访问体验会明显更稳定一些，尤其是在国内晚高峰场景下，效果会更容易体现出来。&lt;/p&gt;
&lt;h2&gt;总结&lt;/h2&gt;
&lt;p&gt;这套方案的关键点，其实就在于把 Tunnel、优选 CNAME 和 SaaS 自定义主机名三个能力串起来：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Tunnel 负责把服务穿透出来&lt;/li&gt;
&lt;li&gt;优选 CNAME 负责改善入口访问体验&lt;/li&gt;
&lt;li&gt;SaaS 负责承接自定义主机名，并把主域名流量交给辅助域名处理&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;整套配置看起来步骤不少，但真正理解“主域名负责访问、辅助域名负责回源”这个思路后，整体就不会太难。&lt;/p&gt;
&lt;p&gt;如果你本身就在用 Cloudflare Tunnel，又觉得默认线路在国内访问体验一般，那么这套方法还是挺值得折腾一下的。&lt;/p&gt;
</content:encoded></item><item><title>Vercel / Netlify / Cloudflare 站点的优选与分流</title><link>https://www.kukie.cn/posts/777/</link><guid isPermaLink="true">https://www.kukie.cn/posts/777/</guid><description>通过华为云 DNS 线路解析，对 Vercel、Netlify、Cloudflare 等平台进行优选与分流，提升不同运营商环境下的访问体验。</description><pubDate>Fri, 19 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;前言&lt;/h2&gt;
&lt;p&gt;如果你的网站部署在 Vercel、Netlify 或 Cloudflare 等平台上，实际访问体验往往会受到网络环境和运营商线路的影响。&lt;/p&gt;
&lt;p&gt;这篇文章主要介绍一种比较实用的方案：借助 &lt;strong&gt;华为云 DNS 的线路解析功能&lt;/strong&gt;，结合第三方优选域名，对不同平台进行优选与分流。这样可以让不同运营商用户访问到更合适的线路，从而改善站点的访问速度。&lt;/p&gt;
&lt;h2&gt;需要准备的账号&lt;/h2&gt;
&lt;p&gt;在开始之前，需要先准备以下账号：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com&quot;&gt;GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.cloudflare.com&quot;&gt;Cloudflare&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://vercel.com&quot;&gt;Vercel&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.netlify.com&quot;&gt;Netlify&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://auth.huaweicloud.com/authui/login.html?service=https%3A%2F%2Fconsole-intl.huaweicloud.com%2Fdns%2F%3FagencyId%3Df03fc6c78ad640679dce46d3caa233b9%26region%3Dap-southeast-1%26locale%3Dzh-cn%26cloud_route_state%3D%2Fdns%2Fdashboard&amp;amp;locale=zh-cn#/login&quot;&gt;华为云&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;第一步：在华为云添加需要优选的子域名&lt;/h2&gt;
&lt;p&gt;假设你最终要访问的站点是 &lt;code&gt;blog.hwy.com&lt;/code&gt;，那么在华为云 DNS 中添加对应的子域名即可。&lt;/p&gt;
&lt;p&gt;添加完成后，华为云会提供一组 NS 记录。接下来需要前往 Cloudflare，将这组 NS 记录配置进去，把该子域名的解析权交给华为云。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.kukie.cn/blog/7770.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;这样后续针对这个子域名的优选与分流，就可以在华为云里完成。&lt;/p&gt;
&lt;h2&gt;第二步：配置平台域名并进行优选&lt;/h2&gt;
&lt;p&gt;这里以 &lt;strong&gt;Vercel&lt;/strong&gt; 为例说明。&lt;/p&gt;
&lt;p&gt;首先，在 Vercel 中添加你的子域名，例如：&lt;/p&gt;
&lt;p&gt;&lt;code&gt;blog.hwy.com&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;完成添加后，Vercel 会给出默认的解析记录。先按平台要求正常完成解析与生效。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.kukie.cn/blog/7771.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;待域名绑定成功后，就可以把原本平台提供的默认解析目标，替换为社区中常见的第三方优选域名，以进一步改善访问质量。&lt;/p&gt;
&lt;h3&gt;第三方优选域名获取&lt;/h3&gt;
&lt;p&gt;常见的第三方优选域名可以从下面这些站点获取：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;https://cf.090227.xyz/
https://www.byoip.top/
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;拿到优选域名之后，将原解析值替换为对应的优选域名或IP即可。&lt;/p&gt;
&lt;h3&gt;测试优选是否生效&lt;/h3&gt;
&lt;p&gt;替换完成后，可以通过测试工具或实际访问下，验证当前优选域名是否已经生效。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.kukie.cn/blog/7772.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;第三步：按运营商进行分流&lt;/h2&gt;
&lt;p&gt;如果你只使用单个平台，那么完成前面的优选步骤通常就已经够用了。
分流并不是必须项。&lt;/p&gt;
&lt;p&gt;但如果你希望进一步优化不同网络环境下的访问体验，比如让电信、联通、移动分别走不同平台，那么就可以继续往下配置线路分流。&lt;/p&gt;
&lt;h3&gt;配置思路&lt;/h3&gt;
&lt;p&gt;重复前面在 Vercel 上的做法，再为 Netlify、Cloudflare 或其他平台分别完成：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;域名绑定&lt;/li&gt;
&lt;li&gt;解析生效&lt;/li&gt;
&lt;li&gt;SSL 下发&lt;/li&gt;
&lt;li&gt;替换为对应优选域名&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;等这些都准备好之后，就可以在华为云中基于运营商线路添加不同的解析记录。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;注：如果 Netlify 长时间无法完成解析，可以先在华为云中暂停其他优选记录，等待 Netlify 验证成功后再重新启用。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;第四步：配置线路解析&lt;/h2&gt;
&lt;p&gt;假设你已经分别为 Vercel、Netlify、Cloudflare 等平台准备好了对应的优选域名，那么接下来就可以根据不同运营商进行分流。&lt;/p&gt;
&lt;p&gt;例如，以电信线路为例：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.kukie.cn/blog/7773.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;同样的方法，也可以继续为联通、移动等线路分别配置不同的 CNAME 记录。具体选哪一个平台作为哪条线路的目标，可以根据你自己的测试结果和访问体验来决定。&lt;/p&gt;
&lt;h2&gt;解析示例&lt;/h2&gt;
&lt;p&gt;以下只是一个示例，具体请以你自己的实际配置为准：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;记录类型：CNAME ｜ 线路：电信 ｜ 记录值：&lt;code&gt;your.cloudflare.app&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;记录类型：CNAME ｜ 线路：移动 ｜ 记录值：&lt;code&gt;your.vercel.app&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;记录类型：CNAME ｜ 线路：联通 ｜ 记录值：&lt;code&gt;your.netlify.app&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;记录类型：CNAME ｜ 线路：全网默认 ｜ 记录值：&lt;code&gt;your.edgeone.app&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;配置完成后，可以再次进行测试，确认各线路是否已经正确指向正确IP。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.kukie.cn/blog/77711.webp&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;一个有趣的延伸玩法&lt;/h2&gt;
&lt;p&gt;线路分流除了用于优化访问速度，其实还可以拿来做一些更有意思的玩法。&lt;/p&gt;
&lt;p&gt;比如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;电信线路访问部署在 Vercel 上的云盘&lt;/li&gt;
&lt;li&gt;联通线路访问部署在 Netlify 上的博客&lt;/li&gt;
&lt;li&gt;移动线路访问另外一个平台上的站点内容&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;也就是说，不同网络环境下访问同一个域名，看到的内容甚至可以不完全相同。&lt;/p&gt;
&lt;p&gt;当然，这种玩法更偏个性化和实验性质，是否这样使用就看你自己的需求了。&lt;/p&gt;
&lt;h2&gt;总结&lt;/h2&gt;
&lt;p&gt;这套方案的核心思路并不复杂：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;把子域名交给华为云解析&lt;/li&gt;
&lt;li&gt;在不同平台上完成域名绑定&lt;/li&gt;
&lt;li&gt;将默认解析替换为第三方优选域名&lt;/li&gt;
&lt;li&gt;利用华为云的线路解析能力，为不同运营商配置不同的访问目标&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;如果你只是想做基础优选，那么做到第三步通常就已经够用了。
如果你还想进一步折腾，或者希望兼顾不同网络环境下的访问体验，那么再继续做分流会更合适。&lt;/p&gt;
&lt;p&gt;整体来说，这是一套比较适合多平台部署场景的方案。&lt;/p&gt;
</content:encoded></item><item><title>Markdown Tutorial</title><link>https://www.kukie.cn/posts/markdown-tutorial/</link><guid isPermaLink="true">https://www.kukie.cn/posts/markdown-tutorial/</guid><description>A simple example of a Markdown blog post.</description><pubDate>Mon, 20 Jan 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;Markdown Tutorial&lt;/h1&gt;
&lt;p&gt;A markdown example shows how to write a markdown file. This document integrates core syntax and extensions (GMF).&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#block-elements&quot;&gt;Block Elements&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#paragraphs-and-line-breaks&quot;&gt;Paragraphs and Line Breaks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#headers&quot;&gt;Headers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#blockquotes&quot;&gt;Blockquotes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#lists&quot;&gt;Lists&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#code-blocks&quot;&gt;Code Blocks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#horizontal-rules&quot;&gt;Horizontal Rules&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#table&quot;&gt;Table&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#span-elements&quot;&gt;Span Elements&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#links&quot;&gt;Links&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#emphasis&quot;&gt;Emphasis&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#code&quot;&gt;Code&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#images&quot;&gt;Images&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#strikethrough&quot;&gt;Strikethrough&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#miscellaneous&quot;&gt;Miscellaneous&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#automatic-links&quot;&gt;Automatic Links&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#backslash-escapes&quot;&gt;Backslash Escapes&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#inline-html&quot;&gt;Inline HTML&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Block Elements&lt;/h2&gt;
&lt;h3&gt;Paragraphs and Line Breaks&lt;/h3&gt;
&lt;h4&gt;Paragraphs&lt;/h4&gt;
&lt;p&gt;HTML Tag: &lt;code&gt;&amp;lt;p&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;One or more blank lines. (A blank line is a line containing nothing but &lt;strong&gt;spaces&lt;/strong&gt; or &lt;strong&gt;tabs&lt;/strong&gt; is considered blank.)&lt;/p&gt;
&lt;p&gt;Code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;This will be
inline.

This is second paragraph.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;This will be
inline.&lt;/p&gt;
&lt;p&gt;This is second paragraph.&lt;/p&gt;
&lt;hr /&gt;
&lt;h4&gt;Line Breaks&lt;/h4&gt;
&lt;p&gt;HTML Tag: &lt;code&gt;&amp;lt;br /&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;End a line with &lt;strong&gt;two or more spaces&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;This will be not
inline.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;This will be not&lt;br /&gt;
inline.&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;Headers&lt;/h3&gt;
&lt;p&gt;Markdown supports two styles of headers, Setext and atx.&lt;/p&gt;
&lt;h4&gt;Setext&lt;/h4&gt;
&lt;p&gt;HTML Tags: &lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;h2&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&quot;Underlined&quot; using &lt;strong&gt;equal signs (=)&lt;/strong&gt; as &lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt; and &lt;strong&gt;dashes (-)&lt;/strong&gt; as &lt;code&gt;&amp;lt;h2&amp;gt;&lt;/code&gt; in any number.&lt;/p&gt;
&lt;p&gt;Code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;This is an H1
=============
This is an H2
-------------
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;This is an H1&lt;/h1&gt;
&lt;h2&gt;This is an H2&lt;/h2&gt;
&lt;hr /&gt;
&lt;h4&gt;atx&lt;/h4&gt;
&lt;p&gt;HTML Tags: &lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;h2&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;h3&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;h4&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;h5&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;h6&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Uses 1-6 &lt;strong&gt;hash characters (#)&lt;/strong&gt; at the start of the line, corresponding to &lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt; - &lt;code&gt;&amp;lt;h6&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# This is an H1
## This is an H2
###### This is an H6
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;This is an H1&lt;/h1&gt;
&lt;h2&gt;This is an H2&lt;/h2&gt;
&lt;h6&gt;This is an H6&lt;/h6&gt;
&lt;hr /&gt;
&lt;p&gt;Optionally, you may &quot;close&quot; atx-style headers. The closing hashes &lt;strong&gt;don&apos;t need to match&lt;/strong&gt; the number of hashes used to open the header.&lt;/p&gt;
&lt;p&gt;Code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# This is an H1 #
## This is an H2 ##
### This is an H3 ######
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;This is an H1&lt;/h1&gt;
&lt;h2&gt;This is an H2&lt;/h2&gt;
&lt;h3&gt;This is an H3&lt;/h3&gt;
&lt;hr /&gt;
&lt;h3&gt;Blockquotes&lt;/h3&gt;
&lt;p&gt;HTML Tag: &lt;code&gt;&amp;lt;blockquote&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Markdown uses email-style &lt;strong&gt;&amp;gt;&lt;/strong&gt; characters for blockquoting. It looks best if you hard wrap the text and put a &amp;gt; before every line.&lt;/p&gt;
&lt;p&gt;Code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,
&amp;gt; consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.
&amp;gt; Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.
&amp;gt;
&amp;gt; Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse
&amp;gt; id sem consectetuer libero luctus adipiscing.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;hr /&gt;
&lt;blockquote&gt;
&lt;p&gt;This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,
consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.
Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.&lt;/p&gt;
&lt;p&gt;Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse
id sem consectetuer libero luctus adipiscing.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr /&gt;
&lt;p&gt;Markdown allows you to be lazy and only put the &amp;gt; before the first line of a hard-wrapped paragraph.&lt;/p&gt;
&lt;p&gt;Code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,
consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.
Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.

&amp;gt; Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse
id sem consectetuer libero luctus adipiscing.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;hr /&gt;
&lt;blockquote&gt;
&lt;p&gt;This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,
consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.
Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse
id sem consectetuer libero luctus adipiscing.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr /&gt;
&lt;p&gt;Blockquotes can be nested (i.e. a blockquote-in-a-blockquote) by adding additional levels of &amp;gt;.&lt;/p&gt;
&lt;p&gt;Code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; This is the first level of quoting.
&amp;gt;
&amp;gt; &amp;gt; This is nested blockquote.
&amp;gt;
&amp;gt; Back to the first level.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;hr /&gt;
&lt;blockquote&gt;
&lt;p&gt;This is the first level of quoting.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This is nested blockquote.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Back to the first level.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr /&gt;
&lt;p&gt;Blockquotes can contain other Markdown elements, including headers, lists, and code blocks.&lt;/p&gt;
&lt;p&gt;Code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; ## This is a header.
&amp;gt;
&amp;gt; 1.   This is the first list item.
&amp;gt; 2.   This is the second list item.
&amp;gt;
&amp;gt; Here&apos;s some example code:
&amp;gt;
&amp;gt;     return shell_exec(&quot;echo $input | $markdown_script&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;hr /&gt;
&lt;blockquote&gt;
&lt;h2&gt;This is a header.&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;This is the first list item.&lt;/li&gt;
&lt;li&gt;This is the second list item.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Here&apos;s some example code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;return shell_exec(&quot;echo $input | $markdown_script&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;hr /&gt;
&lt;h3&gt;Lists&lt;/h3&gt;
&lt;p&gt;Markdown supports ordered (numbered) and unordered (bulleted) lists.&lt;/p&gt;
&lt;h4&gt;Unordered&lt;/h4&gt;
&lt;p&gt;HTML Tag: &lt;code&gt;&amp;lt;ul&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Unordered lists use &lt;strong&gt;asterisks (*)&lt;/strong&gt;, &lt;strong&gt;pluses (+)&lt;/strong&gt;, and &lt;strong&gt;hyphens (-)&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;*   Red
*   Green
*   Blue
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;hr /&gt;
&lt;ul&gt;
&lt;li&gt;Red&lt;/li&gt;
&lt;li&gt;Green&lt;/li&gt;
&lt;li&gt;Blue&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;p&gt;is equivalent to:&lt;/p&gt;
&lt;p&gt;Code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;+   Red
+   Green
+   Blue
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and:&lt;/p&gt;
&lt;p&gt;Code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-   Red
-   Green
-   Blue
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Ordered&lt;/h4&gt;
&lt;p&gt;HTML Tag: &lt;code&gt;&amp;lt;ol&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Ordered lists use numbers followed by periods:&lt;/p&gt;
&lt;p&gt;Code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;1.  Bird
2.  McHale
3.  Parish
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li&gt;Bird&lt;/li&gt;
&lt;li&gt;McHale&lt;/li&gt;
&lt;li&gt;Parish&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;p&gt;It&apos;s possible to trigger an ordered list by accident, by writing something like this:&lt;/p&gt;
&lt;p&gt;Code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;1986. What a great season.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li&gt;What a great season.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;p&gt;You can &lt;strong&gt;backslash-escape (\)&lt;/strong&gt; the period:&lt;/p&gt;
&lt;p&gt;Code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;1986\. What a great season.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;1986. What a great season.&lt;/p&gt;
&lt;hr /&gt;
&lt;h4&gt;Indented&lt;/h4&gt;
&lt;h5&gt;Blockquote&lt;/h5&gt;
&lt;p&gt;To put a blockquote within a list item, the blockquote&apos;s &amp;gt; delimiters need to be indented:&lt;/p&gt;
&lt;p&gt;Code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;*   A list item with a blockquote:

    &amp;gt; This is a blockquote
    &amp;gt; inside a list item.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;hr /&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;A list item with a blockquote:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This is a blockquote
inside a list item.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h5&gt;Code Block&lt;/h5&gt;
&lt;p&gt;To put a code block within a list item, the code block needs to be indented twice — &lt;strong&gt;8 spaces&lt;/strong&gt; or &lt;strong&gt;two tabs&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;Code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;*   A list item with a code block:

        &amp;lt;code goes here&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;hr /&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;A list item with a code block:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;code goes here&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h5&gt;Nested List&lt;/h5&gt;
&lt;p&gt;Code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;* A
  * A1
  * A2
* B
* C
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;hr /&gt;
&lt;ul&gt;
&lt;li&gt;A
&lt;ul&gt;
&lt;li&gt;A1&lt;/li&gt;
&lt;li&gt;A2&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;B&lt;/li&gt;
&lt;li&gt;C&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h3&gt;Code Blocks&lt;/h3&gt;
&lt;p&gt;HTML Tag: &lt;code&gt;&amp;lt;pre&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Indent every line of the block by at least &lt;strong&gt;4 spaces&lt;/strong&gt; or &lt;strong&gt;1 tab&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;This is a normal paragraph:

    This is a code block.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;This is a normal paragraph:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;This is a code block.
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;p&gt;A code block continues until it reaches a line that is not indented (or the end of the article).&lt;/p&gt;
&lt;p&gt;Within a code block, &lt;strong&gt;&lt;em&gt;ampersands (&amp;amp;)&lt;/em&gt;&lt;/strong&gt; and angle &lt;strong&gt;brackets (&amp;lt; and &amp;gt;)&lt;/strong&gt; are automatically converted into HTML entities.&lt;/p&gt;
&lt;p&gt;Code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    &amp;lt;div class=&quot;footer&quot;&amp;gt;
        &amp;amp;copy; 2004 Foo Corporation
    &amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;hr /&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;div class=&quot;footer&quot;&amp;gt;
    &amp;amp;copy; 2004 Foo Corporation
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;p&gt;Following sections Fenced Code Blocks and Syntax Highlighting are extensions, you can use the other way to write the code block.&lt;/p&gt;
&lt;h4&gt;Fenced Code Blocks&lt;/h4&gt;
&lt;p&gt;Just wrap your code in &lt;code&gt;```&lt;/code&gt; (as shown below) and you won&apos;t need to indent it by four spaces.&lt;/p&gt;
&lt;p&gt;Code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Here&apos;s an example:

```
function test() {
  console.log(&quot;notice the blank line before this function?&quot;);
}
```
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Here&apos;s an example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function test() {
  console.log(&quot;notice the blank line before this function?&quot;);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h4&gt;Syntax Highlighting&lt;/h4&gt;
&lt;p&gt;In your fenced block, add an optional language identifier and we&apos;ll run it through syntax highlighting (&lt;a href=&quot;https://github.com/github/linguist/blob/master/lib/linguist/languages.yml&quot;&gt;Support Languages&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;Code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;```ruby
require &apos;redcarpet&apos;
markdown = Redcarpet.new(&quot;Hello World!&quot;)
puts markdown.to_html
```
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;hr /&gt;
&lt;pre&gt;&lt;code&gt;require &apos;redcarpet&apos;
markdown = Redcarpet.new(&quot;Hello World!&quot;)
puts markdown.to_html
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h3&gt;Horizontal Rules&lt;/h3&gt;
&lt;p&gt;HTML Tag: &lt;code&gt;&amp;lt;hr /&amp;gt;&lt;/code&gt;
Places &lt;strong&gt;three or more hyphens (-), asterisks (*), or underscores (_)&lt;/strong&gt; on a line by themselves. You may use spaces between the hyphens or asterisks.&lt;/p&gt;
&lt;p&gt;Code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;* * *
***
*****
- - -
---------------------------------------
___
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;hr /&gt;
&lt;hr /&gt;
&lt;hr /&gt;
&lt;hr /&gt;
&lt;hr /&gt;
&lt;hr /&gt;
&lt;hr /&gt;
&lt;hr /&gt;
&lt;h3&gt;Table&lt;/h3&gt;
&lt;p&gt;HTML Tag: &lt;code&gt;&amp;lt;table&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;It&apos;s an extension.&lt;/p&gt;
&lt;p&gt;Separates column by &lt;strong&gt;pipe (|)&lt;/strong&gt; and header by &lt;strong&gt;dashes (-)&lt;/strong&gt;, and uses &lt;strong&gt;colon (:)&lt;/strong&gt; for alignment.&lt;/p&gt;
&lt;p&gt;The outer &lt;strong&gt;pipes (|)&lt;/strong&gt; and alignment are optional. There are &lt;strong&gt;3 delimiters&lt;/strong&gt; each cell at least for separating header.&lt;/p&gt;
&lt;p&gt;Code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;| Left | Center | Right |
|:-----|:------:|------:|
|aaa   |bbb     |ccc    |
|ddd   |eee     |fff    |

 A | B
---|---
123|456


A |B
--|--
12|45
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;hr /&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Left&lt;/th&gt;
&lt;th&gt;Center&lt;/th&gt;
&lt;th&gt;Right&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;aaa&lt;/td&gt;
&lt;td&gt;bbb&lt;/td&gt;
&lt;td&gt;ccc&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ddd&lt;/td&gt;
&lt;td&gt;eee&lt;/td&gt;
&lt;td&gt;fff&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;A&lt;/th&gt;
&lt;th&gt;B&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;123&lt;/td&gt;
&lt;td&gt;456&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;A&lt;/th&gt;
&lt;th&gt;B&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;12&lt;/td&gt;
&lt;td&gt;45&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h2&gt;Span Elements&lt;/h2&gt;
&lt;h3&gt;Links&lt;/h3&gt;
&lt;p&gt;HTML Tag: &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Markdown supports two style of links: inline and reference.&lt;/p&gt;
&lt;h4&gt;Inline&lt;/h4&gt;
&lt;p&gt;Inline link format like this: &lt;code&gt;[Link Text](URL &quot;Title&quot;)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Title is optional.&lt;/p&gt;
&lt;p&gt;Code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;This is [an example](http://example.com/ &quot;Title&quot;) inline link.

[This link](http://example.net/) has no title attribute.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;This is &lt;a href=&quot;http://example.com/&quot;&gt;an example&lt;/a&gt; inline link.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://example.net/&quot;&gt;This link&lt;/a&gt; has no title attribute.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;If you&apos;re referring to a local resource on the same server, you can use relative paths:&lt;/p&gt;
&lt;p&gt;Code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;See my [About](/about/) page for details.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;See my &lt;a href=&quot;/about/&quot;&gt;About&lt;/a&gt; page for details.&lt;/p&gt;
&lt;hr /&gt;
&lt;h4&gt;Reference&lt;/h4&gt;
&lt;p&gt;You could predefine link references. Format like this: &lt;code&gt;[id]: URL &quot;Title&quot;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Title is also optional. And the you refer the link, format like this: &lt;code&gt;[Link Text][id]&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[id]: http://example.com/  &quot;Optional Title Here&quot;
This is [an example][id] reference-style link.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;This is &lt;a href=&quot;http://example.com/&quot;&gt;an example&lt;/a&gt; reference-style link.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;That is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Square brackets containing the link identifier (&lt;strong&gt;not case sensitive&lt;/strong&gt;, optionally indented from the left margin using up to three spaces);&lt;/li&gt;
&lt;li&gt;followed by a colon;&lt;/li&gt;
&lt;li&gt;followed by one or more spaces (or tabs);&lt;/li&gt;
&lt;li&gt;followed by the URL for the link;&lt;/li&gt;
&lt;li&gt;The link URL may, optionally, be surrounded by angle brackets.&lt;/li&gt;
&lt;li&gt;optionally followed by a title attribute for the link, enclosed in double or single quotes, or enclosed in parentheses.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The following three link definitions are equivalent:&lt;/p&gt;
&lt;p&gt;Code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[foo]: http://example.com/  &quot;Optional Title Here&quot;
[foo]: http://example.com/  &apos;Optional Title Here&apos;
[foo]: http://example.com/  (Optional Title Here)
[foo]: &amp;lt;http://example.com/&amp;gt;  &quot;Optional Title Here&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Uses an empty set of square brackets, the link text itself is used as the name.&lt;/p&gt;
&lt;p&gt;Code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Google]: http://google.com/
[Google][]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;a href=&quot;http://google.com/&quot;&gt;Google&lt;/a&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;Emphasis&lt;/h3&gt;
&lt;p&gt;HTML Tags: &lt;code&gt;&amp;lt;em&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;strong&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Markdown treats &lt;strong&gt;asterisks (*)&lt;/strong&gt; and &lt;strong&gt;underscores (_)&lt;/strong&gt; as indicators of emphasis. &lt;strong&gt;One delimiter&lt;/strong&gt; will be &lt;code&gt;&amp;lt;em&amp;gt;&lt;/code&gt;; *&lt;em&gt;double delimiters&lt;/em&gt; will be &lt;code&gt;&amp;lt;strong&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;*single asterisks*

_single underscores_

**double asterisks**

__double underscores__
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;em&gt;single asterisks&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;single underscores&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;double asterisks&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;double underscores&lt;/strong&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;But if you surround an * or _ with spaces, it&apos;ll be treated as a literal asterisk or underscore.&lt;/p&gt;
&lt;p&gt;You can backslash escape it:&lt;/p&gt;
&lt;p&gt;Code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;\*this text is surrounded by literal asterisks\*
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;*this text is surrounded by literal asterisks*&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;Code&lt;/h3&gt;
&lt;p&gt;HTML Tag: &lt;code&gt;&amp;lt;code&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Wraps it with &lt;strong&gt;backtick quotes (`)&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Use the `printf()` function.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Use the &lt;code&gt;printf()&lt;/code&gt; function.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;To include a literal backtick character within a code span, you can use &lt;strong&gt;multiple backticks&lt;/strong&gt; as the opening and closing delimiters:&lt;/p&gt;
&lt;p&gt;Code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;``There is a literal backtick (`) here.``
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;code&gt;There is a literal backtick (`) here.&lt;/code&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;The backtick delimiters surrounding a code span may include spaces — one after the opening, one before the closing. This allows you to place literal backtick characters at the beginning or end of a code span:&lt;/p&gt;
&lt;p&gt;Code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;A single backtick in a code span: `` ` ``

A backtick-delimited string in a code span: `` `foo` ``
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;A single backtick in a code span: &lt;code&gt;`&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;A backtick-delimited string in a code span: &lt;code&gt;`foo`&lt;/code&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;Images&lt;/h3&gt;
&lt;p&gt;HTML Tag: &lt;code&gt;&amp;lt;img /&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Markdown uses an image syntax that is intended to resemble the syntax for links, allowing for two styles: inline and reference.&lt;/p&gt;
&lt;h4&gt;Inline&lt;/h4&gt;
&lt;p&gt;Inline image syntax looks like this: &lt;code&gt;![Alt text](URL &quot;Title&quot;)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Title is optional.&lt;/p&gt;
&lt;p&gt;Code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;![Alt text](/path/to/img.jpg)

![Alt text](/path/to/img.jpg &quot;Optional title&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;img src=&quot;https://s2.loli.net/2024/08/20/5fszgXeOxmL3Wdv.webp&quot; alt=&quot;Alt text&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://s2.loli.net/2024/08/20/5fszgXeOxmL3Wdv.webp&quot; alt=&quot;Alt text&quot; title=&quot;Optional title&quot; /&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;That is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;An exclamation mark: !;&lt;/li&gt;
&lt;li&gt;followed by a set of square brackets, containing the alt attribute text for the image;&lt;/li&gt;
&lt;li&gt;followed by a set of parentheses, containing the URL or path to the image, and an optional title attribute enclosed in double or single quotes.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Reference&lt;/h4&gt;
&lt;p&gt;Reference-style image syntax looks like this: &lt;code&gt;![Alt text][id]&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[img id]: https://s2.loli.net/2024/08/20/5fszgXeOxmL3Wdv.webp  &quot;Optional title attribute&quot;
![Alt text][img id]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;img src=&quot;https://s2.loli.net/2024/08/20/5fszgXeOxmL3Wdv.webp&quot; alt=&quot;Alt text&quot; title=&quot;Optional title attribute&quot; /&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;Strikethrough&lt;/h3&gt;
&lt;p&gt;HTML Tag: &lt;code&gt;&amp;lt;del&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;It&apos;s an extension.&lt;/p&gt;
&lt;p&gt;GFM adds syntax to strikethrough text.&lt;/p&gt;
&lt;p&gt;Code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;~~Mistaken text.~~
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;s&gt;Mistaken text.&lt;/s&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Miscellaneous&lt;/h2&gt;
&lt;h3&gt;Automatic Links&lt;/h3&gt;
&lt;p&gt;Markdown supports a shortcut style for creating &quot;automatic&quot; links for URLs and email addresses: simply surround the URL or email address with angle brackets.&lt;/p&gt;
&lt;p&gt;Code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;http://example.com/&amp;gt;

&amp;lt;address@example.com&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;a href=&quot;http://example.com/&quot;&gt;http://example.com/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;mailto:address@example.com&quot;&gt;address@example.com&lt;/a&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;GFM will autolink standard URLs.&lt;/p&gt;
&lt;p&gt;Code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;https://github.com/emn178/markdown
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;https://github.com/emn178/markdown&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;Backslash Escapes&lt;/h3&gt;
&lt;p&gt;Markdown allows you to use backslash escapes to generate literal characters which would otherwise have special meaning in Markdown&apos;s formatting syntax.&lt;/p&gt;
&lt;p&gt;Code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;\*literal asterisks\*
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;*literal asterisks*&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Markdown provides backslash escapes for the following characters:&lt;/p&gt;
&lt;p&gt;Code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;\   backslash
`   backtick
*   asterisk
_   underscore
{}  curly braces
[]  square brackets
()  parentheses
#   hash mark
+   plus sign
-   minus sign (hyphen)
.   dot
!   exclamation mark
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Inline HTML&lt;/h2&gt;
&lt;p&gt;For any markup that is not covered by Markdown&apos;s syntax, you simply use HTML itself. There&apos;s no need to preface it or delimit it to indicate that you&apos;re switching from Markdown to HTML; you just use the tags.&lt;/p&gt;
&lt;p&gt;Code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;This is a regular paragraph.

&amp;lt;table&amp;gt;
    &amp;lt;tr&amp;gt;
        &amp;lt;td&amp;gt;Foo&amp;lt;/td&amp;gt;
    &amp;lt;/tr&amp;gt;
&amp;lt;/table&amp;gt;

This is another regular paragraph.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;This is a regular paragraph.&lt;/p&gt;
&lt;p&gt;&amp;lt;table&amp;gt;
&amp;lt;tr&amp;gt;
&amp;lt;td&amp;gt;Foo&amp;lt;/td&amp;gt;
&amp;lt;/tr&amp;gt;
&amp;lt;/table&amp;gt;&lt;/p&gt;
&lt;p&gt;This is another regular paragraph.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Note that Markdown formatting syntax is &lt;strong&gt;not processed within block-level HTML tags&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Unlike block-level HTML tags, Markdown syntax is &lt;strong&gt;processed within span-level tags&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;span&amp;gt;**Work**&amp;lt;/span&amp;gt;

&amp;lt;div&amp;gt;
    **No Work**
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&amp;lt;span&amp;gt;&lt;strong&gt;Work&lt;/strong&gt;&amp;lt;/span&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;div&amp;gt;
&lt;strong&gt;No Work&lt;/strong&gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;hr /&gt;
</content:encoded></item><item><title>Markdown Extended Features</title><link>https://www.kukie.cn/posts/markdown-extended/</link><guid isPermaLink="true">https://www.kukie.cn/posts/markdown-extended/</guid><description>Read more about Markdown features in Mizuki</description><pubDate>Wed, 01 May 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;GitHub Repository Cards&lt;/h2&gt;
&lt;p&gt;You can add dynamic cards that link to GitHub repositories, on page load, the repository information is pulled from the GitHub API.&lt;/p&gt;
&lt;p&gt;::github{repo=&quot;matsuzaka-yuki/Mizuki&quot;}&lt;/p&gt;
&lt;p&gt;Create a GitHub repository card with the code &lt;code&gt;::github{repo=&quot;matsuzaka-yuki/Mizuki&quot;}&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;::github{repo=&quot;matsuzaka-yuki/Mizuki&quot;}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Admonitions&lt;/h2&gt;
&lt;p&gt;Following types of admonitions are supported: &lt;code&gt;note&lt;/code&gt; &lt;code&gt;tip&lt;/code&gt; &lt;code&gt;important&lt;/code&gt; &lt;code&gt;warning&lt;/code&gt; &lt;code&gt;caution&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;:::note
Highlights information that users should take into account, even when skimming.
:::&lt;/p&gt;
&lt;p&gt;:::tip
Optional information to help a user be more successful.
:::&lt;/p&gt;
&lt;p&gt;:::important
Crucial information necessary for users to succeed.
:::&lt;/p&gt;
&lt;p&gt;:::warning
Critical content demanding immediate user attention due to potential risks.
:::&lt;/p&gt;
&lt;p&gt;:::caution
Negative potential consequences of an action.
:::&lt;/p&gt;
&lt;h3&gt;Basic Syntax&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;:::note
Highlights information that users should take into account, even when skimming.
:::

:::tip
Optional information to help a user be more successful.
:::
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Custom Titles&lt;/h3&gt;
&lt;p&gt;The title of the admonition can be customized.&lt;/p&gt;
&lt;p&gt;:::note[MY CUSTOM TITLE]
This is a note with a custom title.
:::&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;:::note[MY CUSTOM TITLE]
This is a note with a custom title.
:::
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;GitHub Syntax&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;[!TIP]
&lt;a href=&quot;https://github.com/orgs/community/discussions/16925&quot;&gt;The GitHub syntax&lt;/a&gt; is also supported.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; [!NOTE]
&amp;gt; The GitHub syntax is also supported.

&amp;gt; [!TIP]
&amp;gt; The GitHub syntax is also supported.
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Spoiler&lt;/h3&gt;
&lt;p&gt;You can add spoilers to your text. The text also supports &lt;strong&gt;Markdown&lt;/strong&gt; syntax.&lt;/p&gt;
&lt;p&gt;The content :spoiler[is hidden &lt;strong&gt;ayyy&lt;/strong&gt;]!&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;The content :spoiler[is hidden **ayyy**]!&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Encrypted Post</title><link>https://www.kukie.cn/posts/encrypted-post/</link><guid isPermaLink="true">https://www.kukie.cn/posts/encrypted-post/</guid><description>This is an article for testing the page encryption feature</description><pubDate>Mon, 15 Jan 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;This blog template is built with &lt;a href=&quot;https://astro.build/&quot;&gt;Astro&lt;/a&gt;. For the things that are not mentioned in this guide, you may find the answers in the &lt;a href=&quot;https://docs.astro.build/&quot;&gt;Astro Docs&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Front-matter of Posts&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;---
title: My First Blog Post
published: 2023-09-09
description: This is the first post of my new Astro blog.
image: ./cover.jpg
tags: [Foo, Bar]
category: Front-end
draft: false
---
&lt;/code&gt;&lt;/pre&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Attribute&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;title&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The title of the post.&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;The date the post was published.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pinned&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Whether this post is pinned to the top of the post list.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;description&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;A short description of the post. Displayed on index page.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;image&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The cover image path of the post.&amp;lt;br/&amp;gt;1. Start with &lt;code&gt;http://&lt;/code&gt; or &lt;code&gt;https://&lt;/code&gt;: Use web image&amp;lt;br/&amp;gt;2. Start with &lt;code&gt;/&lt;/code&gt;: For image in &lt;code&gt;public&lt;/code&gt; dir&amp;lt;br/&amp;gt;3. With none of the prefixes: Relative to the markdown file&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;The tags of the post.&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;The category of the post.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;alias&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;alias for the post. The post will be accessible at &lt;code&gt;/posts/{alias}/&lt;/code&gt;. Example: &lt;code&gt;my-special-article&lt;/code&gt; (will be available at &lt;code&gt;/posts/my-special-article/&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;licenseName&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The license name for the post content.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;author&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The author of the post.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sourceLink&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The source link or reference for the post content.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;draft&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;If this post is still a draft, which won&apos;t be displayed.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;Where to Place the Post Files&lt;/h2&gt;
&lt;p&gt;Your post files should be placed in &lt;code&gt;src/content/posts/&lt;/code&gt; directory. You can also create sub-directories to better organize your posts and assets.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;src/content/posts/
├── post-1.md
└── post-2/
    ├── cover.png
    └── index.md
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Posts alias&lt;/h2&gt;
&lt;p&gt;You can set a alias for any post by adding the &lt;code&gt;alias&lt;/code&gt; field to the front-matter:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;---
title: My Special Article
published: 2024-01-15
alias: &quot;my-special-article&quot;
tags: [&quot;Example&quot;]
category: &quot;Technology&quot;
---
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When a alias is set:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The post will be accessible at the custom URL (e.g., &lt;code&gt;/posts/my-special-article/&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;The default &lt;code&gt;/posts/{slug}/&lt;/code&gt; URL will still work&lt;/li&gt;
&lt;li&gt;RSS/Atom feeds will use the custom alias&lt;/li&gt;
&lt;li&gt;All internal links will automatically use the custom alias&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Important Notes:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Alias should NOT include &lt;code&gt;/posts/&lt;/code&gt; prefix (it will be added automatically)&lt;/li&gt;
&lt;li&gt;Avoid special characters and spaces in alias&lt;/li&gt;
&lt;li&gt;Use lowercase letters and hyphens for best SEO practices&lt;/li&gt;
&lt;li&gt;Make sure alias are unique across all posts&lt;/li&gt;
&lt;li&gt;Don&apos;t include leading or trailing slashes&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;How It Works&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;graph LR
    A[User Password] --&amp;gt; B[bcrypt Hash]
    B --&amp;gt; C[Password Hash]
    C --&amp;gt; D[Extract First 32 Characters]
    D --&amp;gt; E[Encryption Key]
    E --&amp;gt; F[AES Encryption]
    F --&amp;gt; G[Encrypted Content]
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Markdown Mermaid</title><link>https://www.kukie.cn/posts/markdown-mermaid/</link><guid isPermaLink="true">https://www.kukie.cn/posts/markdown-mermaid/</guid><description>A simple example of a Markdown blog post with Mermaid.</description><pubDate>Sun, 01 Oct 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;Complete Guide to Markdown with Mermaid Diagrams&lt;/h1&gt;
&lt;p&gt;This article demonstrates how to create various complex diagrams using Mermaid in Markdown documents, including flowcharts, sequence diagrams, Gantt charts, class diagrams, and state diagrams.&lt;/p&gt;
&lt;h2&gt;Flowchart Example&lt;/h2&gt;
&lt;p&gt;Flowcharts are excellent for representing processes or algorithm steps.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;graph TD
    A[Start] --&amp;gt; B{Condition Check}
    B --&amp;gt;|Yes| C[Process Step 1]
    B --&amp;gt;|No| D[Process Step 2]
    C --&amp;gt; E[Subprocess]
    D --&amp;gt; E
    subgraph E [Subprocess Details]
        E1[Substep 1] --&amp;gt; E2[Substep 2]
        E2 --&amp;gt; E3[Substep 3]
    end
    E --&amp;gt; F{Another Decision}
    F --&amp;gt;|Option 1| G[Result 1]
    F --&amp;gt;|Option 2| H[Result 2]
    F --&amp;gt;|Option 3| I[Result 3]
    G --&amp;gt; J[End]
    H --&amp;gt; J
    I --&amp;gt; J
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Sequence Diagram Example&lt;/h2&gt;
&lt;p&gt;Sequence diagrams show interactions between objects over time.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sequenceDiagram
    participant User
    participant WebApp
    participant Server
    participant Database

    User-&amp;gt;&amp;gt;WebApp: Submit Login Request
    WebApp-&amp;gt;&amp;gt;Server: Send Auth Request
    Server-&amp;gt;&amp;gt;Database: Query User Credentials
    Database--&amp;gt;&amp;gt;Server: Return User Data
    Server--&amp;gt;&amp;gt;WebApp: Return Auth Result
    
    alt Auth Successful
        WebApp-&amp;gt;&amp;gt;User: Show Welcome Page
        WebApp-&amp;gt;&amp;gt;Server: Request User Data
        Server-&amp;gt;&amp;gt;Database: Get User Preferences
        Database--&amp;gt;&amp;gt;Server: Return Preferences
        Server--&amp;gt;&amp;gt;WebApp: Return User Data
        WebApp-&amp;gt;&amp;gt;User: Load Personalized Interface
    else Auth Failed
        WebApp-&amp;gt;&amp;gt;User: Show Error Message
        WebApp-&amp;gt;&amp;gt;User: Prompt Re-entry
    end
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Gantt Chart Example&lt;/h2&gt;
&lt;p&gt;Gantt charts are perfect for displaying project schedules and timelines.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;gantt
    title Website Development Project Timeline
    dateFormat  YYYY-MM-DD
    axisFormat  %m/%d
    
    section Design Phase
    Requirements Analysis      :a1, 2023-10-01, 7d
    UI Design                 :a2, after a1, 10d
    Prototype Creation        :a3, after a2, 5d
    
    section Development Phase
    Frontend Development      :b1, 2023-10-20, 15d
    Backend Development       :b2, after a2, 18d
    Database Design           :b3, after a1, 12d
    
    section Testing Phase
    Unit Testing              :c1, after b1, 8d
    Integration Testing       :c2, after b2, 10d
    User Acceptance Testing   :c3, after c2, 7d
    
    section Deployment
    Production Deployment     :d1, after c3, 3d
    Launch                    :milestone, after d1, 0d
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Class Diagram Example&lt;/h2&gt;
&lt;p&gt;Class diagrams show the static structure of a system, including classes, attributes, methods, and their relationships.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;classDiagram
    class User {
        +String username
        +String password
        +String email
        +Boolean active
        +login()
        +logout()
        +updateProfile()
    }
    
    class Article {
        +String title
        +String content
        +Date publishDate
        +Boolean published
        +publish()
        +edit()
        +delete()
    }
    
    class Comment {
        +String content
        +Date commentDate
        +addComment()
        +deleteComment()
    }
    
    class Category {
        +String name
        +String description
        +addArticle()
        +removeArticle()
    }
    
    User &quot;1&quot; -- &quot;*&quot; Article : writes
    User &quot;1&quot; -- &quot;*&quot; Comment : posts
    Article &quot;1&quot; -- &quot;*&quot; Comment : has
    Article &quot;1&quot; -- &quot;*&quot; Category : belongs to
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;State Diagram Example&lt;/h2&gt;
&lt;p&gt;State diagrams show the sequence of states an object goes through during its life cycle.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;stateDiagram-v2
    [*] --&amp;gt; Draft
    
    Draft --&amp;gt; UnderReview : submit
    UnderReview --&amp;gt; Draft : reject
    UnderReview --&amp;gt; Approved : approve
    Approved --&amp;gt; Published : publish
    Published --&amp;gt; Archived : archive
    Published --&amp;gt; Draft : retract
    
    state Published {
        [*] --&amp;gt; Active
        Active --&amp;gt; Hidden : temporarily hide
        Hidden --&amp;gt; Active : restore
        Active --&amp;gt; [*]
        Hidden --&amp;gt; [*]
    }
    
    Archived --&amp;gt; [*]
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Pie Chart Example&lt;/h2&gt;
&lt;p&gt;Pie charts are ideal for displaying proportions and percentage data.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pie title Website Traffic Sources Analysis
    &quot;Search Engines&quot; : 45.6
    &quot;Direct Access&quot; : 30.1
    &quot;Social Media&quot; : 15.3
    &quot;Referral Links&quot; : 6.4
    &quot;Other Sources&quot; : 2.6
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Mermaid is a powerful tool for creating various types of diagrams in Markdown documents. This article demonstrated how to use flowcharts, sequence diagrams, Gantt charts, class diagrams, state diagrams, and pie charts. These diagrams can help you express complex concepts, processes, and data structures more clearly.&lt;/p&gt;
&lt;p&gt;To use Mermaid, simply specify the mermaid language in a code block and describe the diagram using concise text syntax. Mermaid will automatically convert these descriptions into beautiful visual diagrams.&lt;/p&gt;
&lt;p&gt;Try using Mermaid diagrams in your next technical blog post or project documentation - they will make your content more professional and easier to understand!&lt;/p&gt;
</content:encoded></item><item><title>Include Video in the Posts</title><link>https://www.kukie.cn/posts/video/</link><guid isPermaLink="true">https://www.kukie.cn/posts/video/</guid><description>This post demonstrates how to include embedded video in a blog post.</description><pubDate>Mon, 01 Aug 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Just copy the embed code from YouTube or other platforms, and paste it in the markdown file.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;---
title: Include Video in the Post
published: 2023-10-19
// ...
---

&amp;lt;iframe width=&quot;100%&quot; height=&quot;468&quot; src=&quot;https://www.youtube.com/embed/5gIf0_xpFPI?si=N1WTorLKL0uwLsU_&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allowfullscreen&amp;gt;&amp;lt;/iframe&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;YouTube&lt;/h2&gt;
&lt;p&gt;&amp;lt;iframe width=&quot;100%&quot; height=&quot;468&quot; src=&quot;https://www.youtube.com/embed/5gIf0_xpFPI?si=N1WTorLKL0uwLsU_&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; allowfullscreen&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/p&gt;
&lt;h2&gt;Bilibili&lt;/h2&gt;
&lt;p&gt;&amp;lt;iframe width=&quot;100%&quot; height=&quot;468&quot; src=&quot;//player.bilibili.com/player.html?bvid=BV1fK4y1s7Qf&amp;amp;p=1&amp;amp;autoplay=0&quot; scrolling=&quot;no&quot; border=&quot;0&quot; frameborder=&quot;no&quot; framespacing=&quot;0&quot; allowfullscreen=&quot;true&quot; &amp;amp;autoplay=0&amp;gt; &amp;lt;/iframe&amp;gt;&lt;/p&gt;
</content:encoded></item></channel></rss>