博客
前提:
1.git
2.github帐号
3.cloudflare帐号
折腾了这么久,博客和该死的评论终于弄完了.
Fuwari博客还算简单.
参考链接
这是fuwari的github仓库,点击fork(分叉),Repository name(仓库名)随便,Description(介绍)随便,取消勾选Copy the main branch only(仅复制主分支),点击Create fork.
在命令行中执行以下命令:
git clone <你分叉的仓库地址>
npm install -g pnpm
cd 你分叉的仓库的仓库名
pnpm install #不要运行pnpm add sharp改写Fuwari的基本信息
我们先来改src/config.ts文件,这个文件算是基础设置吧
import type { ExpressiveCodeConfig, LicenseConfig, NavBarConfig, ProfileConfig, SiteConfig,} from "./types/config";import { LinkPreset } from "./types/config";
export const siteConfig: SiteConfig = { title: "Fuwari",//你的博客主标题 subtitle: "Demo Site",//你的博客副标题.可选,在浏览器标签那里会显示为"主标题 - 副标题" lang: "en", // 博客显示语言 'en', 'zh_CN', 'ja','ko'. themeColor: { hue: 250, //你的博客主题色,可以在你的博客右上角的画板图标确定喜欢的颜色再填写 fixed: false, // 为访客隐藏主题颜色选择器 }, banner: { enable: false,//是否开启,如果要开启,请设置为true src: "assets/images/demo-banner.png", //即banner图片,支持http/https URL,相对于/src目录。如果以'/'开头,相对于/public目录 position: "center", // 图片位置,仅支持 'top'、'center'、'bottom'。默认为 'center' credit: { enable: false, // 显示图片的版权文本 text: "", // 要显示的文本 url: "", // (可选)指向原始艺术品或艺术家页面的链接 }, }, toc: { enable: true, // 在文章右侧显示大纲 depth: 2, // Maximum heading depth to show in the table, from 1 to 3 }, favicon: [//即网站图标,支持http/https URL // 留空此数组以使用默认的favicon // { // src: '/favicon/icon.png', // favicon的路径,相对于/public目录 // theme: 'light', // (可选)'light' or 'dark'(“亮”或“暗”),仅当您对亮模式和暗模式有不同的收藏夹图标时才设置 // sizes: '32x32', // (可选)favicon的大小,仅当您有不同大小的favicon时才设置 // } ],};
export const navBarConfig: NavBarConfig = {//导航栏设置的超链接 links: [//这些链接在导航栏上,在关于右边 LinkPreset.Home, LinkPreset.Archive, LinkPreset.About, { name: "GitHub", url: "https://github.com/saicaca/fuwari", // 内部链接不应包含基本路径,因为它会自动添加 external: true, // 显示外部链接图标,并将在新选项卡中打开 }, ],};
export const profileConfig: ProfileConfig = {//你的用户的超链接 avatar: "assets/images/demo-avatar.png", // 相对于/src目录。如果以'/'开头,相对于/public目录 name: "Lorem Ipsum",//你的名字 bio: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",//即个性签名,会显示在头像和名字下面 links: [ { name: "Twitter", icon: "fa6-brands:twitter", // 访问 https://icones.js.org/ 获取图标代码 // 如果尚未包含,您需要安装相应的图标集 // `pnpm add @iconify-json/<图标集名称>` //比如QQ,则填写 fa6-brands:qq ,如图。Fuwari默认支持这几种类型:fa6-brands, fa6-regular, fa6-solid, material-symbols。可以在 astro.config.mjs 中搜索关键字进行配置 url: "https://twitter.com", }, { name: "Steam", icon: "fa6-brands:steam", url: "https://store.steampowered.com", }, { name: "GitHub", icon: "fa6-brands:github", url: "https://github.com/saicaca/fuwari", }, ],};
export const licenseConfig: LicenseConfig = { enable: true, name: "CC BY-NC-SA 4.0", url: "https://creativecommons.org/licenses/by-nc-sa/4.0/",};
export const expressiveCodeConfig: ExpressiveCodeConfig = { // Note: Some styles (such as background color) are being overridden, see the astro.config.mjs file. // Please select a dark theme, as this blog theme currently only supports dark background color theme: "github-dark",};写作
清理src/content/posts目录下的多余文件
首先,在项目根目录执行:
pnpm new-post <这里填写你的文章标题>然后,在根目录下的src/content/posts文件夹中会多出一个 xxx.md文件
我们使用MarkText打开这个文件,你可以看到一些基本信息,我们只需要关注几个重要的信息
---title: xxxpublished: 2024-10-14description: ''image: ''tags: []categories: ''draft: falselang: ''---title:文章标题published:文章创建时间description:文章描述,正常会显示在文章标题下面image:文章封面图(同目录需要写 ./ 如:./https://xxxx/myblog/img/2024-10-14-11-33-28-image.webp)tag:文章标签categories:文章分类draft: 是否为草稿pinned: 是否置顶文章lang: 文章语言,与src/config.ts中设置的不同的话要设置一下更改仓库根目录下的astro.config.mjs。在第34行更改 stie: 为你的站点URL,如: site: “https://blog.com”
预览
在项目根目录执行
pnpm dev发布
设置用户名和邮箱
git config --global user.name "你的Github用户名"git config --global user.email "你的Github邮箱@example.com"更改远程仓库为ssh*(如果是通过ssh克隆的不用改)
git remote set-url origin git@github.com:xxx/xxx提交所有文件
git add .让我们发布一个本地提交
git commit -m "项目初始化"让我们将本地更改提交到远程仓库
git push接下来我们用大善人Cloudflare来构建你的博客
打开Cloudflare,点击计算和 AI,点击 Workers 和 Pages,点击创建应用程序
点击想要部署 Pages后的开始使用
然后选择连接Git存储库,连接你的Github,随后设置
- 构建命令:pnpm build
- 输出目录:dist
绑定自定义域,访问自定义域即可访问你的博客!
之后只需要写文章推送至github就行,大善人会帮你自动构建
cloudflare部署玄学问题
前面写道大善人会帮你自动构建,但是会遇到玄学问题,构建会概率性出现问题,日志如下
Build fails on [vite
这个要么重复构建,要么在src/styles/markdown.css的最顶部添加以下行,让构建通过
@import './main.css';当然这或许并不是一个完美的解决办法.
添加Twikoo评论支持
关于评论这里有两套方案
一个是Giscus,一个是我使用的Twikoo,giscus有个巨大的特点是使用它的博客评论的时候需要登陆github,而twikoo不要.
接下来介绍使用twikoo给fuwari提供评论支持.
参考链接
这是官方的教程,可以理解成twikoo存储数据的方式.
大概分为docker和后端加数据库两种.
docker可以使用Zeabur或者私有部署.
Docker
docker run --name twikoo -e TWIKOO_THROTTLE=1000 -p 8080:8080 -v ${PWD}/data:/app/data -d imaegoo/twikooDocker Compose
version: '3'services: twikoo: image: imaegoo/twikoo container_name: twikoo restart: unless-stopped ports: - 8080:8080 environment: TWIKOO_THROTTLE: 1000 volumes: - ./data:/app/datazeabur
镜像:imaegoo/twikoo环境变量:TWIKOO_THROTTLE: 1000端口:8080卷:/app/data(资源限制 内存 (Mi)64)docker部署完了之后,zeabur设置域名访问即可.
私有部署
cd /optmkdir twikoocd twikoonano docker-compose.ymldocker-compose.yml内容如下:
version: '3'services: twikoo: image: imaegoo/twikoo container_name: twikoo restart: unless-stopped ports: - 8080:8080 environment: TWIKOO_THROTTLE: 1000 volumes: - ./data:/app/data这里参考Astro | 为 Fuwari 主题添加 Twikoo 评论,我没用这种方法就不写了.
Vercel 部署
我用的方案是官方方案中的vercel方案,使用vercel作后端,MongoDB作数据库.
1.准备 MongoDB 数据库
参考链接:
申请 MongoDB Atlas 账号,获取 MongoDB 连接字符串
MongoDB Atlas 是 MongoDB Inc 提供的 MongoDB 数据库托管服务。免费账户可以永久使用 500 MiB 的数据库,足够存储 Twikoo 评论使用。
- 申请 MongoDB AtLas 账号
- 创建免费 MongoDB 数据库,区域推荐选择离 Twikoo 后端(Vercel / Netlify / AWS Lambda / VPS)地理位置较近的数据中心以获得更低的数据库连接延迟。如果不清楚自己的后端在哪个区域,也可选择 AWS / Oregon (us-west-2),该数据中心基建成熟,故障率低,且使用 Oregon 州的清洁能源,较为环保
- 在 Database Access(数据库访问) 页面点击 Add New Database User(添加新数据库用户) 创建数据库用户,Authentication Method(认证方式) 选 Password(密码),在 Password Authentication(密码验证) 下设置数据库用户名和密码,建议点击 Auto Generate(自动生成) 自动生成一个不含特殊符号的强壮密码并妥善保存。点击 Database User Privileges(数据库用户权限) 下方的 Add Built In Role(添加内置角色),Select Role (选择角色)选择 Read and write to any database(读取和写入任何数据库),也可以试试Specific Privileges(特定权限),最后点击 Add User(添加用户).
- 在 Network Access(网络访问) 页面点击 Add IP Address(添加 IP 地址) 添加网络白名单。因为 Vercel / Netlify / Lambda 的出口地址不固定,因此在 Access List Entry(访问列表条目) 输入 0.0.0.0/0(允许所有 IP 地址的连接)即可。如果 Twikoo 部署在自己的服务器上,这里可以填入固定 IP 地址。点击 Confirm 保存
- 获取连接字符串,格式如下:
mongodb+srv://<用户名>:<密码>@cluster0.xxxx.mongodb.net/?retryWrites=true&w=majority&appName=Cluster02. 部署到 Vercel
- 申请 Vercel 账号
- 点击按钮将 Twikoo 一键部署到 Vercel Deploy
- 进入 Settings(设置) - Environment Variables(环境变量),添加环境变量 MONGODB_URI,值为前面记录的数据库连接字符串
默认的连接字符串没有指定数据库名称,Twikoo 会连接到默认的名为 test 的数据库.如果需要在同一个 MongoDB 里运行其他业务或供多个 Twikoo 实例使用,建立加入数据库名称并配置对应的 ACL.
mongodb+srv://<db_username>:<db_password>@cluster0.xxxx.mongodb.net/?retryWrites=true&w=majority&appName=Cluster0)上面这个就是默认的.
如果要设置数据库名称则在cluster0.xxxx.mongodb.net/后面指定数据库名称,如下面的.
mongodb+srv://<db_username>:<db_password>@cluster0.xxxx.mongodb.net/twikoo_fuwari?retryWrites=true&w=majority&appName=Cluster0- 进入 Settings(设置) - Deployment Protection(部署保护),设置 Vercel Authentication(Vercel身份验证) 为 Disabled(禁用),并 Save(保存)
- 进入 Deployments(部署) , 然后在任意一项后面点击更多(三个点) , 然后点击 Redeploy(重新部署) , 最后点击下面的 Redeploy(重新部署)
- 进入 Overview(概览),点击 Domains(域名) 下方的链接,如果环境配置正确,可以看到 “Twikoo 云函数运行正常” 的提示
Vercel Domains(域名)(包含 https:// 前缀,例如 https://xxx.vercel.app)即为您的环境 id
这里提醒一下vercel的域名在国内无法访问,记得把域名换掉.
vercel是后端,vercel的项目域名是后面的envId,MongoDB是数据库,数据库连接字符串能让后端访问数据库.
vercel弄完了之后,我们来为Fuwari添加Twikoo评论支持
参考链接
在项目目录src/components/comment下创建Twikoo.astro文件
twikoo官方文档中cdn引入方式文本
<div id="tcomment"></div><script src="https://cdn.jsdelivr.net/npm/twikoo@1.6.44/dist/twikoo.min.js"></script><script>twikoo.init({ envId: '您的环境id', // 腾讯云环境填 envId;Vercel 环境填地址(https://xxx.vercel.app) el: '#tcomment', // 容器元素 // region: 'ap-guangzhou', // 环境地域,默认为 ap-shanghai,腾讯云环境填 ap-shanghai 或 ap-guangzhou;Vercel 环境不填 // path: location.pathname, // 用于区分不同文章的自定义 js 路径,如果您的文章路径不是 location.pathname,需传此参数 // lang: 'zh-CN', // 用于手动设定评论区语言,支持的语言列表 https://github.com/twikoojs/twikoo/blob/main/src/client/utils/i18n/index.js})</script>这个官方引入方式修改如下写入Twikoo.astro文件
---import { commentConfig } from "@/config";
interface Props { path: string;}
const config = { ...commentConfig.twikoo, el: "#tcomment", path: Astro.props.path,};---
<div id="tcomment"></div><script is:inline src="https://cdn.staticfile.org/twikoo/1.6.44/twikoo.all.min.js"></script><!--这个链接里的版本号要改成你后端的版本号--><script is:inline define:vars={{ config }}> twikoo.init(config)</script>在src/components/comment路径下新建index.astro
---import type { CollectionEntry } from "astro:content";import { commentConfig } from "@/config";import Twikoo from "./Twikoo.astro";
interface Props { post: CollectionEntry<"posts">;}
const { id, data, slug } = Astro.props.post;
const path = `/posts/${slug}`;const url = `${Astro.site?.href}${path}`;
let commentService = "";if (commentConfig?.twikoo) { commentService = "twikoo";}---<div class="card-base p-6 mb-4"> {commentService === 'twikoo' && <Twikoo path={path} />} {commentService === '' && null}</div>然后在 Fuwari 主题的配置文件src/config.ts中的最后添加下述代码来引入commentConfig加载配置:
export const expressiveCodeConfig: ExpressiveCodeConfig = { // Note: Some styles (such as background color) are being overridden, see the astro.config.mjs file. // Please select a dark theme, as this blog theme currently only supports dark background color theme: "github-dark",};
export const commentConfig: CommentConfig = { twikoo: { envId: "https://xxx",//您的环境id lang: "zh-CN", },};envId这一项填写你的envId,非腾讯云环境的话就是 twikoo 后端服务的域名.
修改src/pages/posts/[…slug].astro将 Twikoo 使用的页面路径引入.在顶部也要引入一下index.astro来加载 twikoo 等评论系统可显示的页面配置.
---import path from "node:path";import Comment from "@components/comment/index.astro"; // twikoo评论import License from "@components/misc/License.astro";import Markdown from "@components/misc/Markdown.astro";import I18nKey from "@i18n/i18nKey";
.....
</div> </div>
<Comment post={entry}></Comment> <!-- twikoo评论 -->
<div class="flex flex-col md:flex-row justify-between mb-4 gap-4 overflow-hidden w-full"> <a href={entry.data.nextSlug ? getPostUrlBySlug(entry.data.nextSlug) : "#"} class:list={["w-full font-bold overflow-hidden active:scale-95", {"pointer-events-none": !entry.data.nextSlug}]}>最后src/types/config.ts中加入
export type LIGHT_DARK_MODE = | typeof LIGHT_MODE | typeof DARK_MODE | typeof AUTO_MODE;
// twikoo评论export type CommentConfig = { twikoo?: TwikooConfig;};
type TwikooConfig = { envId: string; region?: string; lang?: string;};// twikoo评论结束保存更改之后本地运行pnpm dev应该能看到posts页面下的文章都能够显示评论了,点击小齿轮图标可以进入管理页面.
这时试着发下评论,如果没问题的话,后端会在数据库里创建数据库.
魔改 Twikoo 样式
新建src/styles/twikoo.css
:root { --tk-text: black; }
html.dark { --tk-text: #d1d5db; }
.tk-comments { @apply text-[var(--tk-text)]; }
.tk-submit { .tk-avatar {134 collapsed lines
@apply hidden; } }
/* Text Area */ .tk-row { .tk-col { @apply flex-col-reverse; .tk-input { textarea { @apply rounded-[var(--radius-large)] py-4 px-6 !min-h-[150px] focus:border-[var(--primary)]; } } } }
/* meta input style */ .tk-meta-input { @apply relative mt-3; div { @apply min-h-10; .el-input-group__prepend { @apply !bg-inherit rounded-l-lg; min-height: inherit; } input { @apply px-4 rounded-r-lg focus:!border-[var(--primary)]; min-height: inherit; } } }
/* Button */ .tk-row.actions { @apply w-full !ml-0 !mt-0; .__markdown { @apply !hidden; } .tk-preview, .tk-send, .tk-cancel { @apply border-none rounded-lg px-3 py-0 h-8 !bg-[var(--btn-regular-bg-active)] disabled:!bg-[var(--btn-regular-bg)] !text-[var(--btn-content)] disabled:!text-[#ffffffa1]; } }
/* Comment title */ .tk-comments-title { .__comments svg { @apply fill-[var(--primary)]; } }
.tk-comment { @apply border-[1px] border-[rgba(144,147,153,0.31)] p-4 rounded-2xl hover:shadow-md transition-all; .tk-action-icon svg { @apply fill-[var(--primary)]; } }
.tk-action { .tk-action-count { @apply text-[var(--btn-content)]; } }
.tk-meta { .tk-tag { @apply border-none rounded-lg text-[var(--btn-content)]; }
.tk-tag-green { @apply bg-[var(--btn-regular-bg)] dark:bg-[var(--primary)] dark:text-[var(--deep-text)]; } }
.tk-content, .tk-preview-container { a { @apply link link-underline text-[var(--primary)] font-medium; }
.tk-ruser { @apply no-underline; }
:not(pre) > code { @apply bg-[var(--inline-code-bg)] rounded-md text-[--inline-code-color] px-1 py-0.5 font-semibold; }
li{ @apply before:content-['•'] before:text-[var(--primary)]; } }
/* Replies */ .tk-replies { .tk-comment { @apply bg-[var(--page-bg)]; .tk-content { > span:first-of-type { @apply text-xs; } } } }
.twikoo .code-block { pre { @apply !rounded-xl; }
.copy-btn-icon { width: inherit !important; height: inherit !important; } }
.tk-expand-wrap .tk-expand, .tk-collapse-wrap .tk-expand { @apply hover:rounded-lg mt-1 hover:bg-[var(--btn-plain-bg-hover)]; }
/*让表情组件在表情包数量太多的时候正确显示*/ .card-base { overflow: visible;}
/* 让图片类型表情不换行显示 */.tk-content img, .tk-preview-container img { display: inline; vertical-align: bottom !important;}解决首次加载不显示
修改src/layouts/Layout.astro
// 专用于创建loadComment的事件,即通知评论组件进行一次加载function initCommentComponent() { const event = new Event("loadComment"); document.dispatchEvent(event);}// twikoo评论
function init() { // disableAnimation()() // TODO loadTheme(); loadHue(); initCustomScrollbar(); showBanner(); initCommentComponent(); // 调用initCommentComponent()函数,twikoo}
....
window.swup.hooks.on('content:replace', initCustomScrollbar) // window.swup.hooks.on('content:replace', initCustomScrollbar) window.swup.hooks.on("content:replace", () => { initCustomScrollbar(); initCommentComponent(); // 添加代码调用 }); window.swup.hooks.on('visit:start', (visit: {to: {url: string}}) => { // change banner height immediately when a link is clicked const bodyElement = document.querySelector('body')为评论区添加小标题
修改src/components/comment/Twikoo.astro
HyperCherry的代码我不知道为什么会报错,import WidgetLayout from “@components/widget/WidgetLayout.astro”;的引用没有效果.可能我是个废物吧.
---import WidgetLayout from "@components/widget/WidgetLayout.astro";import { commentConfig } from "@/config";import I18nKey from "@i18n/i18nKey";import { i18n } from "@i18n/translation";
interface Props {
...
path: Astro.props.path,};---
<WidgetLayout name={i18n(I18nKey.comments)} id="comments"><div id="tcomment"></div></WidgetLayout>
<script is:inline src="https://cdn.staticfile.org/twikoo/1.6.44/twikoo.all.min.js"></script><script is:inline define:vars={{ config }}> twikoo.init(config)解决首次加载不显示,解决评论操作会回到文章顶部
见 issue #721,Twikoo 加了一个href=”#“,这是为了防止回复按钮在某些主题(如 VuePress)下被识别为不可点击的链接而加的,不能被官方仓库删除.但是 Fuwari 正是这个href=”#“导致了问题.
解:重新编译.
Fork官方项目
仓库 Clone 到本地
全局删除href=”#”
编译出 js 文件(或vercel部署)
编译流程:
# 安装 yarn(如未安装)sudo npm install -g yarn# 安装依赖yarn install# 搜索并删除 twikoo 源码中的 href="#"(建议用编辑器全局替换)# 比如 VS Code 搜索全项目替换为 "javascript:void(0)"或删除,我是都删除了# 编译(非腾讯云用 twikoo.min.js,全部文件输出在./dist)yarn buildvercel部署
输出目录:./dist
js文件: 域名/twikoo.min.js
修改src/components/comment/Twikoo.astro
---import WidgetLayout from "@components/widget/WidgetLayout.astro";import I18nKey from "@i18n/i18nKey";import { i18n } from "@i18n/translation";import { commentConfig } from "@/config";
interface Props { path: string;}
const config = { ...commentConfig.twikoo, el: "#tcomment", path: Astro.props.path,};---<WidgetLayout name={i18n(I18nKey.comments)} id="comments"><div id="tcomment"></div></WidgetLayout>
<script is:inline src="https://cdn.staticfile.org/twikoo/1.6.44/twikoo.all.min.js"></script><script is:inline define:vars={{ config }}> twikoo.init(config)<script define:vars={{ config }}>function loadTwikoo() {
// 动态加载 Twikoo 脚本,并在加载完成后执行 twikoo.init
const script = document.createElement('script'); script.src = 'https://xxx/twikoo.min.js';//js文件 script.defer = true; script.onload = () => { if (window.twikoo) { window.twikoo.init(config); } }; // script.onerror = () => { // console.error('Twikoo script load failed'); // }; document.body.appendChild(script);} document.addEventListener("loadComment", loadTwikoo, { once: true }); // 监听加载评论事件,但是我们只能监听一次,从而避免多次触发.</script>Twikoo使用
昵称:显示的名称
邮箱:去Gravatar.com注册账号绑定自己的域名邮箱,在这里填Gravatar的邮箱后会显示Gravatar的头像
网址:点击之后会跳转的网址
Twikoo 管理面板
自定义通知邮件模板,自定义博主通知邮件模板用的Zokiio的.