Normal view

There are new articles available, click to refresh the page.
Before yesterdayMain stream

世界读书日

By: 河石子
23 April 2024 at 21:44

【看看你读书达标了吗?#重庆成年居民人均阅读纸质图书4.2本#】4月17日上午,重庆解放碑,2024巴渝书市在十字金街正式开幕。开幕式上,《重庆市2023年全民阅读指数评估调查报告》(以下简称报告)发布。报告显示,2023年,重庆市成年居民人均阅读纸质图书4.2本,电子图书5.3本,听有声书3.6本,平均阅读量为4.76本。成年居民日均综合阅读时长为39.8分钟,较2021年增长1.8分钟。重庆市青少年群体日均课外阅读时间33.71分钟。重庆青少年最爱的三本书分别是《稻草人》《昆虫记》《小王子》。#2023年你读了几本书#?

这是微博前两天给我推送的消息,随手将其记录在了记事本里,感觉我可以就这个话题说点什么,今天据说是“世界读书日”(准确的说 4 月 23 日应该是“世界图书与版权日”),正好可以就这个话题聊一聊。

虽然不知道微博推送的这个统计数据是怎么来的,但可以肯定的是现在看书的人越来越少了,即便身边有人看书都是通过手机看书软件或者听书的方式来进行阅读,且很少听说在日常生活中有人讨论读书的话题。

大约十年前我还是很喜欢读书的,为此博客甚至还有一个分类叫作“阅读与光影”,目的就是为了来记录自己认真阅读过的书,到现在这个分类不知道已经荒废了多久了。

前些年通过订阅中国移动和中信出版社合作的咪咕中信悦读会员,每个月 48 元的话费有一张兑书券以及全场正版电子书免费读,但现实就是电子书一本都没读完过,纸质书虽然每个月都在兑换,都积攒了两个小书架了,大多数大现在连塑料薄膜都没有撕掉就放书架上吃灰了。

现在总是为自己没有读书找来各种的借口,平时不管是看长视频短视频都有时间,但就是找不出读书的时间。许久不读书的坏处就是现在博客都不会写了,甚至不能用一段文笔通顺的话来表达自己心中所想的事情。

2017 年 1 月 18 日的时候在 iPhone 的备忘录里写下了 “书店之死”的标题,并且理了个提纲想聊聊书店逐渐消亡的事情,因为当时看到镇上的新华书店变成了一个卖铁锅的铺子,除此之外还有两三个旧书店也早已物是人非,为什么我记得这么清楚,因为我们小镇只有一条街,而且是从小生活的地方。

后来到县上学的时候城里有一个大大的新华书店,还有一个位于大同街的“大同书店”,其它的小的旧书店还有不少。后来新华书店渐渐的开始卖学习机,音乐CD之类的,等我上大学第一个暑假回县里的时候新华书店已经改造成了一个大型的商场了,唯一能证明新华书店存在过的痕迹就只剩下一个叫新华书店的公交站名了。

余华书中文革结束后要凭书票通宵排队购书的情景是无法再现了,现在排队都是为了电子产品为了自己的爱豆。

以上,争取 2024 读书数量超过重庆人的平均数。

您也许会感兴趣:

  • 暂无相关文章:

新年快乐2023

By: 河石子
31 December 2022 at 22:42

最后一次新年不快乐系列停留在了 2018 年 1 月,以前每年都是从读书、电影、网络、生活这四个方面来总结过去的一年。那时候还是一个人得过且过的活着,在这五年里经历了失业、抑郁、结婚、生子等自己未曾想过的事情,自诩是一个要活得洒脱不做一个让自己讨厌的人终究还是没有逃过一般人的俗套生活。

不过选择了这样的生活,无论是主动还是被动的都应该好好的面对,所以从今年开始这个系列将会改为新年快乐系列,生活无外乎生理和精神需求。对我来精神方面的需求也就阅读影音互联网这一块的东西了。

阅读方面

已经很久没好好的度过一本书了,虽然有一些碎片时间,但是要好好的读一本书真的是需要静下心来的认真的阅读才能品味其中的精彩之处。但是因为工作孩子的关系,已经沉不下心来认真的读完一本书了,疫情期间也只是浅浅的阅读了一套《福尔摩斯探案全集》这种仅需要浅阅读的术。通过咪咕中信书城白嫖来的纸质书已经堆满了一个小书架了,2023 年应该把这些东西看起来,好的作品应该拿来品鉴而不是用来装饰。

影音方面

2022 这一年来因为收到疫情的影响似乎都没有什么值得一看的电影,除了漫威系列之外就没看过其它的外文电影,国产电影就只看过《独行月球》这一步电影,因为看得少因此电影时间系列也没有更新过了。

最主要的原因还是因为短视频时代太多的三分钟看完一部剧这样的内容,很容易就让自己了解一部电影或一部剧的大概剧情,除非内容口碑很好的剧之外已经很难让我再认真的的静下心来看一部两小时时常的电影了。试问大家有多久不是用 1.5 倍速以上的速度认真的看完一部电影了。

博客方面

写得少的原因不是因为忙,也不是因为没有想写的点子,而是因为懒,而且现在大家都不怎写了。前段时间整理了下 Feedly 的订阅,原来订阅了 150 个左右的独立博客,整理的时候发现半数以上要么是订阅失效网站打不开了,要么就是长达半年以上没有更新的。

上网方面

一直以来都是自建 shadowsocks-libev 节点作为突破国内防火墙的工具,前两年时常在网上看到大家都说自己的 IP 又被封了这样的贴子,往年自己倒是从来没有遇到过。但是 2022 年从五月底开始自己 VPS 的  IP 用原来的方式来翻墙用不了几天就被封i掉了,症状就是全球除了国内都还能 ping 通。换了几次 IP 之后就懒得折腾了,直接用上了所谓的”机场“服务,省事省心,主要还是没有激情去折腾新的方式新的协议这些东西了。

生活方面

从 2020 年以来就已经结束了那种得过且过,勉强活着的生活状态了。这五年里结了婚、买了车/车位、生了娃、骑上了信心心念念的小摩托等等,总之一切都在向着好的方面发展。这一切都要感谢家人以及个别好朋友对我的帮助,虽然是不是的还是有轻微的抑郁焦虑症状,但是总体来说都还能克服生活所带来的不如意。至少自己现在想吃点什么买点什么不用像以前那么局促。

以上,新年快乐。明年见。

您也许会感兴趣:

在平台之外,留一片属于自己的空间:读 Be A Property Owner And Not A Renter On The Internet 一文有感

By: Justin
20 April 2025 at 11:33

文章讨论了互联网平台的集中化带来的问题,如用户被锁定和内容控制权的丧失。建议用户成为“房东”,拥有自己的域名和服务器,建立个人网站,维护自我内容的独立性。强调真正拥有数字资产的重要性,以实现自由和灵活性。

在平台之外,留一片属于自己的空间:读 Be A Property Owner And Not A Renter On The Internet 一文有感最先出现在Justin写字的地方

再小的个体也要建立自己的个人品牌

25 March 2025 at 00:00

土木坛子

某日听我朋友也是前同事讲,他说他身边至少有4个朋友在我的影响下,开始了写公众号,包括他自己。这倒是我没有想到的。

实际上,我已经很多次和别人讲——尤其是年轻人,建议开启自己的自媒体。正如微信公众号的官网有这样的一句话,“再小的个体,也有自己的品牌”。再小的个体也要建立自己的个人品牌,用现在时髦的话来讲就是:个人IP。

严格意义上来讲,我是从2006年开始写博客日志,到如今差不多20年了。这么多年的经历下来,这件事对我的受益或许是最大的。这么多年来,我分享记录自己的经历,这么多年的所想、所思、所见和所得,一切都是随性分享,愉悦自己,甚至也没想到给别人带来什么用处。

但是,当一个人在自己小众的范围内去研究,只要做得比别人好——哪怕好那么一点点,你的能力会得到增长,认知会提升,你分享的东西会被别人看见,当实现了这些之后,赚钱的事情也就自然水到渠成了——如果你有需要的话,财富本来就是对认知的变现,否则有了也守不住。

你的公司可能会裁掉你,甚至它自身也可能会倒闭,但是你的创作内容和创作能力永远属于你自己,这是你的个人主权。你分享自己的见解,锻炼了自己的能力,而这些原创内容在不同平台传播的边际成本很低,并且它会随着时间不断地被重复,不断地被扩散,不断地被人看见,假以时日会产生复利的作用,产生飞轮效应。

这就是我作为一个写了近20年博客文章的人的真切感受,它带给了我超乎想象的收获,而很多人都不知道或者相信自媒体的魔力,更没有去认真执行。

使用自己的域名

By: dimlau
9 December 2024 at 12:08

在 RSS 阅读器里读到一篇介绍「博主」的文章,点开链接跳转到了一篇微信公众号里的文章,从头翻到尾也没有发现作者的博客链接。我不确定只在微信公众号里写文章能不能被称为博主,我是说,其实妳做不了主,不是吗?被删除、被禁止关注、被封禁……妳可能觉得这些事情不会落在自己头上,但是比这些措施更温和地排挤和压制,时刻都发生在妳身上,总之妳要写它们希望妳写的内容才能在那里生存。这就是为什么我永远鼓励还在写文章的朋友们把文字存放到自己可以掌管的空间。

自建博客的确有不少困难需要克服,甚至有时会影响妳写作的心情。那就选择一个给妳足够多自主权的服务提供商,在妳想要迁移时可以不受阻碍地导出自己的数据。所以,不管是自建博客,还是使用现有服务,拥有一个自己的域名吧,这样就算是更换服务商,妳的读者依然可以通过妳自己的域名找到妳。

fin.

博客二十年

By: dimlau
22 November 2024 at 12:55

不准确,但差不多。我还是在 RSS 阅读器里接连看到几篇「写博客 X 周年」的文章才想起自己写博客有二十年了——转瞬即逝。我写第一篇博客文章大概是在 2004 年 5、6 月份,初时无从下笔,便把动画课拉片时看的一部短片改编成了两段小故事。但是后来几次更换域名、服务器,导出、导入的时候有些损失,加之每次做这种搬迁的工作难免要回顾旧文,看了感觉羞耻的古早文章也删掉了一部分。现在难说有没有后悔的情绪,不过应该不会再做这种事了。完全不是不舍得再删,其实全部归零也无妨,只不过,删删减减,像是还在修补颜料早就干裂的自画像。

扯远了,但不算跑题。写博客当然是一种写作,不管是像我这样写自己想些什么、做些什么,还是写技术博客记录心得、制作教程。写作总归会让写作者从日常不自觉的行为和思考模式里跳出来,去和读者对话,哪怕读者就只有自己。妳会用写作,尝试着和读者沟通,挑战她也好、说服她也好……就连哪些留哪些删,这个动作,或者决定全然不删,这种态度,其实也都是沟通的一部分。或许正是二十年里的无数次和自己的沟通,让我接受了曾经的自己,找到了想成为的自己。

fin.

热力图

By: dimlau
6 November 2024 at 14:43

文章更新热力图

类似的热力图,我最早是在 GitHub 看到的,用来展示开发者的更新频率。现在看到不少博客也做了这种小组件:就是从当前日期向前追溯一年,每一天显示成一个灰色的小方块,如果当天有文章发布,就显示成浅绿色,如果当天发布的文章不止一篇,就显示成深绿色。我想了一下,用 Hugo 的模版系统,加上一点 CSS 做布局和显示优化,应该就能实现,动手试了一下,果然效果还算可以。目前可以在首页看到实际演示。

fin.

这18年土木坛子博主在关注什么领域和话题?

3 June 2024 at 00:00

ZEN

土木坛子从2006年开博至今,共撰写了1633篇博文。这么多年来,我的关注领域较多,以至于我自己都不清楚到底关注了哪些领域和话题,因为我的总体思路就是记录和分享自己的所见所想所闻。

借助AI,我把这1633篇博文的标题生成纯文本文档喂给AI(庆幸没有什么标题党),让其提炼出最主要的关键词。以下是AI给我的答案。

  1. Bitcoin:多次提到关于BTC的投资、价值、使用及加密货币相关经验。
  2. 博客:涉及博客写作原则、广告技巧、优化访问速度等。
  3. 互联网:讨论互联网内容、免费服务、网络安全等。
  4. 金融:涉及去中心化金融、货币贬值、财富管理等。
  5. 科技:包括如何建立网站、云存储、硬件钱包等。
  6. 生活:谈论旅游安全、餐饮体验、家庭生活等。
  7. 教育:涉及中文学校、比利时的教育经验等。
  8. 健康:涉及医疗保障、免费医疗、体检等。
  9. 文化:包括书籍读后感、诗词、各国文化比较等。

这些关键词涵盖了文章的主要内容和主题,反映了作者关注的多个领域和话题。

我看了以上结论,基本认同AI对土木坛子关注点的分析。虽然我的关注领域和话题在这18年间比较广泛,但我还是有所聚焦:阅读、写作、投资——精神思想层面的输入、输出和物质层面上解决温饱的赚钱。不弃微末,久久为功。我体验到了持之以恒带来的力量和收获。

顺便说一句,要不是AI的强大,我自己都无法如此了解自己。

输出是一种排泄

By: Steven
20 May 2024 at 21:13

在不同的平台上时不常的都能看到一些内容创作者他们会有疑问,说我的东西明明很有深度,准备得也很充分,制作也很用心,但是为什么没有获得很好的流量,或者其他的回报?这种时候要么就是真的有疑问,要么就是想通过这种疑问的方式,来表达对于这种流量的不满或者鄙视。

每次看到他们说这种话的时候,我就会代入到自己。我也有很多内容是花了很多心思很认真做的,但就是没有什么人看,没有什么人听。前几年确实会有疑惑,但现在我很坦诚地接受自己就是不擅长做那种大众流量欢迎的内容。

这里并没有鄙视大众流量的意思,我是真的发自内心的不懂,哈哈哈哈哈~

因为我做内容 99% 的动机,都只是为了把脑袋里的东西腾出来,它只是我的一个思考过程的外化。有人获得共鸣和启发,那就最好,没有那也无所谓。因此我确实没有真的花过心思在研究怎么样制作大家都喜欢的那种类型的内容,因为我也确实没有发自真心地想把自媒体作为自己的一条所谓职业赛道来看待。

因此,没有获得那样的流量,是很正常,也应该的。

一张封面引发的内核更换

By: Steven
28 April 2024 at 18:29

我把博客的模版换了,更简洁,但更好用了。

事情要从「播客封面的输出事故」开始。

我在播客后台上传的一张 1600×1600 的封面图,在通过 RSS Feed 分别同步到小宇宙和 Apple Podcast 的时候,出现了不显示或被识别成「未提供」的状态。小宇宙的后台能看见,这张图是抓到了的,但在播放页没显示;而在 Apple Podcast Connect 的后台就直接识别为「未提供」。同样的源我也尝试给到 YouTube,能抓到,能显示,但非常模糊。

第一时间我就认为是博客那头的设置问题,但具体是什么原因呢?实在是太多年没有折腾过博客的模版设计了。每个菜单我挨个检查了一遍,发现确实有个「摘录」的开关打开了,它会限制 Feed 分享出去的是完整的一篇还是只有局部的内容。这确实有影响,它导致小宇宙没抓到全文,在单集详情页里只显示了第一段话,后面还跟一个无法点击的跳转的纯文字「阅读更多」。关掉这个开关之后,小宇宙也马上就更新,能显示全文了,但封面依然没有显示出来;Apple Podcast 那边完全没动静,别说更新了,就是搜索都还搜不出来,但明明已经发布了。

我实在想不出是哪里的设置不对,就上即刻问了一下。很幸运的是,小宇宙的小伙伴立刻就开始帮我找原因。在几经周折后,最终联系上了小宇宙的技术同学,他给我看说托管源输出的图片尺寸只有 180×200 px。这就很明确了!

https://suithink.files.wordpress.com/2024/04/vol-0000.jpg?w=180&h=200&crop=1

但我依然不知道为什么,因为翻遍了整个后台,都不存在一个设置 RSS Feed 输出封面尺寸的地方。别的朋友也都没遇到过这样的事。况且,一张正方形的图,就算是缩略图也应该是正方形的,比例变了又是为什么呢?

于是我意识到一件事:

这是一个行业内的标准做法,那就应该是通用的,如果别人的播客都没有这个问题,而博客后台又不存在可设置和调整的界面,那最有可能的原因大概就是,我博客使用的模板太过于老旧了。

为什么我会想到这个角度呢?

因为我博客目前用的模板,是 2013 年开始启用的,这十一年来,只在 2022 年时调整过一次,但技术内核还是原本的那套东西。然而事实上,我博客后台切换到区块编辑器已经好几年了,我还在用的这个老模板其实已经下架很多很多年了,只是因为我一直没有更换它,还在生效而已。

为了验证这件事,我先是研究了一下朋友托管播客的网站结构,确定了「封面图」在通用模版中的形式,再在我的博客后台巡了几圈,选定一些结构相似的、我也喜欢的模板,把它们套用在我的播客日志上,看看是什么表现。最后,我在区块编辑器里找到这些页面,看看它们是怎么表达和处理这张「封面图」的,有哪些可以设置的项。

至此,我锁定,问题的根源就在于,这个多年前就早已下架不再维护的老版本软件的模版,它在技术层面和现行的技术之间的差异,导致输出的封面图变成了一个比例错误的缩略图。我只需要换上一个新模版,就可以解决了。

但「换模版」这件事,其实我已经考虑好长时间了。

在这次「封面图事故」之前,我就有换新的的想法了。一方面确实是,在日常写作和新增一些页面时会明显感觉到这种技术上的代际差,只是自己懒得动,能用就不改。我相信大部分程序员也是这么想的,代码屎山不就是这么回事嘛。但如果只是换个模版,其实不用想那么久,所以另一方面更核心的是,我在同时考虑把博客的套餐升级到 Explorer 版,还想提前买下后面几年的域名使用权,因此,在我心里,模版的更新、升级、域名这三件事是合并在一起考虑的。

这次小事故,倒像是上天推了我一把。

于是乎,我下了决心,升档、域名、模版,一次性全部处理好了。我现在的博客,是一个更为简练、但更好用的全新状态。播客源的抓取也回归正常了。

20132022 到今天,眼看着我的博客越改越简练,但内容越来越充盈,我心中是欢喜的。这就是我这些年的状态,越发充盈,越不需要装饰,所有形式都让位于内容。我只要一件舒适的 T 恤就够了。年轻时喜欢说的个性,那不是通过页面、手机壳、衣裤鞋来体现的,个性是行动做派,不需要是任何视觉化的呈现。

这就是另一种「我变秃了,但更强了」。

在博客上做播客,再因为做播客而全面更新了博客,再把这个过程记录在博客上,我如果不写出来,这事儿说给人听都会觉得我有神经病哈!不过 Blog 和 Podcast 这俩完全不相关的事物,在简体中文里的说法竟然像绕口令一般相似,也是有意思。

一些日常生活中的杠铃策略

By: Steven
23 April 2024 at 00:01

「杠铃策略」是一种投资思路,它主张同时投资高风险高收益和低风险低收益的项目,避免那些不上不下的中等投资类项目,通过这样的组合来实现收益的平衡与稳健增长。它鼓励我们一边冒险一边保守,以下是这种策略,应用在日常生活中的例子:

☕ 不要每天早上都喝咖啡,这会让你过度依赖咖啡因,长期处于高兴奋状态会影响效率。应该避免平时一直喝咖啡,留到周末尽情喝,用它把有趣的事情变得更有趣。

📖 不要读那些含糊不清的科学书籍,而是读纯粹好玩的书(比如奇幻、科幻、漫画等)或者真正深入的科学书籍(教科书和综述论文)。

🧑‍🤝‍🧑 不要总交一些「还行」的朋友,而是通过聚会和互联网快速结识成百上千的人,然后找出一小群或几个跟你非常合得来的人,经常见面或聊天。

💻 不要一边写文章一边修改,这样太累了。可以一天写五六篇随笔,随时记录想法,然后在一周内逐渐合并修改成一篇好文章。这样,你的创作冲动就不会被心中的批评家扼杀,同时你内心的批评家也能确保你的写作质量。

💼 别用业余时间做些无聊的项目,尝试一段时间内同时做几份工作,然后用赚的钱去实现一些大胆的计划,比如创业、成为独立研究员等。

🧘 别只是每天用零碎时间冥想,不如每年集中花十天冥想,这样会更快地提升心灵,其他时间尽管随意生活。

📱 不要只是在上厕所的时候随手刷刷交友软件,不如花一个周末好好完善你的资料,然后尽可能多地和不同的人交流,这样你就有更多的可能性找到合适的伴侣。

📚 不要每天都读一章书,而是每几个月花两三周时间集中阅读,那时你可以一天读一本,然后用空闲时间思考书中的内容,把它们串联起来,这样收获会更多。

💬 也别每周读一本书,而是多花点时间写书评,阐释它的主要观点,思考书中的内容,试图与作者的思想进行辩论。通过查找有关主题的更多信息,来丰富自己的知识与思考。

源一:Examples of barbell strategies

源二:Barbell Investment Strategy

配图:SUiTHiNK by Midjourney

翻译:ChatGPT 3.5

润色:SUiTHiNK

重构博客友链页面 & 友链朋友圈开源

By: prin
13 March 2024 at 00:00

先来看看效果:友情链接 - PRIN BLOG

自我感觉还是不错的,友链的博客们有什么更新都可以实时展示在页面上,一目了然。作为博主,不用打开 RSS 阅读器就可以查看新文章;作为访客,也可以快速找到更多自己感兴趣的内容,比起原来全是链接的页面,看起来也让人更有点击欲望了。

从临时起意到开发完成总共两个晚上,最速传说就是我!(误)

缘起

前段时间看到有个博客用了这样的一个东西:

当时就感觉卧槽好高端,很有想法。

这种聚合订阅的形式有个名字,叫做 Planet(社区星球)。Planet 通常用于聚合某个领域的博客,然后展示在一个页面上,方便用户一站式阅读,比如:

这种形式在开源社区里比较常见,不过用在博客的友链上我倒还是第一次看到。


就像我在本站友链页里说的一样,独立博客之间的联系基本上就是靠的链接交换和评论互访。一个博客的访客看到了其他博客的链接,点过去看了,然后从对面的友链中,又导航到新的博客……如此往复,我们就依靠着这种从现在看来显得十分古老的方式,维系着这些信息孤岛之间的纽带。原始又浪漫。

不过这里就会涉及到一个用户点击率的问题。我自己之前在维护友链页面的时候,总感觉只放标题和链接看起来效果不怎么好。就算加上描述、头像这些元素,也总觉得差点意思。因为一个博客最重要的其实还是它的内容,仅靠一个网站标题,可能很难吸引到其他用户去点击。

而「友链朋友圈」的这种形式,就像微信朋友圈一样,作为一个聚合的订阅流,展示了列表中每个博客的最新文章。

比起干巴巴的链接,这显然会更加吸引人。虽然我写博客到现在也已经 9 年了,早就佛系了,主打一个爱看不看。不过对于和我交换了友链的博主们,还是希望他们能够获得更多的曝光和点击(虽然我这破地方也没多少流量就是啦……),也希望我的访客们也可以遇到更多有价值的博客。


然而在准备接入的时候,我发现这玩意儿不就是一个小型的 RSS 阅读器么……其实等于是自己又实现了一套订阅管理、文章爬取、数据保存之类的功能。

于是我就寻思,可能直接复用已有 RSS 阅读器 API 的思路会更好,让专业的软件做专业的事。友链的管理也可以直接复用 RSS 阅读器的订阅管理功能,这样增删改也不需要了,我们就只需要封装一下查询的 API,提供一个精简的展示界面就 OK。

技术栈选择

作为行动力的化身,咱们自然是说干就干,下班回家马上开工!

首先是 RSS 后端的选择。

市面上的 RSS 阅读器有很多,我自己主要用的是 Inoreader。然而我看了下,Inoreader API 只面向 $9.99 一个月的 Pro Plan 开放,而且限制每天 100 个请求……这还玩个屁。Feedly 也是差不多一个尿性,可以全部 PASS 了。我也不知道该说他们什么好,也许做 RSS 真的不挣钱,只能这样扣扣搜搜了吧。

另外一个选择就是各种支持 self-host 的 RSS 阅读器,比如 Tiny Tiny RSSMiniflux。我之前部署过 TTRSS,说实话感觉还是太重了。Miniflux 则是使用 Go 编写的,该有的功能都有,非常轻量级,部署也很方便。就决定是它了!

技术栈方面选择了之前一直比较心水的 Hono,部署在 Cloudflare Workers 上。前端方面没有使用任何框架,连客户端 JS 都没几行,基本上是纯服务端渲染。有时候不得不感叹技术的趋势就是个圈,以前那么流行 SPA,现在又都在搞静态生成了。

cf-workers-usage

页面渲染使用了 Hono 提供的 JSX 方案,可以在服务端用类似 React 的语法返回 HTML,挺好用的。不过 CSS 没有用 Hono 的那一套 CSS-in-JS,因为要允许用户覆盖样式,所以要用语义化的类名。最后选了 Less,还是熟悉的味道。

前端文件的构建使用了 tsup,配置文件就几行,爽。

实现

实现思路很简单,就是做一个 Proxy 层,把:

这两个 Miniflux 的 API 包一下。这里要注意不能暴露实际的 API Endpoint,避免可能的恶意攻击。API 缓存也要在我们这一层做好,防止频繁刷新把服务打爆。

缓存策略上使用了 SWR (Stale-While-Revalidate):

  1. 拿到 API 响应后,放到 KV 中,同时把时间戳放入 metadata;
  2. 后续从 KV 读取缓存时,对比当前时间和 metadata 中的时间戳;
  3. 如果经过的时间没有超过设置的 TTL,说明缓存有效,直接返回前端;
  4. 如果经过的时间超过了 TTL,则标记缓存为 stale 状态,依然返回前端
  5. 此时,后端在后台重新请求 API,并将最新的响应写入 KV 中;
  6. 下一次再从 KV 读取时,拿到的缓存就是最新的了。

这样可以保证最快的响应速度,以及相对及时的更新速度,比较适合这种场景。

最后的交付形式其实就是两个 HTML 页面,通过 <iframe> 的形式嵌入到网页中。另外参考 giscus 提供了一个脚本,可以设置参数并自动完成 iframe 的初始化,用户只需要引入一个 <script> 标签即可,非常方便:

<script  async  data-category-id="28810"  src="https://blog-friend-circle.prin.studio/app.js"></script>

friends-page-demo

当然也可以作为独立页面打开,有做双栏布局适配:

blog-friend-circle.prin.studio/category/2/entries

开源

新版博客友链朋友圈的所有代码都开源在 GitHub 上,欢迎使用:

👉 prinsss/blog-friend-circle

这个方案和 hexo-circle-of-friends 并没有孰优孰劣之分,只是侧重点和实现方式不同。不过我这个的一个好处是,如果你已经在用 Miniflux 了,那么可以直接复用已有的大部分能力,不需要再起一个 Python 服务和数据库去抓取、保存 RSS,相对来说会更轻量、稳定一些。

如果你选择使用 Miniflux 官方提供的 RSS 服务,甚至可以无需服务器,部署一下 CF Workers 就行了,像我这样的懒人最爱。

博客主题可以自动切换深色模式啦

By: prin
9 August 2021 at 03:05

有时候我也很佩服自己,这么简单的一个功能,写写也就几个小时,一年多前就想搞了,竟然给我拖到现在才装上去。拖延症,恐怖如斯!

以前我对深色模式其实不怎么感冒,主要感觉开了也没啥用,就系统界面变黑了,其他 App 里还是白色的,等于没开。不过这几年大部分应用的适配都跟上来了,体验也就好起来了,晚上玩手机看着不那么刺眼,挺好的。

现在浏览器网页也支持检测用户的系统主题色,所以我也凑个热闹,给博客加上了自动切换浅色/深色主题的功能。适配过程还是挺顺利的,记录一下供参考。

原理

就是使用 CSS 的 prefers-color-scheme 媒体查询。

@media (prefers-color-scheme: dark) {  /* dark theme styles go here */}

参考文档:prefers-color-scheme - CSS | MDN

不过需要注意的是,不支持 IE

使用方法

最简单的例子:

body {  background-color: white;  color: black;}@media (prefers-color-scheme: dark) {  body {    background-color: black;    color: white;  }}

这样在亮色模式下是白底黑字,在暗色模式下就是黑底白字。

依样画葫芦,给原主题中颜色相关的 CSS 加上对应的深色样式就差不多了。

使用 mixin 处理颜色

拿我自己写的这个主题举例,在主题中我们一般会用到很多颜色。一个常见的做法就是使用 CSS 预处理器,把这些颜色定义成变量方便后续使用(我用的是 Stylus):

$color-primary        = convert(hexo-config('primary_color'));$color-background     = #fff;$color-text           = #333;$color-text-secondary = #999;

同样,定义这些颜色的深色版本:

$color-primary-dark        = convert(hexo-config('primary_color_dark'));$color-background-dark     = #181a1b;$color-text-dark           = #c8c3bc;$color-text-secondary-dark = #a8a095;

引用之:

body {  background-color: $color-background;  color: $color-text;}a {  color: $color-primary;}@media (prefers-color-scheme: dark) {  body {    background-color: $color-background-dark;    color: $color-text-dark;  }  a {    color: $color-primary-dark;  }}

然而问题来了,这样岂不是要写很多媒体查询语句?麻烦且不说,看着都眼花。如果把不同地方的这些语句集中起来,放在一起,又会破坏模块设计,也不利于后续维护。

想要写得简洁一点,不妨利用 CSS 预处理器的 mixin 特性

定义 mixin(可以理解为可重用的代码片段):

// 根据传入参数拼装变量名color-themed(name) {  color: lookup('$color-' + name);  @media (prefers-color-scheme: dark) {    color: lookup('$color-' + name + '-dark');  }}

这个 mixin 的意思就是我们传一个名称进去,它会根据这个名称去查找对应的颜色变量及其深色版本,然后一起应用。

如此一来,上面的样式就可以简化为:

body {  background-color-themed: 'background';  color-themed: 'text';}a {  color-themed: 'primary';}

使用 CSS 变量处理颜色

用上面那种方法,比原来的是好了不少,但感觉不太直观。

另一种方法,就是用 CSS 原生的变量机制来处理颜色。定义变量:

:root {  --color-primary: #7065a3;  --color-background: #fff;  --color-text: #333;  --color-text-secondary: #999;}@media (prefers-color-scheme: dark) {  :root {    --color-primary: #bb86fc;    --color-background: #181a1b;    --color-text: #c8c3bc;    --color-text-secondary: #a8a095;  }}

使用:

body {  background-color: var(--color-background);  color: var(--color-text);}a {  color: var(--color-primary);}

是不是清爽了很多呢?

不过遗憾的是,IE 浏览器不支持 CSS 变量。(又是你!!!🙃

所以为了兼容性我还是选了预处理器 + mixin 的方法,这样在 IE 上虽然不能自动切换,但至少能保证默认的浅色主题是可以正常显示的。而如果全部使用 CSS 变量的话,在不支持的浏览器上就啥都没有了,得考虑 polyfill 和 fallback,还是算了。

如果不用考虑兼容旧浏览器的话,CSS 变量是最佳选择。

加载外部样式

使用 link 标签加载的外部 CSS 也可以指定媒体查询

比如本主题使用的 highlight.js 代码高亮的样式:

<link rel="stylesheet" href="atom-one-dark.min.css" media="screen and (prefers-color-scheme: dark)"><link rel="stylesheet" href="atom-one-light.min.css" media="screen and (prefers-color-scheme: light)">

这样在浅色模式下会加载 light 样式,在深色模式下会加载 dark 样式。

参考

另外,关于深色模式下的图片要如何处理,其实也是需要考虑的。

不过我懒,就直接不管了。更详细的相关内容可以参考:

最后是自动切换的效果图(视频):

使用 GitHub Actions 自动部署 Hexo 博客

By: prin
7 February 2021 at 04:05

联动三年前的文章:使用 Travis CI 自动部署 Hexo 博客

今天更新了一下博客,寻思着好歹也改一下页脚的 Copyright 年份,改完 push 上去以后却发现 GitHub Pages 迟迟没有更新。进去 Travis CI 一看,发现任务一直处于 Queued 状态,半小时了都没开始构建。

查了一下,并不是只有我遇到了类似情况(似乎是因为 Travis CI 正在将 travis-ci.org 迁移至 travis-ci.com):

看了一圈感觉有点悬,干脆换成 GitHub Actions 吧。

我的博客完全托管在 GitHub 上:prinsss.github.io,其中 source 分支放的是源码,master 分支(即 GitHub Pages)是 Hexo 生成的静态博客页面。

要做的也和之前 Travis CI 差不多,当 source 分支有更新时,自动使用 Hexo 构建新页面并更新 GitHub Pages 就可以了。

配置部署密钥

生成一个新的 SSH 密钥,用于 push 至 GitHub Pages 所在的 repo:

ssh-keygen -f hexo-deploy-key -C "prinsss.github.io"

将公钥 hexo-deploy-key.pub 设置为仓库的部署密钥(Settings > Deploy keys):

add-deploy-key

然后在 Settings > Secrets 中新增一个 secret,命名为 DEPLOY_KEY,把私钥 hexo-deploy-key 的内容复制进去,供后续使用。

编写 Workflow

Workflow 就是 GitHub Actions 的配置文件,类似于 .travis.yml

首先新建文件:

mkdir -p .github/workflowstouch .github/workflows/deploy.yml

编辑 deploy.yml

name: Hexo Deploy# 只监听 source 分支的改动on:  push:    branches:      - source# 自定义环境变量env:  POST_ASSET_IMAGE_CDN: truejobs:  build-and-deploy:    runs-on: ubuntu-latest    steps:      # 获取博客源码和主题      - name: Checkout        uses: actions/checkout@v2      - name: Checkout theme repo        uses: actions/checkout@v2        with:          repository: prinsss/hexo-theme-murasaki          ref: master          path: themes/murasaki      # 这里用的是 Node.js 14.x      - name: Set up Node.js        uses: actions/setup-node@v1        with:          node-version: '14'      # 设置 yarn 缓存,npm 的话可以看 actions/cache@v2 的文档示例      - name: Get yarn cache directory path        id: yarn-cache-dir-path        run: echo "::set-output name=dir::$(yarn cache dir)"      - name: Use yarn cache        uses: actions/cache@v2        id: yarn-cache        with:          path: ${{ steps.yarn-cache-dir-path.outputs.dir }}          key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}          restore-keys: |            ${{ runner.os }}-yarn-      # 安装依赖      - name: Install dependencies        run: |          yarn install --prefer-offline --frozen-lockfile      # 从之前设置的 secret 获取部署私钥      - name: Set up environment        env:          DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }}        run: |          sudo timedatectl set-timezone "Asia/Shanghai"          mkdir -p ~/.ssh          echo "$DEPLOY_KEY" > ~/.ssh/id_rsa          chmod 600 ~/.ssh/id_rsa          ssh-keyscan github.com >> ~/.ssh/known_hosts      # 生成并部署      - name: Deploy        run: |          npx hexo deploy --generate

当然,具体步骤还是得根据自己的需求进行相应的修改。

GitHub Pages 相关的具体配置放在了 Hexo 的 _config.yml 里:

deploy:  type: git  repo: git@github.com:prinsss/prinsss.github.io.git  branch: master  name: prinsss  email: prinsss@gmail.com

部署结果

更新 source 分支,push 后 GitHub Actions 就会自动执行。

deploy-result

不到半分钟就 build 完了,只能说微软爸爸还是牛逼。

参考链接

❌
❌