2025-03-01 05:02:00
一眨眼也是进入了这学期的reading week. 和第一个学期的reading week相比大家都没有那么激动了, 这次就没有出门旅游, 只是简单的聚了个餐.
就像这篇博文的标题一样, 我认为这个月的主题就是悠闲.
食物方面, 从有了自己的厨房以来就没有再亏待过自己的嘴巴. 自己在家琢磨各种各样的美食. 比如下图, 按照记忆中的味道去复刻大学时候和女友吃到的土豆鸡+虾/用Instantpot去炖的猪蹄/去朋友家做的大烩菜/豉汁排骨/可乐鸡翅+虎皮蛋.
这里留一个最满意的高压锅炖猪蹄的菜谱:
我在中国超市买了2个猪蹄, 大约是8CAD, 吃了4顿. 一开始还在担心这么多的汤汁到底要浇多久的米饭才能用完, 结果好吃到仅仅4顿就连汤带肉一起消灭掉了, 一点都没有剩下.
上个月的月度小结里没有写到这个主题, 就在这里归纳一下: 本月入手了2个小玩意.
详情我写在了这篇当中, 我着重说一下使用体验. 使用场景大概是每天的通勤2h+晚上在床上看2h, 算是中等程度的使用. 新的一代据说是暖屏(没有参照物), 我习惯将色温设置在和Marginnote4的护眼色相近的10
档.
和看手机屏幕比, 体验好了不止一点, 也变相的大幅提升了我的阅读时间, 这个月看的书得超过之前5年看的书了(笑).
这是从国内邮寄过来的, 大概上年年末的时候遇到一个学长要回国, 在小红书上卖全新的白夜魔和xbox手柄, 价钱折合人民币不到1100, 刚好身边朋友需要xbox手柄, 我就一起购入了. 之后也一直没有顾得上改这个键盘(北美客制化的发展没有竞争对手去卷, 和国内比少太多配件了), 直到情人节, 女友问我要什么我选了这个.
和刚到手的声音相比, 键盘的声音更偏向于麻将音了. 我还额外买了圣熊猫的镀金卫星轴, 出乎意料的是夜魔原装的简易卫星轴的发挥全方位优于圣熊猫的卫星轴, 最后我还是换上了原装的简易卫星轴.
我在arc浏览器code分类的侧边栏根目录下保存了Umami访客统计
, 一般2~3天我都会看一下读者会从哪里访问. 最多的来源一般是V2EX, 其次是我之前在知乎上发布的一些教程, astro的官网和astro中国开发者的导航页, 再其次是google, 最后是赛博友邻的友链.
言归正传, umami可以添加一些自定义的event来方便追踪用户行为, 之前对于点赞的event只定义了一个Like
标志, 即使能看到有读者点赞了文章, 但是没有办法显示读者点赞了哪一篇文章. 现在修改为data-umami-event=${fileName}-Like
, 这样的好处是可以知道读者点赞了哪片具体的文章.
<open-heart href={`https://xxx/${currentUrl}/like`} data-umami-event=`${fileName}-Like` emoji="♥">♥</open-heart>
这个月的闲暇时间识图系统学习了一下像素画, 于是有了about
页面右下角的产物:
点击后会出现毛毛的丑照(毛毛就是我的长毛猫, 具体可以看这篇文章)
++book/4bVED3OmX1AIAOy52Yxp4W++
++book/0Qv4iGUnpdGHu9GEqpP5xh++
++book/3BWmn3mhMrqIazr5ZO3pTa++
++movie/6Bob1fCW9QcEpZoL56X16n++
++tv/6ReFpsYl0zhcWdmgiCIOoO++
++tv/7in2q2PQbOkpEcgnqr5DeP++
2025-02-12 23:02:00
曾几何时也是非常眼馋一些赛博友邻的观影页, 但是碍于没有相关的经验(懒)和Astro缺少相关的教程一直没有考虑过实现, 一开始的时候是想着这是一个动态服务, 所以可能需要考虑第三方服务来实现. 在看了几个博主是如何实现的后, 初步有了一些想法, 即可以用GitHub Action来实现. 因此, 本文所介绍的实现方式为:
如果我的描述不够清晰, 或许你可以从官方文档找到答案.
首先打开终端, 输入以下指令, client_name
随意,redirect_uris
可以填写为你的博客url再加上/callback
, website
为你的博客链接, 即前者去掉/callback
:
curl https://neodb.social/api/v1/apps \
-d client_name=MyApp \
-d redirect_uris=https://blog.asyncx.top/callback \
-d website=https://blog.asyncx.top
之后会返回如下格式的内容, 你需要留存client_id
和client_secret
供后文使用:
接着, 你需要在浏览器访问如下的网页链接, 将
[CLIENT_ID]
和[REDIRECT_URI]
替换成你的输入即可:
https://neodb.social/oauth/authorize?response_type=code&client_id=[CLIENT_ID]&redirect_uri=[REDIRECT_URI]&scope=read+write
如果没有问题则会弹出这样的图片, 点击Allow即可, 接着你会跳转你自己的网页, 在浏览器的链接栏你可以看到生成的code
.
接着,使用以下指令来生成Token,其中新获得的code也需填写于其中:
curl https://neodb.social/oauth/token \
-d "client_id=CLIENT_ID" \
-d "client_secret=CLIENT_SECRET" \
-d "code=AUTH_CODE" \
-d "redirect_uri=https://example.org/callback" \
-d "grant_type=authorization_code"
生成Token这步, 我会报错
access denied
, 但我没有发现任何导致出现错误的问题, 如果有读者发现麻烦留言, 我会同步更新博文. 因此这步后我使用了测试Token. 生成的链接位于https://neodb.social/developer/ 点击Test Access Token
即可生成.
在获得并存储了Token后, 接下来进入Github Action的设置中.
首先创建一个新的GitHub存储库(我创建新库的原因是防止每天定时的更新会让本地的Obsidian频繁拉取更改/让历史记录更清晰), 点击Setting-Security(Secrets and variables)-Action-New repository secret
, 将生成的Token填进去, Name
为NEODB_ACCESS_TOKEN
接下来点击
Actions-Newworkflow
, 复制下面的代码到新建的.yml
文件中
name: Sync NeoDB Data
# 允许 GitHub Actions 拥有写入仓库的权限
permissions:
contents: write
on:
schedule:
- cron: "0 17 * * *"
workflow_dispatch:
jobs:
neodb_sync:
name: Sync NeoDB Data for multiple categories
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Check JQ
run: |
if ! command -v jq &> /dev/null; then
echo "jq is not installed. Installing..."
sudo apt-get update
sudo apt-get install -y jq
else
echo "jq is already installed."
fi
echo "WORK_DIR=$(pwd)" >> $GITHUB_ENV
- name: Ensure local JSON files exist
run: |
# 定义需要同步的分类(移除 album)
categories=("book" "movie" "tv" "game")
mkdir -p data/neodb
for category in "${categories[@]}"; do
local_file="data/neodb/${category}.json"
if [ ! -f "$local_file" ]; then
echo "Creating default JSON for category: $category"
echo '{"data": [], "pages": 0, "count": 0}' > "$local_file"
fi
done
- name: Sync Categories Data
run: |
# 定义需要同步的分类(移除 album)
categories=("book" "movie" "tv" "game")
UPDATED=0
for category in "${categories[@]}"; do
echo "Processing category: $category"
# 下载该分类第一页数据,用于获取 count 和 pages
curl -s -X GET "https://neodb.social/api/me/shelf/complete?category=${category}&page=1" \
-H "accept: application/json" \
-H "Authorization: Bearer ${{ secrets.NEODB_ACCESS_TOKEN }}" \
-o "${category}1.json"
# 提取远程数据的 count 和 pages, 如果为 null 则设为 0
remote_count=$(jq '.count // 0' "${category}1.json")
pages=$(jq '.pages // 0' "${category}1.json")
echo "Remote count for ${category}: $remote_count, pages: $pages"
# 读取本地数据的 count
local_file="data/neodb/${category}.json"
local_count=$(jq '.count // 0' "$local_file")
echo "Local count for ${category}: $local_count"
# 对比远程和本地的 count 数值,若一致则跳过下载
if [ "$remote_count" -eq "$local_count" ]; then
echo "No update for ${category}. Skipping download."
continue
else
echo "Update detected for ${category}. Downloading all pages..."
UPDATED=1
# 为当前分类创建临时目录存储下载数据
mkdir -p "neodb/${category}"
if [ "$pages" -gt 0 ]; then
# 循环下载所有页数据
for ((i=1; i<=pages; i++)); do
echo "Downloading ${category} page $i"
curl -s -X GET "https://neodb.social/api/me/shelf/complete?category=${category}&page=$i" \
-H "accept: application/json" \
-H "Authorization: Bearer ${{ secrets.NEODB_ACCESS_TOKEN }}" \
-o "neodb/${category}/${category}${i}.json"
done
# 利用 jq 合并所有页面数据为一个 JSON 文件
jq -c -s '{
data: map(.data[]) | unique | sort_by(.created_time) | reverse,
pages: (map(.pages)[0]),
count: (map(.count)[0])
}' neodb/${category}/*.json > "${category}.json"
else
# 如果 pages 为 0,则创建默认空数据文件
echo '{"data": [], "pages": 0, "count": 0}' > "${category}.json"
fi
# 确保目标目录存在,然后将合并后的 JSON 文件复制过去
mkdir -p data/neodb
cp -f "${category}.json" "data/neodb/${category}.json"
fi
done
# 如果所有分类均未更新,则退出工作流
if [ $UPDATED -eq 0 ]; then
echo "No categories updated. Exiting."
exit 0
fi
- name: Git Add and Commit
uses: EndBug/add-and-commit@v9
with:
message: 'chore(data): update neodb data for multiple categories'
add: './data/neodb'
点击提交, 接下来你需要再次进入Actions
并手动Run一下, 不出意外你就可以看到新生成的json文件了.
到这一步, 你已经存储了NeoDB的数据, 接下来就是前端工作了.
到了这一步我全权交给了ChatGPT, 由于展示的内容实在很多, 我在尝试了几个想法发现效果不理想后, 最终确定的内容为:
我在博客的页面目录/pages
下创建了新的路径文件/bmmg/index.astro
, 这样最终的访问url为https://blog.asyncx.top/bmmg
. 对于下面的代码来说, 你需要手动修改一下自定义域名后的json文件url.以及由于我使用了TailwindCSS, 你需要让GPT修改其样式为普通的CSS
---
import Layout from "../../layouts/Layout.astro";
// 定义各分类对应的 JSON 文件地址
const jsonUrls = {
movie: "https://neodb.asyncx.top/data/neodb/movie.json",
tv: "https://neodb.asyncx.top/data/neodb/tv.json",
game: "https://neodb.asyncx.top/data/neodb/game.json",
book: "https://neodb.asyncx.top/data/neodb/book.json"
};
// 定义分类中文显示名称
const categoryMap = {
movie: "影",
tv: "剧",
game: "游",
book: "书"
};
// 用于存储各分类的所有数据(不做时间过滤,取最新20条)
const grouped = {};
// 用于存储合并后的数据(仅包含过去3个月内的记录)
let mergedRecentItems = [];
// 计算当前日期三个月前的日期
const now = new Date();
const threeMonthsAgo = new Date();
threeMonthsAgo.setMonth(now.getMonth() - 3);
// 动态读取各 JSON 文件
await Promise.all(
Object.entries(jsonUrls).map(async ([cat, url]) => {
const res = await fetch(url);
const jsonData = await res.json();
// 对该分类所有数据按创建时间降序排序(不做时间过滤)
const sortedAll = jsonData.data.sort(
(a, b) => new Date(b.created_time) - new Date(a.created_time)
);
// 分类展示:取前20条,并附加所属分类信息
grouped[cat] = sortedAll.slice(0, 20).map(item => ({ ...item, category: cat }));
// 合并展示:过滤出过去三个月内的记录,并附加所属分类信息
const filteredRecent = jsonData.data.filter(
(item) => new Date(item.created_time) >= threeMonthsAgo
).map(item => ({ ...item, category: cat }));
mergedRecentItems = mergedRecentItems.concat(filteredRecent);
})
);
// 对合并后的所有数据按创建时间降序排序,并取前20条
mergedRecentItems.sort((a, b) => new Date(b.created_time) - new Date(a.created_time));
mergedRecentItems = mergedRecentItems.slice(0, 20);
// 定义生成跳转链接的函数
const getLink = (entry) => {
if (entry.category === "movie") {
// 对于电影,点击跳转到固定的电影 JSON 文件地址
return jsonUrls.movie;
} else {
// 对于其它分类,构造链接为:https://neodb.social/{分类}/{uuid}
return `https://neodb.social/${entry.category}/${entry.item.uuid}`;
}
};
---
<Layout title="NeoDB" description="NeoDB">
<div class="container mx-auto py-8">
<h1 class="text-3xl font-bold mb-6">最近看/玩了什么</h1>
<!-- <p class="text-gray-500 mb-6">
上半部分展示过去3个月内的全部记录,下半部分按分类展示各自最新的20条数据。
</p> -->
<!-- 全部展示部分:仅展示过去3个月内的记录 -->
<section class="mb-8">
<!-- <h2 class="text-2xl font-semibold mb-4">全部</h2> -->
{mergedRecentItems && mergedRecentItems.length > 0 ? (
<div class="grid grid-cols-2 md:grid-cols-5 gap-3">
{mergedRecentItems.map((entry) => (
<a href={getLink(entry)} class="block">
<div class="border rounded overflow-hidden shadow hover:shadow-lg transition-shadow">
<img
src={entry.item.cover_image_url}
alt={entry.item.title}
loading="lazy"
class="w-full h-48 object-cover"
/>
</div>
<p class="mt-2 text-sm font-bold text-center truncate">
{entry.item.title}
</p>
</a>
))}
</div>
) : (
<p class="text-gray-500">暂无数据</p>
)}
</section>
<hr class="my-8" />
<!-- 分类展示部分:各分类显示最新20条数据,不限制时间 -->
{Object.keys(jsonUrls).map((cat) => (
<section class="mb-12">
<h1 class="text-2xl font-semibold mb-4">{categoryMap[cat]}</h1>
{grouped[cat] && grouped[cat].length > 0 ? (
<div class="grid grid-cols-2 md:grid-cols-5 gap-3">
{grouped[cat].map((entry) => (
<a href={getLink(entry)} class="block">
<div class="border rounded overflow-hidden shadow hover:shadow-lg transition-shadow">
<img
src={entry.item.cover_image_url}
alt={entry.item.title}
loading="lazy"
class="w-full h-48 object-cover"
/>
</div>
<p class="mt-2 text-sm font-bold text-center truncate">
{entry.item.title}
</p>
</a>
))}
</div>
) : (
<p class="text-gray-500">暂无数据</p>
)}
</section>
))}
</div>
</Layout>
将数据存储在本地的好处是不用担心日后哪天失效, 倘若失效还有数据可以展示(笑). 如果我有描述不清晰的地方, 请尽情评论, 我会将没讲清楚的地方更新在文中.
2025-02-07 07:02:00
魁省进入雪天也有很长一段时间了, 每次回家都被风雪吹得狼狈不堪, 这对一个从小在国内中原地区长大的人还是很有冲击力的... 本月的生活还是比较充实的.
尽管在美国读书的朋友一再劝我选容易通过的简单课程, 但是受制于必修课的选择, 我还是选择了一门对我来说颇有难度的Java编程课. 这门课程每周会有一个实验课需要强制出席, 每次需要解决两道算是LeetCode的easy难度的算法题, 这对大学本科几乎没有动手从0开始写java代码的我很是头大. 不过固定的考查模式让我上手很快, 时至今日的第三次实验课我已经可以全部完成.
生活上简简单单, 我也一贯坚持着什么都能苦, 就是不能苦我的嘴的观点在努力干饭. 我也在我的文字性内容归档站更新了Instantpot食谱. 用来记录一些可以用高压锅省心完成的饭. 由于过年的时候是周二, 我们几个中国留学生朋友都是满课, 于是我们提前到了周末, 聚在一起吃了顿年夜饭, 我也是掏出了逢年必做的烤鸡.
由于经常下雪的缘故, 我也经常开车, 从国内没上过几次高速的新手也变成了现在倒车入库比较在行的"中手"了.
这个月算得上是井喷式更新了:
此外我对博客的样式也一直在进行微调,例如将<h1>
设置为了渐变的彩色, 为最近做什么和友链单独创建了页面, 这里立一个从2024年传过来的flag: 添加多图拼接功能.
2025-02-06 07:02:00
前些天购入了Kindle Paperwhite 12th 32G signature的版本. 其实是没有什么动机的, 只是联想到每天的通勤时间可能长达2h(因为住的离学校远, 需要大量的公共交通时间), 自习思索了一番, 认为可以购入一个Kindle来打发时间. 原计划是购入普通版本, 但是家附近的Bestbbuy已经没有普通版(16G版本), 考虑到我会用来看漫画和长期使用, 索性购入了一个32G的版本. (由于我在国内还有一个Paperwhite3, 本文可能会用两者进行对比.) 使用了几天, 打算写一篇文章记录在使用过程中遇到的一些细节.
不知道是否是签名版的缘故, 我到手后没有广告之类的选项, 所以省略了网上关闭广告的步骤. Paperwhite6相比前代5, 根据网上博主测评, 所谓的翻页速度提高可能只是翻页时间从0.3s到了0.25s(无法取证). 但相比于我之前的3带, 这个从左到右过渡动画着实让我欣喜.
在之前的系统版本中, Kindle已经允许用户自己导入喜欢的字体. 但官网所说我这代没有办法使用macos读取, 你只需要下载你喜欢的字体, 然后用数据线连接到Windows系统的电脑, 打开Kindle的fonts文件夹放入即可.
关于资源, 我的获取途径并不固定, 具体是如下2类.
用Google搜索的格式是书籍名 + 格式
. 例如我最近下载了特德·姜的<呼吸>
, 我只需要搜索 呼吸 epub
. 或对这个资源进一步做出过滤:呼吸 特德姜 epub
. 此外, 我还会看一些小说, 但是上述的几种途径都没有办法搜索, 因此这里我推荐一种新的办法: 在微信中直接搜索小说的名字即可, 有相当一部分公众号会提供.txt
格式的文件下载, 这样的格式需要经过处理才可以用Kindle阅读, 因此延伸出下个部分.
我使用到的工具只有Calibre. 这个软件可以让你在电脑上高效的处理电子书的一些格式.
软件具体的使用我不赘述, 你可以在网络上查找相关教程, 这里我对一些在网上难以搜索到的教程/用法做出一些讲解, 顺序为:
作者+书名 ---<更多资源:xxx.com>
等情况), 你需要编辑并推送.除了使用数据线将kindle连接到电脑, 你还可以打开Calibre的邮件推送. 具体位置位于设置-分享-以电子邮件分享书本
接下来你需要做:
找到kindle的电子邮箱后, 你需要填写到下图红框的位置处. 将格式修改为EPUB(加上mobi似乎也是可以的.)
接下来就是添加calibre的发送邮箱, 即SMTP服务, 如果你有添加邮箱到第三方邮箱客户端的经验, 只需要填写下方的相关内容, 并点击测试电子邮件
即可. 如果没有你可以在这篇文章看到更详细的配置.
当你完成后, Calibre就可以向你的Kindle正常的推送书籍了, 但是这里会出现书籍的名称和作者被转换为拼音的情况, 因此你需要一个额外的插件来处理.
如何解决 Calibre 推送中文书到 Kindle 显示拼音书名问题 参照这篇文章, 你可以很快的解决问题.
假如你在网上找到了一些被网站二次编辑元数据的电子书, 你可以将电子书拖入calibre, 并且右键你想要修改的书籍, 如下操作:
你可以很直观的看到和修改这个电子书的所有数据.
接下来讲一下如果你下载了txt格式的电子书你需要如何做. 在导入calibre后, 你可以直接转换其格式, 也可以为其添加大纲. 点击左上的转换书本-结构探测
, 你需要根据txt文件的目录来修改这个Xpath表达式. 我这里提供一个几乎通用的表达式, 它会读取所有开头为第X章/卷/节... XXX
的内容. 我建议你配合GPT来对当前的txt电子书进行修改.
//*[re:test(., "^\s*[第卷][0123456789一二三四五六七八九十零〇百千两]*[章回部节集卷].*", "i")]
上一个kindle是我在中学时候偷偷买的, 在我的印象里我没有过多的去折腾它, 只是去使用. 它也高强度(直到我偷偷买了手机)的陪伴了我2年.
如果评价当时的阅读体验, 我会说很棒, 用它我看完了老生常谈的基地/沙丘/..., 也看了武·科瓦奇/菲利普·迪克/恩斯特·克莱恩等人所写的数不清的科幻作品. 但它最后也难逃吃灰的下场(碎片化的手机视频app,老式接口和不耐用的电池). 但是如果问我值得现在再买一个吗, 我肯定会心疼, 但会说值得.
2025-01-18 20:01:00
前日晚, 和汪哥聊起了搜索优化问题. 因为我经常折腾, 所以我修起这些问题来能比较快的定位到问题所在, 他问到我是如何掌握这些知识的. 我用流水账般的语言讲了从大学开始折腾的过程, 在某段时间做了什么, 在某段时间又做了什么. 乍一听起来就是一个学习的过程, 其内容就像是在某年某月学了什么, 会了什么. 这样讲出来, 旁人看起来一定是会说一句"我*, 👍", 仿佛你是一个轻松获得胜利的天才, 但实际上你可能在时候淡化了你当时的努力.
汪哥用了一个简单的例子说明了这点:
经历的事情,就像是在拾柴火,在拾的过程中根本不知道什么时候会点火,不知道拾了有啥用,就是闷着头拾就行了。等到某个时间点,得到了一个火种,这时候才发现这火种恰巧可以点着柴火,这时候才会对以前拾的柴火觉得有意义。
讲到这里的时候让我霍然开朗, 这在逻辑上来讲可以形成自洽. 当你积累(柴)了足够多, 在某一天你的灵感迸发(点火)了, 完成了某个目标, 而不是说你能在没有任何理论基础的情况下无师自通, 并且能知行合一的学以致用, 天才也不行.
那么用这个例子套入传授知识的过程, 我们的侧重点应该放在在有清晰理论的基础下进行引导. 也就是提供上等木柴的同时递给学生打火机. 在我国分数为王的教育体系里, 像学这些东西有什么用?能用来做什么
这样的声音已经被淹没了, 鲜有老师可以做到上面这点. 下面从教学体系上来讲解: 每个学校教授的内容是固定的, 那么如何避免不同的老师在授课内容上有偏差? 这就发明了教学大纲, 一些厉害的老师们将自己的毕生所学填充进去, 所有的老师再去进行雕琢完善, 就成为了一个包含所有老师智慧结晶的产物, 接下来就是围绕着大纲备课, 传授. 这一点无论是放在国内还是放在国外都是一样的.
话再说回来, 为什么经常会有人唾弃国内的教学体系? 套用上述例子, 个人拙见是老师尽心尽力的把优质木柴塞给了你, 却没有交给你点火的手段. 你知道这是木柴, 却不知道要如何点火. 那么会有人说, 我会做题了不就是会点火了吗. 你有了答题思路, 只会在同样的问题上不丢分, 换了问题照样会有大部分的人做错. 为什么说是大部分? 是因为对于小部分人来说, 他已经有了火种, 故而能触类旁通
. 因此, 一问一答看似解惑, 实则仍然属于传道授业的范畴.
在我的上一学期, 有一门课业比较繁重, 课程叫做Natural Language Processing(NLP/自然语言处理) 这门课程是一位风趣的女教授, 这是她时隔十几年来重新开设这门课程, 从基础的朴素贝叶斯讲起, 到最后的Transformer架构(GPT2/GPT3的底层架构)循序渐进娓娓道来. 我认为她的课程略显枯燥, 但是作业的质量极高. 总共3个作业参与评分, 每个占15%, 内容为一个.ipynb
项目文件+一个report. 项目文件会提供传入传出参数的注释, 你需要完成封装的逻辑, 使用的训练数据库都是目前最新or最权威的, 在完成项目文件后你需要完成2个Experiment, 例如修改参数/更换训练数据库等. 并且要将你Experiment写在report中. 我的作业1的report有些老实, 要求6页我就写了6页, 最终得分为71/100🤦♂️. 在确定老师所喜欢的论点后我的后面2个作业分数为100/100. 所有的report都拿到了满分, 例如如果有2份数据集的比较相差过大怎么办?(在作业3中使用了Transformer来实现英语和法语的翻译, 数据集的大小相差几十倍) 我用Python爬取了2份数据集的相关词汇的占比, 结果为占比类似, 因此这2份数据集参数比较仍然有相同点以供分析. 在这门课程中, 你获得的柴火可以在作业中点燃, 并且你在上一个作业的的report撰写方案仍然可以被优化, 应用到下一篇的分析中. 你的角度会越来越刁钻, 越来越专业.
这是我的缺点, 我在完成阶段性任务后往往选择归档搁置. 不会回过头来吸收这段过程中有用的地方, 因此如果和别人聊起来我在这段时间做了哪些努力, 学习了哪些内容, 我往往会一笔带过, 没能给大家提供有用的帮助. 所以在完成任务后复盘, 哪怕是撰写一份大纲进行留存也是一个进步.
2025-01-17 05:01:00
很多时候, 写前端是一个不怎么用脑力参与的事情. 你已经知道了它的基本原理, 你的键盘就在手前, 想到什么功能只需要去用那个逻辑实现就可以了. 刚好昨天实现了拖沓很久的openheart, 翻看之前的博客感觉有些冗杂, 虽然核心功能就那么多, 但在观感和页面加载速度上有些问题. 干脆一不做二不休的重新写一个. 存储库覆盖了原先的主题, 仍然位于A5yncX/DG
之前偶然在github闲逛发现了我现在个人主页的template, 于是打算新的主题贯彻那种风格, 找了找发现没找到, 于是打算基于Astro官网模板的Miniblog进行了二次开发. 说是二次开发, 其实大改了一翻(笑. 移除了更多的无关元素, 专注于写作本身, 于是有了现在这个主题, 我命名为Marius
. 没什么含义, 可能会作为日后我的英文名.
相信很大一部分人喜欢极简主义, 其实在我的上个博客中我也在做一个尝试, 同时顾及视觉的繁复和极简, 我认为对比色和干净的界面元素是一个很好的主意, 于是使用了#9bdbee
和#ffb300
作为对比色----没错, 灵感依旧来源于电影<TRON:Legacy>
.
现在看来尝试的结果是褒贬不一的, 但是新博客的内测用户: 汪哥(没错他有了博客)给出了很鼓舞的评价:
言归正传, 年末时分由于频繁的出入Benji的
OpenHeart
博文, 于是发现了很多具有时效性的小彩蛋. 例如你会在他的blog的黑色背景中发现白色小点, 在你点击后所有具有超链接属性的文字会五颜六色, 又例如在圣诞节前后, 如果在他的网站滞留时间过长, 你的屏幕则会被大雪所填满, 你需要点击联系铲雪公司的按钮来清理掉所有的积雪. 我认为这是为博客添加特色的一个完美方案. 在上个博客中可能会有部分读者发现当访问主页的时候会出现随机的特效, 例如宇宙,又或者是彩色马赛克格. 这也是我的一个简单尝试, 但我看了访问统计的后端后发现鲜有人会呆在主页观看. 所以我打算将此类功能作为一个简单的TODO, 即添加一些彩蛋来奖励长时间留在blog中的读者.
大部分还是和上个博客的功能一样, 由于Astro的性质, markdown的渲染可以加入自建的remark/rehype.js
文件, 因此现在参与博客渲染的功能有状态bar/图注...etc. 此外就是使用markdown-it
的解析全文的rss, 以及让代码框功能更多的expressive-code
, 本地搜索Pagefind
, pagefind的css被集成在了其他地方, 考虑到双色浏览的可用性我用!important
覆盖了原先的颜色. 还有最最重要的就是终于填了2年前用TailwindCSS
的坑, 由于MiniBlog是用的TailwindCSS, 我被迫简单学习了一下, 真的很好用. .css
的行数从原博客的620行变成了现在的184行, 是一个不小的进步.
今天仔细的看了一下Astro的内容集合
, 也想明白了之前试图将博文分为中文和英文的困难之处, 新的主题将参与页面搭建的.md
归档在pages
集合, 而同时posts
集合又负责存储所有的博文, 这意味着我之后可以在Obsidian中编辑很大一部分页面的信息, 这对于时效性的内容, 例如最近在做的事/节日快乐等消息可以更快更简单的编辑.
我在写新的主题的时候尽可能的去顾及读者的观感.(btw, 实际发现我的blog可能并不会有外国有人读, 因此我取消了国际化功能. 考虑到rss不能变动, 所以订阅链接依旧为blog.asyncx.top/zh.xml
).此外, 也取消了博文置顶和友链的单独分类. 一个存在于Header中的README.md
栏对于专业性的读者/其他博主会有更强的吸引力.
虽然不是很懂所谓的冥想
, 但是像这样不分昼夜的去雕琢前端的细节对我来说是很能静下心的. 这断断续续的十几个小时能让我清空大脑是很值得的.
关于新的一年的展望其实有很多, 与自己和解/完全入门法语/多做,多尝试一些事情, 让未来的自己不后悔.
就是这样了, 新的一年, 新的博客, 加油💪