归档内容

💡
欢迎加入 Craft Docs 中文社区(非官方): @craft_do
目前 Craft 的分享页面还不支持自定义域名, 所以写了一个 Cloudflare Worker 脚本, 用于反向代理 Craft 页面, 从而实现自定义域名的效果.
notion image

演示

源代码

视频教程

隔壁文章发了个视频版的教程 (点击跳转), 这里就不传了, 给 Notion 节省点空间.

已实现

  • 在 Craft 编辑器里即可配置网站
  • 页面内容实时更新
  • 完整适配 Craft 页面
    • 支持页面白名单
    • 支持密码访问 (公开但需要密码访问)
  • 支持 Craft 评论功能
    • 支持评论提醒 (提醒发送到 Telegram)
  • 支持在 Craft 编辑器中自定义网站界面
  • 优化图片缓存
  • 支持 sitemap
  • SEO 优化

未实现

支持 RSS
支持搜索
支持外联页面

使用方法

1. 准备工作

需要准备以下账号和域名:
  • Cloudflare 账号
  • 托管在 Cloudflare 的域名
  • Craft Docs 账号
  • Telegram 账号(可选, 用于接收评论提醒)
这些服务都是免费的, 其中 Cloudflare Worker 每日都有十万次免费额度(个人网站完全够用), Craft Docs 免费账号也可以使用这个脚本.

2. 设置 DNS 解析

打开 Cloudflare 的仪表盘, 设置域名中添加一项 CNAME 记录. 如果你有一个域名是 mydomain.com, 你希望直接用 mydomain.com 做 Craft 站点, "名称"一栏就填 @ , 如果想用 note.mydomain.com 作为 Craft 站点, "名称"一栏就填 note .
"目标"填 craft.do, 实际上这里填其他任意有效域名都可以, 安全起见就写 Craft 域名吧.
notion image

3. 初始化站点

首先在 Craft 软件中创建一个文件夹, 例如 My Public Notes 或者其他你喜欢的名字. 在文件夹中新建一个页面, 这个页面将会用作你的网站首页, 你可以随意布置这个页面.
点击分享这个页面, 把”显示标题”关闭, 这样你的首页会更好看.
notion image
复制这个页面的分享链接, 我们马上就需要它了.

现在我们还需要再创建一个页面, 它将作为整个网站的配置中心. 现在我们打开这个”配置”页面, 在这个页面的第一行(必须确保是第一行)插入一个代码块, 如下图所示:
notion image
Craft 会弹出一个代码输入框, 高亮选择 JSON.
notion image
在框内填入下面内容:
{ "index": "https://www.craft.do/s/XXXXXXXXX" }
其中 index 是不可改变的, 后面的链接是你刚刚复制的”首页”创建的分享链接.
最后一步, 把这个”配置”页面也打开分享, 复制分享链接. 现在你的 Craft 已经完成初始化.

你可以参考我的网站, 我的首页是 https://note.zuolan.me/ , 我的配置页面是 https://www.craft.do/s/3MtGzyRv7l26kF .
以后, 当你有新的页面想发布, 只需要到”配置”页面的代码块中添加即可. 例如我想添加一个”关于我”的页面, 我只需要在”配置”页面添加新页面的路径和 Craft 的分享链接.
{ "index": "https://www.craft.do/s/XXXXXXXXX", "about": "https://www.craft.do/s/WWWWWWWWW" }

4. 配置 Worker 脚本

打开 Cloudflare 控制台, 点击 Worker 面板, 新建一个 Worker.
notion image
新建页面需要修改三个地方:
  1. 修改 Worker 的名字, 在下图 1 的地方, 修改成你喜欢名字.
  1. 删除代码编辑器里的所有内容, 粘贴 Github 上的代码, 并根据注释修改代码顶部的内容, 改为你的信息.
  1. 点击”保存并部署”.
notion image
返回 Worker 面板, 为刚才创建的脚本设置一个路由, 选择刚刚创建的 worker, 填上你的域名, 注意路由后面的 * 符号是必不可少的.
notion image
现在脚本已经就绪.
你现在可以通过你配置的域名来访问首页了.

5. 自定义你的页面 (可选)

通过 Cloudflare Worker 我们还可以定制一些内容, 例如我的网站右上角的 Logo 菜单. 如果你想自定义一些内容, 可以在脚本代码最后面找到两个类: BodyRewriter 和 HeadRewriter.
在两个类中编写你的 HTML/CSS/JS 代码即可实现自定义页面.
下面是我的自定义菜单的代码 (点击展开)
class BodyRewriter { element(element) { element.append(` <div class="navigation"> <input type="checkbox" class="navigation__checkbox" id="nav-toggle" /> <label for="nav-toggle" class="navigation__button"> <a aria-label="toggle navigation menu"> <img alt="logo" class="navigation__logo" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDBwdCIgaGVpZ2h0PSIxMDBwdCIgdmlld0JveD0iMCAwIDEwMCAxMDAiPjxnIGZpbGw9ImJsdWUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAuMDAwMDAwLDEwMCkgc2NhbGUoMC4wODAwMDAsLTAuMDgwMDAwKSI+PHBhdGggZD0iTTc2MiAxMjAzIGMtNiAtMTUgLTEzIC00NiAtMTcgLTY4IC00IC0yMiAtMTMgLTQ5IC0yMCAtNjEgLTE1IC0yMyAtMTIyIC02OSAtMjU3IC0xMDkgLTQ5IC0xNCAtODggLTI4IC04OCAtMjkgMCAtMiAzMyAtMjAgNzMgLTQwIDQ5IC0yNCA4NyAtMzYgMTE1IC0zNiAyOCAwIDQyIC00IDQyIC0xMyAwIC0zNCAtMjk1IC01MTcgLTM5MCAtNjM5IC00MCAtNTIgLTQgLTI4IDg2IDU2IDQ5IDQ2IDEwNSAxMDkgMTI0IDE0MSAxOSAzMSA2NCA5OCAxMDAgMTQ4IDc3IDEwOCAxMjUgMTg2IDE3MyAyODMgMjAgMzkgNDYgNzggNTkgODYgMTMgOCA2OSAzNCAxMjYgNTggMTA3IDQ1IDExOCA1NyAxMTAgMTExIC0zIDIxIC0xMCAyNSAtNzggMzQgbC03NSAxMCAtNSA0NSBjLTUgNDIgLTcgNDUgLTM2IDQ4IC0yNiAzIC0zMyAtMSAtNDIgLTI1eiIvPjxwYXRoIGQ9Ik03NTQgNjE2IGMtNDAgLTE5IC04OCAtMzkgLTEwOCAtNDYgLTQzIC0xNCAtNDUgLTMwIC03IC03MiAyNSAtMjggMzMgLTMxIDgwIC0zMCAzOSAxIDU0IC0zIDU4IC0xNSA3IC0xOCAtMzAgLTE0MCAtNTggLTE5MiAtMzYgLTY3IDYgLTkzIDEzNSAtODQgbDg2IDYgMCAtMjYgYzAgLTE0IC00IC0zNyAtMTAgLTUxIC01IC0xNCAtOCAtMjYgLTYgLTI2IDcgMCAxMTAgNjggMTI5IDg1IDExIDEwIDE3IDMwIDE3IDYwIDAgNjIgLTIyIDcwIC0xNTAgNTcgLTUyIC01IC05OCAtNiAtMTAzIC0yIC00IDMgMyAzMSAxNiA2MSAxMyAzMCAzMiA3OCA0MiAxMDggMTAgMzAgMjggNzAgNDEgODkgMjYgMzggMzAgNjMgMTQgOTMgLTE3IDMxIC05MSAyNSAtMTc2IC0xNXoiLz48L2c+PC9zdmc+" /> </a> </label> <div class="navigation__background"></div> <h1 class="navigation__title">左蓝的笔记</h1> <div class="navigation__icon"> <a target="_blank" href="<https://t.me/zuolan>"> <img alt="Telegram" src="data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48dGl0bGU+VGVsZWdyYW08L3RpdGxlPjxwYXRoIGZpbGw9ImdyYXkiIGQ9Ik0xMS45NDQgMEExMiAxMiAwIDAgMCAwIDEyYTEyIDEyIDAgMCAwIDEyIDEyIDEyIDEyIDAgMCAwIDEyLTEyQTEyIDEyIDAgMCAwIDEyIDBhMTIgMTIgMCAwIDAtLjA1NiAwem00Ljk2MiA3LjIyNGMuMS0uMDAyLjMyMS4wMjMuNDY1LjE0YS41MDYuNTA2IDAgMCAxIC4xNzEuMzI1Yy4wMTYuMDkzLjAzNi4zMDYuMDIuNDcyLS4xOCAxLjg5OC0uOTYyIDYuNTAyLTEuMzYgOC42MjctLjE2OC45LS40OTkgMS4yMDEtLjgyIDEuMjMtLjY5Ni4wNjUtMS4yMjUtLjQ2LTEuOS0uOTAyLTEuMDU2LS42OTMtMS42NTMtMS4xMjQtMi42NzgtMS44LTEuMTg1LS43OC0uNDE3LTEuMjEuMjU4LTEuOTEuMTc3LS4xODQgMy4yNDctMi45NzcgMy4zMDctMy4yMy4wMDctLjAzMi4wMTQtLjE1LS4wNTYtLjIxMnMtLjE3NC0uMDQxLS4yNDktLjAyNGMtLjEwNi4wMjQtMS43OTMgMS4xNC01LjA2MSAzLjM0NS0uNDguMzMtLjkxMy40OS0xLjMwMi40OC0uNDI4LS4wMDgtMS4yNTItLjI0MS0xLjg2NS0uNDQtLjc1Mi0uMjQ1LTEuMzQ5LS4zNzQtMS4yOTctLjc4OS4wMjctLjIxNi4zMjUtLjQzNy44OTMtLjY2MyAzLjQ5OC0xLjUyNCA1LjgzLTIuNTI5IDYuOTk4LTMuMDE0IDMuMzMyLTEuMzg2IDQuMDI1LTEuNjI3IDQuNDc2LTEuNjM1eiIvPjwvc3ZnPg==" /> </a> <a target="_blank" href="<https://twitter.com/izuolan>"> <img alt="Twitter" src="data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48dGl0bGU+VHdpdHRlcjwvdGl0bGU+PHBhdGggZmlsbD0iZ3JheSIgZD0iTTIzLjk1MyA0LjU3YTEwIDEwIDAgMDEtMi44MjUuNzc1IDQuOTU4IDQuOTU4IDAgMDAyLjE2My0yLjcyM2MtLjk1MS41NTUtMi4wMDUuOTU5LTMuMTI3IDEuMTg0YTQuOTIgNC45MiAwIDAwLTguMzg0IDQuNDgyQzcuNjkgOC4wOTUgNC4wNjcgNi4xMyAxLjY0IDMuMTYyYTQuODIyIDQuODIyIDAgMDAtLjY2NiAyLjQ3NWMwIDEuNzEuODcgMy4yMTMgMi4xODggNC4wOTZhNC45MDQgNC45MDQgMCAwMS0yLjIyOC0uNjE2di4wNmE0LjkyMyA0LjkyMyAwIDAwMy45NDYgNC44MjcgNC45OTYgNC45OTYgMCAwMS0yLjIxMi4wODUgNC45MzYgNC45MzYgMCAwMDQuNjA0IDMuNDE3IDkuODY3IDkuODY3IDAgMDEtNi4xMDIgMi4xMDVjLS4zOSAwLS43NzktLjAyMy0xLjE3LS4wNjdhMTMuOTk1IDEzLjk5NSAwIDAwNy41NTcgMi4yMDljOS4wNTMgMCAxMy45OTgtNy40OTYgMTMuOTk4LTEzLjk4NSAwLS4yMSAwLS40Mi0uMDE1LS42M0E5LjkzNSA5LjkzNSAwIDAwMjQgNC41OXoiLz48L3N2Zz4=" /> </a> <a target="_blank" href="<https://github.com/izuolan>"> <img alt="Giithub" src="data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48dGl0bGU+R2l0SHViPC90aXRsZT48cGF0aCBmaWxsPSJncmF5IiBkPSJNMTIgLjI5N2MtNi42MyAwLTEyIDUuMzczLTEyIDEyIDAgNS4zMDMgMy40MzggOS44IDguMjA1IDExLjM4NS42LjExMy44Mi0uMjU4LjgyLS41NzcgMC0uMjg1LS4wMS0xLjA0LS4wMTUtMi4wNC0zLjMzOC43MjQtNC4wNDItMS42MS00LjA0Mi0xLjYxQzQuNDIyIDE4LjA3IDMuNjMzIDE3LjcgMy42MzMgMTcuN2MtMS4wODctLjc0NC4wODQtLjcyOS4wODQtLjcyOSAxLjIwNS4wODQgMS44MzggMS4yMzYgMS44MzggMS4yMzYgMS4wNyAxLjgzNSAyLjgwOSAxLjMwNSAzLjQ5NS45OTguMTA4LS43NzYuNDE3LTEuMzA1Ljc2LTEuNjA1LTIuNjY1LS4zLTUuNDY2LTEuMzMyLTUuNDY2LTUuOTMgMC0xLjMxLjQ2NS0yLjM4IDEuMjM1LTMuMjItLjEzNS0uMzAzLS41NC0xLjUyMy4xMDUtMy4xNzYgMCAwIDEuMDA1LS4zMjIgMy4zIDEuMjMuOTYtLjI2NyAxLjk4LS4zOTkgMy0uNDA1IDEuMDIuMDA2IDIuMDQuMTM4IDMgLjQwNSAyLjI4LTEuNTUyIDMuMjg1LTEuMjMgMy4yODUtMS4yMy42NDUgMS42NTMuMjQgMi44NzMuMTIgMy4xNzYuNzY1Ljg0IDEuMjMgMS45MSAxLjIzIDMuMjIgMCA0LjYxLTIuODA1IDUuNjI1LTUuNDc1IDUuOTIuNDIuMzYuODEgMS4wOTYuODEgMi4yMiAwIDEuNjA2LS4wMTUgMi44OTYtLjAxNSAzLjI4NiAwIC4zMTUuMjEuNjkuODI1LjU3QzIwLjU2NSAyMi4wOTIgMjQgMTcuNTkyIDI0IDEyLjI5N2MwLTYuNjI3LTUuMzczLTEyLTEyLTEyIi8+PC9zdmc+" /> </a> </div> <nav class="navigation__nav" role="navigation"> <ul class="navigation__list"> <li class="navigation__item"> <a href="<https://note.zuolan.me/>" target="_blank" class="navigation__link">首页</a> </li> <li class="navigation__item"> <a href="<https://note.zuolan.me/about>" target="_blank" class="navigation__link">关于</a> </li> <li class="navigation__item"> <a href="#" class="navigation__link">联系</a> </li> </ul> <p class="footer">© CC BY-NC-SA 4.0</p> </nav> </div> `, { html: true }) } } class HeadRewriter { element(element) { element.append(` <style> /* Hide the Craft "Login in" button in comment board. */ .sc-CtfFt { visibility: hidden; } .hGGlzy { visibility: hidden; } .header .right-side { padding-right: 3rem; } .navigation { position: fixed; top: 0; right: 0; z-index: 400; } .navigation__checkbox { display: none; } .navigation__button { position: absolute; top: 0.5rem; right: 0.8rem; height: 2.4rem; width: 2.4rem; text-align: center; border-radius: 50%; z-index: 300; cursor: pointer; } .navigation__logo { width: 1.5rem; height: 1.5rem; padding-top: 0.4rem; padding-right: 0.1rem; } .navigation__title { position: fixed; top: 0.5rem; right: 3rem; visibility: hidden; margin: 0.5rem 1rem; color: gray; font-size: 1rem; z-index: 300; transition: all 200ms ease-out; } .navigation__background { position: fixed; top: 0.5rem; right: 0.7rem; height: 2.4rem; width: 2.4rem; border-radius: 50%; background: #FFFFFF; /* background-size: cover; background-position: center; */ z-index: 100; transition: all 400ms cubic-bezier(0.86, 0, 0.07, 1); } .navigation__nav { position: fixed; top: 0; right: 0; opacity: 0; width: 100%; visibility: hidden; z-index: 200; transition: all 400ms ease-in; } .navigation__icon { position: fixed; top: 17rem; right: 0; visibility: hidden; margin: 0.8rem 2rem; z-index: 300; transition: all 200ms ease-out; } .navigation__icon a { top: 0; right: 0; display: inline-block; width: 1rem; margin: 0.5rem; z-index: 300; } .navigation__list { position: absolute; top: 4rem; right: 1rem; list-style: none; } .navigation__item { margin: 1rem; } .navigation__link:link, .navigation__link:visited { display: inline-block; padding: 0.5rem 1rem; color: #494b4e; font-size: 1.4rem; text-decoration: none; transition: all 0.2s; } .navigation__icon a:hover { opacity: 0.7; } .navigation__link:hover { color: #494b4e; transform: scale(1.2); } .navigation__checkbox:checked ~ .navigation__background { background: #edeeee; transform: scale(20); /* transform: scale(80); */ } .navigation__checkbox:checked ~ .navigation__title { visibility: visible; opacity: 1; } .navigation__checkbox:checked ~ .navigation__icon { visibility: visible; opacity: 1; } .navigation__checkbox:checked ~ .navigation__nav { width: 100%; visibility: visible; opacity: 1; } .footer { position: absolute; top: 20rem; right: 2rem; color: #b7c0c3; font-size: 0.8rem; } </style> `, { html: true }) } }
对于本文内容有任何疑问, 可与我联系.