普通视图

独立博客自省问卷15题

2024年11月23日 15:07

感谢雅余同学发人深省的15问,看到不少博友都回复了,挺有意义故而也参与下,顺便扩散下。 1、你的博客更新频率是多少? 答:这个不一定,一是看心情,二是看时间,三是看有没有想写来的东西,三个碰巧都有了,那就会更新下,一般来说,短则一月两三更,...

收藏的博客

2025年9月14日 22:41

收藏的博客 - 第1张图片

积薪关停之后,博客阅读来源几乎只有订阅的 RSS,用 Folo 进行查阅。单从积薪的形式和做法来说,它是一个好项目,收录的博客都很有水准,不管是从内容、设计、风格等方面都是一些值得收藏和阅读的好网站,没能延续下去确实是一个遗憾。可能这也是网站商业化的弊端之一,要考虑受众群体的想法和需求。

一个博客导航网站倒下,还会有成千上万个博客导航网站出现。现在就是如此,但同质化太严重,要么是千篇一律的模板,要么是没有严格的收录标准,一些质量低下、存活时间不长的网站输出 RSS 到首页,更是污染时间线的行为,我曾经也做过博客导航网站,也因上述原因而倒下,这次我选择做点不一样的。

它只是我的一个收藏,像一个图书馆一样,把我喜欢的博客放进去,贴上我定义的标签,按我的想法进行分类,99% 的主观,不带任何广告,不掺杂任何商业元素,不接受任何自荐,我没有收藏某个博客,并不代表这个博客不好,只表示我不喜欢。因此,我这次没有使用其他网站程序,没有找所谓的导航主题,只用 Notion,并用它的自定义域名发布,有人要问了,既然自己收藏,一切都随自己想法,为什么还要公开呢,雅俗共赏,看一看别人的审美和兴趣。

最初定义的是收藏一些有特色的博客网站,特色的涵盖范围比较广,包括但不限于内容本身、网站设计、文章排版等等。基于我的主观性,拒绝花里胡哨、无病呻吟之流的博客,也拒绝网络搬运、三天打鱼,两天晒网等类型的网站。现在很常见的一个现象是,是个人都能建网站,随便发点东西就能称之为博客,但实际上更多的是在污染中文互联网,制造越来越多的内容农场。与之对应的是优质内容很难快速、便捷获取,这才有了我的这个想法。

目前使用 Notion 的数据库,画廊模式,添加了网址、标签、程序等字段,后续我也会在详情里添加自己的一些描述和评论。没有额外添加 RSS 地址,我几乎已经订阅了,而且如果访问到这个网站的用户,有需要,直接去博客里寻找即可。

有意思的是,幸运地使用了 BlogRoll 作为 Notion 二级域名的前缀,所以网址是:

https://blogroll.notion.site

以上观点并不针对特定的人和网站,请勿对号入座。

问:你为什么要收藏自己的博客?

答:我乐意。

收藏的博客》最先出现在印记

一脚油门要花多少钱? 保时捷卡宴/Cayenne油耗看: 每脚油门成本

一脚油门要花多少钱?——从保时捷 Cayenne 油耗看“每脚油门成本” 很多人开车从不去想:

我这一脚油门,到底花了多少钱?
最近我在算自家 Porsche Cayenne 的用油成本时,顺便研究了一下“每脚油门或刹车”到底值多少钱。大概估算了一下,确实很费油。 只要经常在城里开,MPG就很低,显示 12 MPG,卡宴SUV真是耗油。如果经常开高速,MPG能20多。一般油耗正常的大概平均三四十。我之前的手动档奥迪A6就很省油,2.0的引擎MPG大概平均三四十。 [caption id="attachment_70188" align="alignnone" width="1442"]保时捷卡宴在城里开堵车的情况下 MPG只有12左右 保时捷卡宴在城里开堵车的情况下 MPG只有12左右[/caption]

一、已知条件

项目数值
车型Porsche Cayenne
平均油耗(城市堵车)12 MPG
平均油耗(综合路况)20 MPG
油价£1.379 / 升
满油成本约 £100
满油续航约 480–500 英里
从油箱续航和油价推算,一箱油约 72.5 升,说明油耗与这些数据是匹配的。

二、每英里油钱是多少?

油耗 20 MPG(英里/加仑):
  • 1 英制加仑 = 4.546 升
  • 每英里耗油:1 ÷ 20 × 4.546 ≈ 0.2273 升/英里
  • 油价 £1.379/L → 每英里油费:0.2273 × 1.379 ≈ £0.313 ≈ 31.3 便士/英里
结论:平均每跑一英里(约 1.6 公里),花 £0.31(约 2.8 元人民币)

三、刹车/油门频率假设

路况平均速度每英里刹车/加速次数
高速路约 60 mph1–2 次(取 1.5)
城市道路约 30 mph4–5 次(取 4.5)
假设:一半路程是城市,一半是高速,每次油门/刹车都消耗部分动能,高速加速比城市加速动能高约 4 倍。

四、推导每次油门的能耗成本

设城市每次油门成本为 s(便士),高速每次油门成本 h = 4s。 每英里燃油费用分配:
  • 高速每英里耗 = 1.5 × h = 6s
  • 城市每英里耗 = 4.5 × s
平均每英里燃油成本: (6s + 4.5s)/2 = 5.25s 已知每英里成本 31.3p → 5.25s = 31.3 → s ≈ 5.97p 于是:
场景每次油门成本
城市(30 mph)≈ 6p (£0.06 ≈ 0.55元)
高速(60 mph)≈ 24p (£0.24 ≈ 2.2元)
检验(代回每英里总花费):(1.5×24 + 4.5×6)/2 = 31.3p/英里

五、平均每脚油门/刹车多少钱?

综合两种路况,一英里平均约有 3 次油门或刹车操作(这里简单认为一次油门对应一次刹车,方便计算): 31.3 ÷ 3 ≈ 10.4p/次 也就是说:平均每踩一脚油门或刹车,约花 10 便士(≈0.9 元人民币)

六、为什么高速刹车更“贵”?

动能与速度平方成正比:[math] E = \frac{1}{2}mv^2 [/math] 速度翻倍(30 → 60 mph),动能增加 4 倍。高速刹车次数少,但每次损失更大,所以“少而贵”。

七、省油小建议

  • 🚫 少急加速(尤其城市堵车)
  • 🚦 提前预判,尽量滑行减速
  • ⚙️ 保持匀速行驶,减少频繁启停

八、总结一览表

项目数值说明
平均油耗20 MPG综合路况
油价£1.379/L英国 95# 汽油
每英里油费£0.313 ≈ 31p
城市每脚油门≈ 6p
高速每脚油门≈ 24p
平均每脚油门≈ 10p约 0.9 元人民币

九、结语

在堵车或城市驾驶中,每脚油门大约要花 6 便士;在高速上,一脚油门可能要 24 便士。你每一次无意识的加速、刹车,其实都能在钱包里听见响声。 [show_file file="/var/www/wp-post-common/justyy.com/car-insurance.php"]

相关文章:

  1. 智能手机 HTC One M9 使用测评 虽然我对手机要求不高, 远远没有像追求VPS服务器一样, 但是怎么算来两年内换了四个手机, 先是三星 S4 用了一年多, 然后 Nokia Lumia 635 Windows Phone, 后来又是 BLU, 半年多前换了...
  2. 按揭贷款(房贷,车贷) 每月还贷计算器 去年给银行借了17万英镑 买了20万7500英镑的房子, 25年还清. 前2年是定率 Fix Rate 的合同 (年利率2.49%). 每个月大概是还 700多英镑. 有很多种还贷的计算方式, 定率/每月固定 是比较常用的. 简单来说就是 每个月交的钱是...
  3. 第一次私校家长会: 原来家长比孩子还卷 前几天参加了娃的第一次家长会,和几位家长聊下来,真是个个都很厉害。不光孩子们卷,家长也一样卷,一眼望去基本都是 Dr/博士。娃还调侃我一句:“这有什么的,你不也是 Dr 吗?” 我心里默默想:还好没写学校名字,不然我这野鸡大学的头衔真拿不出手 😂。 私校里真是人才济济,乐器过 8 级的太常见了,卷得不得了。我还问过娃,是想当 big fish in a small pond...
  4. 怎么样移动WordPress博客的评论? 有时候WP的博客评论并非留在我们想要的博文中, 这也许是看了好几篇博文后突然想留下个评论导致的. 为了有利于SEO, 评论还是尽量的留在相关文章或者页面里. 这时候我们就需要移动指定的几条评论. 我们可以通过SQL语句(高级用户) 或者插件(一般用户) 两种方法来移动Wordpress评论. 怎么样通过SQL来移动Wordpress评论? 如果你对SQL很熟悉, 懂得登陆MySQL 控制台或者是使用 PHPMyAdmin等 数据库管理平台, 那么你就可以通过以下方法来移动Wordpress评论....
  5. 比特币最近波动有点大: 一天牛市一天熊 比特币10万美金以内都是最后上车的机会! 比特币近期的价格波动可以归因于多个关键因素,包括地缘政治动态、监管变化以及加密行业内的重大安全事件。其中一个主要影响因素是美国前总统唐纳德·特朗普对乌克兰和加密货币监管的立场变化。据报道,特朗普再次当选,他可能会推动减少美国对乌克兰的支持,这可能会影响全球金融市场和风险偏好。同时,特朗普正在将自己塑造为亲加密货币的候选人,表示有意让美国成为一个更加友好的加密货币环境。这一立场引发了市场对监管政策可能发生变化的猜测,导致市场情绪在乐观和不确定性之间波动。 特朗普对俄乌战争的态度 美国第43届总统唐纳德·特朗普已经在2025年1月当选并正式上任(第二次),那么他的政策可能会对比特币价格的波动产生更加直接和显著的影响。他政府对乌克兰和加密货币监管的立场已经不再是猜测,而是正在实际塑造市场的关键力量。 特朗普(Donald Trump)减少美国对乌克兰的支持,全球投资者可能会预期地缘政治稳定性发生变化,从而增加对比特币作为避险资产的需求。同时,他的亲加密货币立场可能正在推动市场的乐观情绪。如果他的政府推出有利于加密行业的监管政策,例如明确的合规指南或减少监管审查,可能会吸引更多机构投资者进入市场,并促进更广泛的加密货币采用。然而,政策的快速变化也可能导致短期市场剧烈波动,因为市场需要时间来消化新的政策动向。 朝鲜黑客盗取Bybit交易所15亿美元的ETH 另一个显著影响比特币价格的事件是近期涉及朝鲜黑客组织“Lazarus”的15亿美元以太坊被盗案件。据报道,Bybit交易所(全球第二)这些被盗的ETH已经被清洗,此次大规模黑客攻击引发了人们对加密行业安全性的担忧。此类安全事件不仅会削弱投资者信心,还可能引发更严格的监管审查,导致短期市场动荡。此外,被盗资金的大规模流动和出售可能对市场流动性造成冲击,进一步加大价格波动。随着这些事件的持续发酵,比特币价格正受到政治决策、监管预期以及安全挑战等多重因素的影响。 与此同时,与朝鲜黑客组织 Lazarus 相关的 15 亿美元以太坊被盗事件仍在影响加密市场。由于这些被盗 ETH 已被清洗,人们对加密行业安全漏洞的担忧持续存在,同时也可能引发更严格的监管审查。政治、监管和安全等多重因素交织在一起,共同导致了比特币近期的剧烈价格波动。...
  6. 微信PC端程序占用了1.39 TB的空间! 快速清理微信占用空间 前两天我的 C 盘剩余空间突然变红了,我随手一查,竟然发现微信 PC 端程序居然占用了 1.39 TB 的空间,简直不可思议。在手机上,微信同样是名列前茅的“吞空间大户”,在 设置 → 通用 → 手机存储空间 里几乎稳居第一。 更离谱的是,这些空间大多并不是因为聊天记录,而是各种缓存文件、视频、图片和被动接收的文件所堆积起来的。平时我们只是点开看一眼,就算没保存下来,微信也会悄悄把它们留在本地,占据大量磁盘。尤其是群聊里转发的视频和文件,日积月累就成了一个“隐形黑洞”。...
  7. 花钱让人换汽车钥匙的电池真是个智商税 今天想不到我这么聪明的人也被人狠狠的收了一把智商税. 今天被收智商税了, 去 Tesco 换车钥匙的电池. . 才发现如此的简单, 那人直接2分钟搞定2个, 然后收了我25英镑. . 服了. . 我还以为很复杂…… 网友说 “1....
  8. 老婆的配偶签证被拒 郁闷死了, 601镑签证费打水漂,一去不回!费钱费力. 去年12月份我请了律师拿到了永居.老婆是T1G签证的陪工签 (DEPENDENT VISA) 2016年4月份到期. 然后我就想说得趁早把她的签证转成配偶签(SPOUSE)这样她就可以尽快走五年永居的路线. 今天收到拒签信,原因是我没有提供 有工资进帐的那份银行帐单,我提供了我和我老婆的联名帐户, 但是工资并不是直接打到这个帐单上的.所以就这一点被拒了.完全不给解释,不给补材料的机会.601镑就这样再见了. 英国的签证寄出之后是先由另一个部门先收费, 收完费才正式审理,而且不管结果如何是不退钱的.后悔没让律师弄,也不至于到现在浪费这么多时间和金钱,签证还没过.由于原签证还没到期,所以还不能上述.估计只能等搬完家后年底请律师搞定这事. 真是郁闷, 600镑, 我可以再买一个IPHONE6,或者给我的新买的车换四个轮胎....

重要通知: 弃用 FeedBurner RSS 请改用 https://justyy.com/feed

最近我发现原本的 RSS(/rss、/feed)没有按时更新。 [caption id="attachment_5288" align="alignnone" width="351"]rss rss[/caption] 进一步检查后发现这些地址都被 301 重定向到了 FeedBurner(https://feeds.feedburner.com/zhihua-xblog),而 FeedBurner 已经久未维护,偶有抓取失败或延迟,导致读者无法及时收到新文章。 造成这次重定向的原因是我们使用的第三方主题/插件(mytheme)里曾经内置了将站点 feed 转发到 FeedBurner 的功能。 当时之所以做 301 转向,是为了节省服务器带宽并统一订阅链接。 但现在服务器已经升级,带宽与性能不再是主要问题,因此不再需要通过 FeedBurner 做中转。 更糟糕的是,外部订阅器或旧配置在访问 /feed 时被持续重定向到 FeedBurner,如果 FeedBurner 自身抓取不到最新源,就会出现更新停滞或重复重定向的风险,极端情况下甚至可能出现重定向环(redirect loop)。 为了避免订阅丢失或链接异常,我们决定弃用 FeedBurner,并将本站的官方 RSS 源迁回自有域名。 请所有读者、RSS 订阅器和外部引用尽快把订阅地址改为: https://justyy.com/feed 如果你在使用 Feedly、Inoreader、邮件订阅或其他 RSS 客户端,请把原来的 FeedBurner 地址替换为上面的新地址,以确保你能及时收到更新。 如果你在网站或第三方平台上嵌入了本站的 RSS 链接,也请尽早更新为 https://justyy.com/feed,以免未来出现不可预期的中断。

用 FeedBurner 的好处

FeedBurner 由一家初创公司在 2004 年开发,2007 年被 Google 收购。FeedBurner 在 2000 年代非常流行,它的主要优点包括:
  • 统一和美化 RSS 输出:让各平台的 RSS 格式一致,订阅链接固定。
  • 订阅统计:可以看到每日订阅人数、来源与点击数。
  • 邮件推送功能:自动将新文章通过邮件发送给订阅者。
  • 广告功能:早期支持 AdSense for Feeds,在 RSS 中插广告获利。
  • 节省带宽:FeedBurner 缓存内容,订阅者访问时不会直接访问原站。
这些特性在当年是 WordPress 等博客系统无法原生提供的,因此 FeedBurner 成为了许多博主的默认选择。

用 FeedBurner 的坏处

然而,随着时间推移,FeedBurner 已经不再更新,甚至部分功能被 Google 下线,带来了以下问题:
  • 功能残缺:订阅统计、邮件推送等功能已被停用或不稳定。
  • 数据不准确:订阅数与阅读数常年不更新。
  • 影响 SEO 与品牌归属:订阅链接属于 FeedBurner,而不是你自己的域名。
  • 更新延迟:FeedBurner 抓取源可能延迟几小时,无法实时同步。
  • 潜在风险:如果未来 FeedBurner 服务终止,订阅者将全部丢失。
如今的 WordPress 已经具备完善的 RSS 功能,且现代工具(如 Mailchimp、Jetpack Subscribe、Substack)可以提供更强的推送与统计能力。 因此,继续依赖 FeedBurner 已经没有意义,反而会成为隐患。

总结与迁移建议

如果你还在使用 FeedBurner,请尽快切换到自有域名的 RSS 地址。 这不仅能避免服务中断与重定向问题,也能让你重新掌控订阅用户数据。 本站新的 RSS 地址是: https://justyy.com/feed 请更新你的 RSS 阅读器、订阅源或网站引用,确保后续能继续收到本站的最新内容。 FeedBurner 在 2010 年是 RSS 的标准,但在 2025 年,它几乎已经是“废墟”。现在更推荐:直接用 WordPress 自带 feed + 现代邮件/自动化工具,让控制权回到你手上。 感谢所有读者的长期支持与理解。 [caption id="attachment_70167" align="alignnone" width="1472"]RSS更新延迟一周,我得登陆FeedBurner强制Update一下 RSS更新延迟一周,我得登陆FeedBurner强制Update一下[/caption]

相关文章:

  1. 2025年10月10号币圈黑天鹅: 要想一直在牌桌前就不要玩杠杆/合约 只要不加杠杆,你就是安全的:除非你有能力承担损失,否则任何人都不应该使用杠杆。即使没有杠杆,加密货币的波动性也已经足够大了。 You are safe as long as you don’t do leveraging: No one should be...
  2. 个人网站Adsense广告申请通过: 需要最少15篇文章 我的个人网站 zhihua-lai.com 本月通过了 Adsense 审核,终于可以再次放置广告,赚些零花钱了。 其实,最初 Adsense 账户通过审核后就能直接放广告,但后来规则变得严格了。如果一个网站长时间没有放置任何 Adsense 广告代码,账户资格会被撤销。重新启用时,需要进行单独审核。如今,在 Google Adsense 中新增一个域名,也必须通过审核后才能投放广告。 为了让我的网站通过审核,我尝试了几次,但总是被拒,原因之一是必须要有足够的内容支持。例如,以前我做的工具网站 SlowAPI.com...
  3. 微信公众号(justyyuk)机器人支持 STEEM 查询啦 The wechat bot (justyyuk) now supports Inquiry for Steem Accounts. 之前把API给放出来, 能做的事情就很多了. 比如我就在我的公众号上加上了STEEM 查询. 查询的时候只需要给公众号发...
  4. 特朗普加关税的公式竟然是EXCEL里弄的? 这两天中美关税大战越演越烈,据说,特朗普加关税的计算方式竟然是直接在EXCEL电子表格里弄的,具体如下: 其中 I 是 Import,进口;E 是 Export 出口。 优美又实用的公式家族又添新成员 勾股定理: 欧拉恒等式: 牛顿运动定律: 爱因斯坦质能等价公式: 特朗普的“互惠关税”公式:,其中 I...
  5. 新的旅途 – 离别总是伤感的, 离开了一起创业的公司 2周前, 正式离开了一起创业的公司, 这公司是我博士毕业后的第一份正式工作, 待了8年多了, 离别总是伤感的. 我是9月初提的离职, 三个月 Notice Period, 最后的几周交接完工作确实没有什么压力了. 11月30号, 在公司最后一天, 公司有个习惯, 对于 Good...
  6. Minuet in C – 小步舞曲C Posted Youtube – 油管地址 孩子弹琴的时候最帅了. 我现在成了我儿子的粉丝了. Eric (Aged 6) is playing “Minuet in C” when...
  7. 儿子问我软件工程师的工作体验是怎么样的? 儿子问我软件工程师(Software Engineer)都是做什么的, 他很好奇我的工作内容, 我简单的说就是写代码+调试=解决问题. 正好那天是周五下午, 娃在上Papworth上钢琴课, 我一般都在车里剪视频利用起这个碎片时间. 我抱着笔记本在车里工作, 从年初就在忙一个大的改动, 忙了有两个多月, 终于差不多了, 两同事代码审核(Code Review)都通过了就差一些小改动, 所以我在车里还在努力, 根据收到的建议提交了代码...
  8. 伦敦海底捞火锅 (Hidilao) 好吃吗? 这一次去的是伦敦的海底捞(Hidilao)火锅. 已经开了有几年了, 这次等到英国疫情放开后才想着去试试. 以前听说人特别多, 得排队好几个小时, 这次大概是快中午12点去的, 给了个号码, 说大概要45分钟, 但感觉不到半小时就排到了. 伦敦的海底捞在地铁口(Piccadilly Circus)附近, 两分钟就到了, 不过感觉门面并不是很大, 一进门就是等候区, 用餐的在楼下二层....

RevolverMaps下线了

2024年11月24日 01:09

我的访客记录页面本有一个3D的地球图案,用以记录和实时显示当前正在浏览此页面的用户,是个非常漂亮的动态组件,今天发现不显示了,一开始以为是DNS解析的问题,结果排查下来发现是这个服务下线了,官网也关了,只留下了两句话:

RevolverMaps has shut down.
Many thanks to all users and supporters of the service!

—— https://www.revolvermaps.com/

自从玩博客以来,从Web 2.0时代至今,用过了很多有意思的插件、组件,还有许多的主题、第三方图床、音乐服务。这个3D地图是我自接触它就一直用到今天从未想过舍弃的组件,至少有10年以上,不知道RevolverMaps团队是资金出了问题还是单纯地不玩了。在网页存档网站搜索了一番,favicon11月7日都还是正常的,favicon11月16日已经下线服务了,关站应该就是在这期间里的某一天。

实在惋惜,虽然再次印证了第三方服务随时会跑路的定律,但还是感谢RevolverMaps的陪伴!

以前的截图,上面的3D地球图案就是RevolverMaps


除非注明,三棵树阁文章均为原创,转载请以链接形式标明本文地址
本文链接:http://www.sksren.com/archives/1994.html

一点小改动

2024年9月9日 23:45

起心很久了,今晚得空,精简了下博客导航栏的文字,同时添加了Emoji表情符号。

略微更新了关于页和链接页的内容,其他页面有更新的计划,但不在今晚。在导航栏新设专题菜单,把四川县市游记计划专页归入其中,准备再新增一项明信片交换计划,以后有冲动的想法或者计划以及天马行空的思绪都单开专页做记录。

我以为我不会再折腾了,没想到我居然还能有这折腾的心。


除非注明,三棵树阁文章均为原创,转载请以链接形式标明本文地址
本文链接:http://www.sksren.com/archives/1979.html

即使集市再繁荣也应该拥有属于自己的独立店铺

2025年3月10日 13:26
即使集市再繁荣也应该拥有属于自己的独立店铺

平台就像一个集市,既有卖内容的商家,也有来消费或闲逛的游客。在平台上注册账号发布内容,就像在集市上摆摊,我们不需要交租金,因为平台也知道,只有人流多的地方才有生意。

通过平台发布内容来表达自己或吸引顾客,确实比在偏僻的地方开店更能带来流量和收益。但集市终究是短暂的,不是自己的地方。哪天平台有新政策或倒闭了,我们也只能打包走人。

在集市上经营摊位,最重要的是不断结识新朋友、收获新的交流。别指望这个免租金的摊位会永远存在。

摆摊是一种很棒的体验,但我们还是应该拥有一个属于自己的店铺。虽然不求像集市那样的人流量,但装修店里的每个细节——灯光、桌椅、门前的花草——都是对自己的愉悦和治愈。

我会在集市上和大家谈笑风生,邀请大家有空来我店里坐坐。我的店位于不为人知的「半山腰转角处」,虽然不像集市那般丰富和有趣,但也算是个不浮躁的精致小屋。

「她的蓝」是我自建立的个人摄影品牌,创建于 2019 年,各大自媒体平台和制作客户摄影集的署名都会用到这个名字。除了像 b 站、小红书、抖音等等这种集市上的摊位,我也有自己的独立店铺——独立博客,你可以在搜索引擎输入「她的蓝」,通常第一个链接便是了,点击进去即可阅读,又或者可以输入我引以为傲的域名也可访问。

独立博客虽然更新不勤,但闲暇业余也是用心经营,欢迎大家有空访问光临。

即使集市再繁荣也应该拥有属于自己的独立店铺
我的桌面和独立博客

我们要成为专注的人

2025年1月20日 15:45
我们要成为专注的人

以前,我很喜欢收集那种人们拿着相机,专注于拍摄眼前景象的照片。最初,我以为自己只是迷恋相机设备,或者是喜欢记录时光的浪漫。然而随着时间的推移,我意识到我更喜欢的是人们全神贯注地处理事物的样子——比如在图书馆里看书,专心致志地做笔记,或者埋头写作。现在我才明白,我热爱的不仅仅是工具本身,而是人们用心去掌控工具,朝着目标努力的那份专注与投入。

我们要成为专注的人
拍摄于 2017 年,和朋友去深圳园博园玩摄影
我们要成为专注的人
拍摄于 2013 年,和朋友去看许巍演唱会

难以专注的时代

不知不觉,我已经使用哔哩哔哩十二年了,接触互联网也刚好二十年。从网瘾少年到从事电商行业,屏幕与键盘早已成为生活的一部分。我亲历了简中互联网的发展,从 1990 年至 2000 年的探索起步,到 2000 年至 2010 年的百花齐放,再到 2010 年至 2020 年的移动互联崛起。进入 2020 年后,「他们」对互联网的全面接管让我再也无法断开网络生活。

在这个短平快的时代,专注成了稀缺品。各大科技公司绞尽脑汁夺取我们的注意力,延长产品的使用时长。不仅如此,用户(博主)也在用尽各种「黄金开头三秒」「爆款钩子」等技巧来吸引点击、播放和点赞。这本身无可厚非——毕竟这是他们谋生的方式。然而,对于大多数观众来说,停止刷视频、关闭网页却变得异常困难。一眨眼,半天光阴悄然流逝,只留下短暂的满足感,现实中真正重要的事情却被搁置,视频中的「知识」也未能转化为行动,甚至被遗忘在收藏夹的深处。

奖赏机制,沉迷成瘾

多巴胺是一种神经调控分子,同时也是单胺类神经递质。大脑中存在多条多巴胺通路,其中一条在奖励系统中起着至关重要的作用。它驱使我们对某个结果产生欲望或厌恶,进而促使我们去追求或回避。

需要明确的是,多巴胺并非所谓的「快乐分子」,它更像是「获取更多」的驱动力。我们之所以感到愉悦,并非源于已经得到的事物,而是来自于不断「追求更多」的过程。而这种愉悦往往是短暂的,因此,我们会不自觉地反复刷新屏幕,持续探索、发现,试图获得更多的信息和刺激,以满足内在的渴望。

有人统计了「做一些行为中会分泌多少多巴胺」的排行,数据未经考实,但可大概参考参考。

  1. 撸猫撸狗 (27 单位)
  2. 在田野里散步(43 单位)
  3. 被表扬(51 单位)
  4. 游泳(56 单位)
  5. 滑雪(59 单位)
  6. 看体育比赛(61 单位)
  7. 很美的睡一觉(64 单位)
  8. 洗个热水澡(71 单位)
  9. 发现一个新音乐(75 单位)
  10. 看最喜欢电视节目(76 单位)
  11. 跳舞(80 单位)
  12. 学一些新的东西(82 单位)
  13. 早晨一杯热咖啡(84 单位)
  14. 读完一本书(87 单位)
  15. 变得高效-心流(89 单位)
  16. 帮助他人(90 单位)
  17. 捡到钱(92 单位)
  18. 按摩(93 单位)
  19. 听音乐(96 单位)
  20. 冥想(100 单位)
  21. 挠痒痒(106 单位)
  22. 非常疲倦时入睡(117 单位)
  23. 和朋友玩耍(120 单位)
  24. 收到喜欢的人发来的信息(130 单位)
  25. 吃最喜欢的食物(130 单位)
  26. 锻炼(142 单位)
  27. 喝酒(153 单位)
  28. 收到工资(165 单位)
  29. 玩电脑游戏(176 单位)
  30. 非常憋的时候上厕所(179 单位)
  31. 加薪(184 单位)
  32. 通过一个考试(185 单位)
  33. 药品-吗啡(190 单位)
  34. 亲亲(192 单位)
  35. 滚床单(205 单位)
  36. 赢得赌约(210 单位)
  37. 抽烟(220 单位)
  38. 登顶珠峰(223 单位)
  39. 还钱(226 单位)
  40. 和一个人结婚(231 单位)
  41. 男性 gc(240 单位)
  42. 毒品-可卡因(325 单位)
  43. 女性 gc(480 单位)
  44. 彩票中奖(750 单位)
  45. 陷入爱河(760 单位)
  46. 毒品-甲基苯丙胺(1280 单位)

多巴胺还有一个重要机制——阈值。当我们完成一项高多巴胺分泌的活动后,往往会对那些分泌较低的活动失去兴趣和动力。比如,打了几场游戏(分泌 176 个单位的多巴胺),此时想要静下心来读一本书就变得异常困难。阅读显得枯燥乏味,而我们只想继续进行能带来更高刺激的活动,比如继续打游戏、刷视频。

如果想让读书变得有趣,关键在于降低多巴胺阈值。要做到这一点,需要给大脑一段「静止期」,这对很多人来说极其困难。或者通过一些「痛苦」的方式来调节,比如洗冷水澡、跑步等。这些活动能帮助大脑恢复平衡,降低对高刺激的依赖,从而让阅读等低多巴胺活动重新变得可行。

生命就是一团欲望,欲望得到了满足就会无聊,欲望得不到满足就会痛苦,人生就像钟摆一样,在痛苦和无聊之间左右摇摆。——叔本华

这种对「更多」的渴望,源自我们祖先遗留的基因——他们习惯于囤积贝壳、食物,总是不断寻找、收集、储藏。这种行为触发了大脑中的多巴胺分泌,让我们乐此不疲。然而,这种永不满足的机制,如今已经从生存的工具,变成了分散专注力的枷锁。

手机不适合专注阅读

手机和 APP 天生不适合从事需要专注的事情。小屏幕让阅读和处理图文内容变得吃力,用手指在屏幕上打字更是低效至极。手机的适用范围本应局限于电话、即时消息、扫码支付、随身音乐、闹钟日历、导航和天气等日常需求。而严肃的阅读、写作、剪辑调色等深度工作仍然离不开电脑(暂时不提纸质媒介),平板也许是勉强的替代,但手机显然不够适合。

我们要成为专注的人
拍摄于 2018 年,我的 iPhone se

厂商不断扩大屏幕尺寸,将手机卡在了 6 英寸这个临界点,使其拥有了更大的显示空间。然而,这种尺寸的手机介于传统小屏幕和平板之间,既无法完全胜任阅读和写作等严肃任务,又不失为碎片化娱乐的最佳工具。原本设计为方便生活的手机,如今却成为了消耗专注力的娱乐载体。从根本上来说,手机并不适合承载深度的思考与专注。

几乎快要放弃我所专注的博客

在 2020 年之前,我一直坚持着博客这种载体。从购买域名和服务器,到搭建程序、折腾主题,再到撰写文章和推广,我满怀期待,幻想着有一天身边的人会访问我的博客,阅读我的文字,与我讨论那些有趣的观点。然而,现实却给了我当头一棒。

我们要成为专注的人
拍摄于 2021 年,我的桌面和博客

博客始终像是自娱自乐的存在。身边的人从未在浏览器里输入过我精心挑选的域名。博客上的留言寥寥无几,也只是那几个博客圈的熟人偶尔互动。人们的注意力被吸引到了小红书、抖音、哔哩哔哩等平台,那里内容丰富、形式多样,又新奇又好看。谁还会耐心读枯燥的文字?又有谁会特意打开一个访问都显得麻烦的网站。

渐渐地,我感到心灰意冷。这些平台就像一座座喧嚣的集市,吸引着川流不息的人群,而我的博客却像一座孤岛,冷清、孤寂,无人问津。

文字更适合专注

我经常怀疑自己是否该放弃电脑端,转而投身移动端。经过这几年的体验,我发现各大平台的移动端阅读体验实在差强人意。如今大众主流平台几乎被短视频占据。不可否认,视频更适合传播,人们不需要滑动屏幕,只需跟随进度条和作者的节奏,就能看完整个内容。

但视频也有显而易见的缺点——相比文字,它的阅读效率极低。文字可以一目十行,快速提取重点,而视频即使倍速播放,也需要从头到尾看完才能获取信息。更糟糕的是,现在许多博主为了争取流量和互动,往往会在视频内容中加入大量冗余的「话术」和无意义的铺垫。这种「拖时长」的做法不仅浪费时间,还大大降低了内容的质量和阅读体验。

文字更适合思考

无论何时,图片的作用始终是在视觉上辅助传递信息,但信息的核心依然是文字。观看图片几乎无需思考,而阅读文字则需要经过大脑的深度处理,这一过程本质上就是思考。与视频的被动信息接收不同,阅读文字需要主动理解,能够随时停下来思考、做笔记、理清逻辑,加深记忆,并最终形成属于自己的知识体系。正如老话所说:「有些事情很久不做,就会变生疏,脑子都生锈了」这句话背后其实蕴含着科学依据。

当我们学习时,大脑会发生神经可塑性的变化,即在神经元之间建立新的连接。练习得越多,这些连接就越牢固,信息传输的速度和效率也随之提高,使我们在踢足球、阅读、绘画等方面不断精进。可以将神经元之间的连接比作森林中的小径——在没有路的森林中前行十分困难,需要不断开辟道路。而如果经常行走同一条路,路径会变得清晰易行。相反,如果长时间不使用,植被会重新覆盖,小路会慢慢消失。这与大脑的运作机制如出一辙——当你停止练习某项技能,神经元的连接会逐渐减弱,甚至最终被修剪、移除。这也是为什么整个夏天没有阅读的人,开学后会觉得读书变得困难。

因此,强化神经连接的关键策略就是反复激活。只有通过不断的重复和实践,大脑的通路才能变得更加稳固、高效,帮助我们在各种学习任务上取得更好的进步。

专注实事

当我洗澡、上厕所、散步或跑步时,思维总会变得异常活跃,许多困扰已久的事情,常常能在那短短的十几分钟里豁然开朗。可一旦坐下来,准备记录这些想法时,脑海却突然变得一片空白。接着,习惯性地打开小红书、哔哩哔哩、微信,开始毫无目的地在网络中游荡。

这与我最初使用电脑的习惯密切相关。刚接触电脑和互联网时,「探索新事物」是我的主要目的。我不停地使用搜索引擎,寻找那些有趣、好玩的网站,在一个个页面之间跳转,继续挖掘有趣的帖子。久而久之,每当坐在电脑前,我总会习惯性地开启探索模式,而不是将其作为创作的工具。

但在公司的环境中,情况却截然不同。每天的工作围绕着事务处理,电脑仅仅是一个高效的生产工具,目标明确,任务清晰,几乎不会被探索的冲动分散注意力。

改变习惯,是一个痛苦且漫长的过程,需要慢慢适应。 只有在不断的实践中,才能找到自己的方向,一次次试错,然后继续前进。相比于追逐流量的短视频,或许,静下心来写好博客,勤于阅读和思考,专注于深度、系统的事情,才是更值得坚持的长期之计。

集市终有散去的一天,摊位上曾琳琅满目的商品,最终都要被打包收走,人们各回各家。在互联网的世界里,或许我还有属于自己的一片自留地。

我们要成为专注的人
拍摄于 2021 年,从公司窗口看日落

使用Leafletjs实现足迹地图功能

2025年2月9日 11:40

我的博客上面挂着一个使用Leaflet实现的足迹地图功能,最近又给他添加了一些功能并且进行了一些美化。之前也有人问题这个怎么实现的,趁着刚折腾完来分享一下。

代码库的选择

早前一直想要做一个足迹的功能,像是国内的百度地图和阿里地图都有js的sdk,但是他们的sdk使用不简单,并且他们的地图只有国内的。后来了解过google map以及mapbox,但是都没有深入研究。后来看到博主水八口记使用了leaflet还比较简单,就使用这个库来实现了我的足迹功能。

地图图层

使用leaflet的一大好处是,你可以自由使用你想要的地图图层,对于符合Leaflet的地图瓦片地址我们是可以直接使用的,通常是类似这种格式的地址: https://{s}.somedomain.com/{foo}/{z}/{x}/{y}.png,其中的{z}/{x}/{y}是必须要支持的,leaflet会在运行的时候替换具体的值,从而请求对应的放大级别(z,zoom), 对应坐标(x, y)的瓦片进行渲染。

一般使用cartocdn提供的openstreetmap的地图时,是可以直接使用的,但是我们如果想要使用mapbox地图或者其他地图供应商的时候,就需要借助插件了,可以在这个页面看看有没有Plugins - Leaflet - a JavaScript library for interactive maps

对于地图图层,leaflet是支持同时加载多个图层的,比如说我可以添加一层底图再添加一层天气卫星图。

我们这里先看一下如何创建一个地图并且设置我们的地图图层. 首先需要引入leaflet的css和js文件

1
2
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY=" crossorigin=""/>
<!-- js引入一定要放到css的后面 --> <script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js" integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=" crossorigin=""></script>

之后,在我们需要显示地图的位置放一个div元素,并且设置一个id,这样我们在后面的js代码中才能控制它:

1
<div id="footprintmap"></div>

同时我们可以通过css设置这个容器的宽度高度:

1
2
3
4
#footprintmap {
width: 100%;
 height: 180px;
}

这些做完之后就可以在javascript中去创建地图对象,并且给它添加地图图层了:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
<script type="text/javascript">

 //地图的版权声明,使用三方地图数据出于对版权的尊重最好加一下
      var cartodbAttribution = '&copy; <a href="https://www.openstreetmap.org/copyright" target="_blank">OpenStreetMap</a> contributors, &copy; <a href="https://carto.com/attribution" target="_blank">CARTO</a>';
      var map = L.map('map', {gestureHandling: true, minZoom: 1, maxZoom: 14}).setView([33.3007613,117.2345622], 4); //创建地图,设置最大最小放大级别,setView设置地图初始化时候的中心点坐标和放大级别
      map.zoomControl.setPosition('topright'); //设置放大控制按钮的位置
      map.createPane('labels');

      map.getPane('labels').style.zIndex = 650;

      map.getPane('labels').style.pointerEvents = 'none';

      L.tileLayer('https://{s}.basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}.png', {

    attribution: cartodbAttribution

}).addTo(map); //添加地图图层到map对象当中

</script>

添加足迹点到地图中

经过以上的步骤我们就可以在网页上展示一个地图了,而我们实现足迹功能一般会给我们去过的地点打上标记。一种方法是给去过的城市做一个蒙层,一种方式是加一些点标记。这里先看加点标记的方法。

标记在Leaflet中称为Marker, 我们可以使用以下代码添加默认的Market:

1
marker = new L.marker([33.3007613,117.2345622]).bindPopup("popup text").addTo(map);

效果如下:

在上面我们通过bindPopup来设置点击Marker之后弹出的内容,其中我们是可以设置HTML元素的,因此我们就可以显示图片或者超链接之类的内容了。

如果不喜欢这个默认的蓝色Marker,也可以替换为图片。比如我用如下的代码就设置类一个svg图片作为Market标记图:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
function colorMarker() {
  const svgTemplate = `
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" class="marker">
      <path fill-opacity=".25" d="M16 32s1.427-9.585 3.761-12.025c4.595-4.805 8.685-.99 8.685-.99s4.044 3.964-.526 8.743C25.514 30.245 16 32 16 32z"/>
      <path stroke="#fff" fill="#ff471a" d="M15.938 32S6 17.938 6 11.938C6 .125 15.938 0 15.938 0S26 .125 26 11.875C26 18.062 15.938 32 15.938 32zM16 6a4 4 0 100 8 4 4 0 000-8z"/>
    </svg>`;
  const icon = L.divIcon({
    className: "marker",
    html: svgTemplate,
    iconSize: [28, 28],
    iconAnchor: [12, 24],
    popupAnchor: [7, -16],
  });
  return icon;
}

marker = new L.marker([lat, lng], {
    icon: colorMarker(),
  }).bindPopup(popupText).addTo(map);

主要是在前面创建marker的时候传的这个icon,你也可以传普通的图片。

如果我们需要展示多个点的时候,我们可以把这些点的数据存储成一个json,并且把他作为一个JavaScript对象加载,再读取他把每个点添加到地图中。 我就创建了一个points.js的文件保存所有的点:

1
2
3
let points = [
    ["<b>北京</b><i>Beijing</i><a href='/2025-01-beijing/'><img src='https://img.isming.me/photo/IMG_20250101_133455.jpg' />北京游流水账</a>", 40.190632,116.412144],
    ["<b>广州</b><i>Guangzhou</i>", 23.1220615,113.3714803],];

内容大概如上:

1
2
<!--加载点数据这样我们在javascript环境中就可以拿到points这个数组-->
 <script type="text/javascript" src="/points.js"></script>

以上加载了点数据,通过下面的代码来读取并且添加点:

1
2
3
4
5
6
7
for (let i = 0; i < points.length; i++) {
//循环遍历所有点,并且保存到如下三个变量中
  const [popupText, lat, lng] = points[i];
  marker = new L.marker([lat, lng], {
    icon: colorMarker(),
  }).bindPopup(popupText).addTo(map);
}

到此为止就完成了足迹点功能的开发。

去过的区域图层开发

而我们要实现去过的城市标记,这个时候就不是一个一个的点了,我们可能给去过的城市添加遮罩,这个其实就是给地图上画一个新的图层。每一个城市本质上就是许多个点围成的多边形,我们可以使用Leaflet提供的polygon方法来绘制,但是我们需要给把每个城市的多边形的各个顶点找到并且组织成一个数组,工作量真的是巨大的。

这样的难题我们不是第一个遇到的,前人已经遇到并且帮我们解决了。在2015年就有了GeoJson这种用Json描述的地理空间数据交换格式,他支持描述点,线,多边形。而Leaflet对齐也有支持。因此,我们只需要找到我们所需要的城市的geojson数据的MultiPolygon或者Polygon数据,就可以在Leaflet中进行绘制了。

对于中国的数据,我们可以在阿里云的datev平台进行下载,你可以省份数据或者按照城市甚至更小的行政单位下载数据。对于国外的数据可以到github上面去查找,这里是一份国家数据: datasets/geo-countries: Country polygons as GeoJSON in a datapackage

对于我们下载的中国的geojson数据,因为比较详细,也就比较大,我们可以使用mapshaper这个工具来对数据进行一些处理,直接使用Simplify功能,使用它减少点的数量,从而减少我们的文件的大小。

按照geojson文件格式,我们对于多个城市需要组成一个类似如下的json:

1
2
3
4
5
6
{
"type": "FeatureCollection", features: [
{"type": "Feature", "geometry": {"type": "Polygon", "coordinates": [[[88.40590939643968,22.55522906690669],[88.36498482718275,22.494854169816982],[88.28898205570562,22.51497913551355],[88.2714429545955,22.55235407180718],[88.32990662496253,22.55235407180718],[88.36498482718275,22.60410398359836],[88.35913846014606,22.62997893949395],[88.38837029532957,22.62710394439444],[88.40590939643968,22.55522906690669]]]}},
...
]
}

对于这样的一个json对象,我们就可以直接使用Leaflet的geojson文件进行加载,代码如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
function onEachFeature(feature, layer) { // does this feature have a property named popupContent?
 if (feature.properties && feature.properties.popupContent) {
 layer.bindPopup(feature.properties.popupContent); //从json文件中读取属性进行popup展示
 }
}

var geojson = L.geoJSON(areas, {
 onEachFeature: onEachFeature,
  style: function (geoJsonFeature) {
    return {
      color: '#ffcc80', //设置遮罩的颜色
      fillOpacity: 0.4, //设置透明度
      stroke: false, //是否要显示边缘线
    };
  }
}).addTo(map);

对于geojson我们也可以在properties中设置弹框的内容进行展示。

总结

到这里我们就完成了基于leaflet的一个足迹地图,既包括足迹点,也包括去过的城市的遮罩。而geojson和Leaflet的功能远远不止这些,感兴趣的可以去看相关文档。另外因为我使用的地图是openstreetmap的数据,关于中国领土有争议的部分标记不正确,这个不在我的解决能力范围之内,只能暂且使用,但是不代表本人观点。

参考资料:

  1. Tutorials - Leaflet - a JavaScript library for interactive maps
  2. https://tomickigrzegorz.github.io/leaflet-examples/
  3. GeoJSON - 维基百科,自由的百科全书
  4. DataV.GeoAtlas地理小工具系列

看完评论一下吧

WordPress插件HTACCESS Manager

2025年11月19日 16:59
AI智能摘要
HTACCESS Manager是一款适用于Apache及LiteSpeed服务器的WordPress插件,旨在安全智能地管理.htaccess文件中的重定向规则。支持强制HTTPS、WWW与根域名互跳、二级域名配置,并自动生成优化规则,兼容多种环境且不影响其他插件规则。提供手动复制、自动更新与安全移除功能,确保规则准确生效。需注意备份.htaccess文件,不适用于Nginx服务器。
— 此摘要由AI分析文章内容生成,仅供参考。

我写这个插件的目的,就是为了不去手动直接编辑.htaccess文件。

本插件适用于Apache、LiteSpeed(含OpenLiteSpeed和LiteSpeed Enterprise)服务器,也适用于其他兼容Apache规则的服务器。

以下内容为AI通过阅读源代码后生成,并经本人细致修改。


HTACCESS Manager

一个专业的WordPress插件,用于智能管理.htaccess文件中的重定向规则。支持HTTPS强制重定向、WWW与根域名跳转配置,以及二级域名站点支持。

功能特点

🔒 强制HTTPS重定向

  • 自动将所有HTTP请求重定向到HTTPS
  • 确保网站安全连接

🌐 灵活的域名跳转配置

  • WWW跳转到根域名www.example.comexample.com
  • 根域名跳转到WWWexample.comwww.example.com
  • 自由选择跳转方向

🏷️ 二级域名支持

  • 专门针对二级域名站点的优化配置
  • 启用后只强制HTTPS,不处理WWW跳转

⚡ 智能规则管理

  • 自动生成优化的.htaccess规则
  • 不干扰其他插件的现有规则
  • 安全的规则添加和移除机制

🛡️ 安全可靠

  • Must-use插件支持,确保高可靠性
  • 精确的规则匹配,避免误删其他配置
  • 完整的卸载清理机制

安装方法

方法一:手动安装

  1. 下载插件ZIP文件
  2. 在WordPress后台进入【插件】→【安装插件】→【上传插件】
  3. 选择ZIP文件并上传
  4. 激活插件

方法二:FTP安装

  1. 解压插件文件到 wp-content/plugins/htaccess-manager/
  2. 在WordPress后台【插件】页面激活”HTACCESS Manager”

使用方法

基本配置

  1. 进入【设置】→【HTACCESS 管理】
  2. 根据您的需求配置选项:
    • 是否为二级域名:如果使用类似 sub.domain.com 的地址请启用
    • 重定向类型:选择WWW与根域名的跳转方向
    • 自动更新:启用后设置更改时自动更新.htaccess文件

配置示例

场景1:主域名站点,WWW跳转到根域名

www.example.com → example.com
http → https

配置:

  • 是否为二级域名:❌ 否
  • 重定向类型:✅ WWW跳转到根域名

场景2:主域名站点,根域名跳转到WWW

example.com → www.example.com
http → https

配置:

  • 是否为二级域名:❌ 否
  • 重定向类型:✅ 根域名跳转到WWW

场景3:二级域名站点

sub.example.com → https://sub.example.com
(不处理WWW跳转)

配置:

  • 是否为二级域名:✅ 是
  • 重定向类型:自动禁用

手动操作

  • 复制规则:手动复制生成的规则到.htaccess文件
  • 手动更新:强制更新.htaccess文件
  • 移除规则:安全移除所有本插件添加的规则

生成的规则示例

WWW跳转到根域名 + HTTPS

# BEGIN HTACCESS Manager
RewriteEngine On

# 同时处理 HTTPS 和 WWW 重定向
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} ^www\. [NC]
RewriteCond %{HTTP_HOST} ^(?:www\.)?(.+)$ [NC]
RewriteRule ^ https://%1%{REQUEST_URI} [L,R=301]
# END HTACCESS Manager

二级域名 + 只强制HTTPS

# BEGIN HTACCESS Manager
RewriteEngine On

# 强制HTTPS重定向(二级域名)
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# END HTACCESS Manager

兼容性

测试环境

  • ✅ WordPress 5.0+
  • ✅ PHP 7.4+
  • ✅ Apache 2.4+
  • ✅ LiteSpeed(含OpenLiteSpeed和LiteSpeed Enterprise)服务器
  • ✅ 多站点网络

插件兼容

  • ✅ 与大多数缓存插件兼容
  • ✅ 与安全插件兼容
  • ✅ 不影响其他.htaccess规则生成插件

故障排除

常见问题

Q: 插件激活后网站出现重定向循环? A: 检查服务器是否已配置SSL证书,或尝试清除浏览器缓存。

Q: .htaccess文件无法写入? A: 确保.htaccess文件权限设置为644,或使用手动复制功能。

Q: 规则没有生效? A: 确认服务器支持mod_rewrite模块,检查Apache配置。如果是OpenLiteSpeed服务器,可能需要重启OpenLiteSpeed服务。

Q: 如何恢复默认设置? A: 停用并重新激活插件,或使用”移除规则”功能。

日志检查

如果遇到问题,请检查:

  1. WordPress调试日志
  2. 服务器错误日志
  3. .htaccess语法验证

开发者信息

文件结构

htaccess-manager/
├── htaccess-manager.php     # 主插件文件
├── readme.md                 # 说明文档
└── (自动生成)
  └── mu-plugins/
      └── htaccess-helper.php # Must-use插件

钩子函数

插件提供以下WordPress钩子:

  • htaccess_manager_before_update – 规则更新前
  • htaccess_manager_after_update – 规则更新后

自定义开发

如需扩展功能,可参考插件中的规则生成逻辑:

$manager = new HTACCESS_Manager();
$rules = $manager->generate_htaccess_rules();

版本历史

v1.0.2 (当前版本)

  • 增强规则移除安全性
  • 改进空行处理
  • 优化MU插件逻辑

v1.0.1

  • 修复规则冲突问题
  • 添加内容预览功能
  • 改进用户界面

v1.0.0

  • 初始发布
  • 基础重定向功能
  • Must-use插件支持

技术支持

如果您遇到问题或需要帮助,请:

  1. 查看README文档
  2. 检查WordPress错误日志
  3. 联系服务器管理员确认Apache配置

许可证

GPL v2或更高版本

贡献

欢迎提交Issue和Pull Request来帮助改进这个插件。

注意:(1)在使用本插件前,请务必备份您的.htaccess文件。

(2)本插件不适用于Nginx服务器。


下载地址

点击下载或将以下链接复制到浏览器地址栏并敲击回车键:

https://git.localhost.observer/linhaicaoyuan/htaccess-manager

不合群

2025年11月15日 17:19
AI智能摘要
作者自述自己和所写博客均不合群,以“只为苍生说人话”为信条,暗示其言论追求真实、独立,不迎合主流或群体意志,展现出与大众保持距离的清醒立场。
— 此摘要由AI分析文章内容生成,仅供参考。

我不是一个合群的人。

我在博客上写的文章也是不合群的。

单凭我以“只为苍生说人话”为信条这一点,就很不合群了,对不对?

Typecho主题SimpleBlog开源

2025年8月13日 22:15
AI智能摘要
2025年8月初,作者将一款心仪的WordPress主题移植至Typecho平台,并将其命名为SimpleBlog。移植过程耗时约2.5天,其中评论系统适配最为耗时。该主题延续了原作简约风格,具备响应式布局、自定义侧边栏和社交媒体集成等特点,并针对中文显示进行了优化。作者在获得原作者Anders Norén的许可后,已基于GPL 2.0许可证将其开源,旨在为注重内容呈现的Typecho用户提供一个轻量且专注的选择。
— 此摘要由AI分析文章内容生成,仅供参考。

一次跨越平台的主题移植手记

2025年八月初,我将一款心仪的WordPress主题移植至Typecho平台,并应用于我的技术博客“林海爱折腾”。

在此之前,这款WordPress主题已在我的博客上使用了近一年半的时间(自2024年1月19日至2025年8月11日)。为了获得更好的中文显示效果并修复一些已知问题,我曾对其进行过一番本地化修改,更加适配汉字的显示与阅读美感。

将这款主题移植到Typecho平台的想法,源于两个简单的初衷:

第一,是对这款主题简约风格的喜欢;

第二,我这可是个技术博客,不亲手移植一个主题,怎么对得起“技术”二字呢?(斜眼笑)

整个移植过程由手动编码与AI辅助相结合。主题框架的搭建本身颇为迅速,大约只用了两小时;然而,后续修复bug,却前后持续了一坤天(2.5天)。

这次的移植过程,让我对两个平台的技术框架有了更深的认识。WordPress将诸多功能(如评论系统、jQuery库等)高度封装,开发者仅需一行或寥寥数行代码便可调用;区块主题更是进一步简化,整个主题的源代码只有数百行,却可以实现高度的可定制化。相比之下,Typecho则相对原始,许多功能的实现都需要开发者从零开始构建样式与逻辑,代码的编写显得细致和繁复。对于编程基础几乎为零的我,这个过程稍有不慎便会“落霞与bug齐飞”,过程相当痛苦。

这里我特别说明一件事——评论区的适配耗费了最多的精力,前后投入了约一天半的时间。若完全沿用原主题当中WordPress封装的评论样式,会导致点击“回复”时评论框无法跟随;若尝试用JavaScript修正此问题,又会引发二级及更深层级评论的显示异常。这是一个AI都束手无策的Bug。我最终选择妥协,选择了一个功能稳定且视觉上同样协调的方案。

主题移植完成并稳定运行数日后,一个有趣的插曲,促使我更换了本博客的主题——由于两个博客的主题外观极为相似,仅在header区域有配色差异,我经常会在不经意间混淆它们,输入错误的后台地址,然后看到那抽象的404页面。为了避免再出现这样的事情,更换主博客的主题,成了一个直接有效的选择。

移植后的主题在几天的实际使用中,未再发现明显的问题。当然,我深知代码中或许还残留着一些移植过程中尚未完全清理的冗余代码,只是这些代码完全不影响博客的正常运行与速度。我希望它能对他人有所助益,我决定将其开源。

以下,是对这款移植主题的详细介绍。其中,“SimpleBlog主题介绍”这部分内容,是在AI助手Craft在阅读源代码分析的基础上,由我人工修订而成。


SimpleBlog主题介绍

主题介绍

SimpleBlog是一款为Typecho博客系统设计的简约风格主题,它移植自设计师Anders Norén的经典作品。这款主题追求“简约而不简陋”的设计哲学,旨在为内容创作者提供一个干净、清晰且能全身心专注于文字的展示平台。

设计特点

1. 极简设计风格

SimpleBlog采用极简主义美学,审慎地去除了多余的视觉元素,引导读者的目光聚焦于内容本身。以黑白为主的配色方案,辅以恰到好处的留白与精心编排的版式,共同营造出一种专业且宁静的阅读氛围。

2. 响应式布局

主题全面支持响应式设计,确保在桌面电脑、平板或是智能手机上,都能呈现出一致而优雅的浏览体验。在移动设备上,导航菜单将自动收敛为汉堡菜单,以维持界面的整洁与空间的通透感。

3. 自定义侧边栏

桌面端采用了固定侧边栏设计,其背景颜色支持用户自定义,默认为沉静的深色(#121212)。侧边栏整合了网站标题、描述及导航菜单,功能清晰,简明实用。

4. 社交媒体集成

主题内置了社交媒体链接功能,支持Twitter、Facebook和GitHub等常用平台,为博主与读者之间建立更广泛的连接提供了便利。

5. 优雅的文章展示

文章页面的设计简洁而大方,标题醒目,正文排版清晰易读。页面支持特色图片的展示,能够有效提升文章的视觉吸引力。同时,文章的分类、发布时间等元信息也以直观的方式呈现。

技术特点

1. 轻量化设计

主题整体代码结构清晰,无冗余功能和复杂的外部依赖,确保了页面的快速加载,对服务器资源消耗极低。

2. 标准化HTML5/CSS3

主题基于最新的HTML5与CSS3标准进行构建,保证了良好的浏览器兼容性与未来的可扩展性。

3. 自定义字段支持

为方便博主更灵活地控制文章的展示形态,主题支持多种自定义字段,例如文章缩略图(thumbnail)与文章摘要(excerpt)等。

下载地址

详见下载地址(下载地址1下载地址2)内的主题文档。

适用场景

SimpleBlog主题尤其适合以下类型的博客:

  1. 个人日志:记录生活点滴、心情随笔的个人空间。
  2. 技术博客:分享编程知识、技术教程的专业园地。
  3. 文字创作:专注于小说、散文等以文字为核心的创作平台。
  4. 极简主义者:追求简约设计与内容至上理念的博客作者。

总结

SimpleBlog主题秉承“简约而不简陋”的设计理念,为Typecho用户提供了一个专注于内容、设计精美且易于使用的博客主题。它没有华丽的动画与繁复的设置,但在每一处简约的背后,都体现了对用户体验和内容呈现的深思熟虑。

如果您是一位注重内容质量,希望读者能够专注于您的文字,而非被纷繁的设计元素分散注意力的创作者,SimpleBlog或许会是一个理想的选择。


主题改造详情

为了让这款源于WordPress的主题能在Typecho上呈现出理想的状态,我进行了一系列细致的调整。

删减的功能

1.统一日期格式:移除了原主题中 j M / M j 等多种英文日期格式切换选项,统一为更符合中文阅读习惯的 n月j日 格式。

2.移除“相关文章”模块:原主题的相关文章功能对缩略图有硬性要求,若文章缺少缩略图,会影响布局的美观。相比之下,一些付费主题(如Typology)在此处的处理更为灵活优雅。

原主题的相关文章样式

3.取消首页标题显示:据观察,启用此功能的用户不多。我曾在自己的博客上短暂保留此设计,以审视其视觉效果,但最终还是决定取消,直至更换新主题。(请见图片中用横线标注的位置)

横线标注的是首页标题显示效果

4.简化移动端搜索交互:原主题在移动端使用了Ajax即时搜索,但其体验并不完善——仅能搜索标题,无法覆盖内容。考虑到Typecho需自行适配Ajax,我将其简化为更传统、更高效的“输入+回车”搜索模式。

优化的功能

  1. 社交链接后台化:由于Typecho缺乏原生的菜单系统,我将社交链接的设置移至后台。预设了GitHub、Twitter和Facebook三个输入框,通过Font Awesome字体库渲染图标。若留空,则侧边栏仅显示搜索按钮。
  2. 中文字体适配:对主题的字体族和字号进行了微调,使其在中文环境下显示更为和谐、易读。
  3. 提升视觉统一性:新增了一项功能,即用户在后台设定的主题色,现在会自动同步应用于评论按钮、超链接以及文本选中时的背景色,从而增强了整体视觉的一致性。
  4. 调整分割线样式:将首页及归档页文章标题间的分割线由实线改为虚线,个人认为这样更加美观,从而将焦点聚焦在内容上。
  5. 文章置顶:配合我修改的文章置顶插件,可利用主题内置样式显示置顶文章。

移植主题合法吗?

Of course!

原主题基于GPL 2.0许可证发布,该许可证赋予了用户自由使用、修改和分发软件的权利。

同时,我也需要履行GPL的相应义务:我修改后的版本同样须在GPL 2.0许可证下发布,并且必须保留原作者的版权声明。

为了审慎起见,我特意致信原作者,并在两天后收到了他的积极回复:

Sure, go right ahead! All of my themes are released under the GPL license, which means you can port them as long as you also release the port under that license.

——Anders Norén

如果您决定使用这款主题,也请务必遵守GPL 2.0许可证的相关条款

如您喜欢这款主题,我会倍感欣慰。

一款简洁、美观的 WordPress 友情链接插件

2025年8月5日 10:38

近日,我开发了一款全新 WordPress 友情链接插件。该插件简洁、美观、易于使用。

可以访问以下链接查看实际展示效果:友情链接展示页

插件特性

  • 响应式布局:在桌面端默认每行展示 3 个链接,并能根据屏幕尺寸自动调整,在平板和手机上也能完美呈现。
  • 信息展示丰富:每个链接均会展示对方网站的 Favicon(头像)和博客名称,一目了然。
  • 灵活的排序方式:支持固定排序和随机排序两种模式。设置为随机排序后,每次刷新页面都会带来全新的链接顺序。
  • 智能头像获取:自动通过 favicon.im 服务抓取网站头像。同时支持手动指定头像链接,或在留空时显示默认头像。
  • 简洁的管理后台:后台管理界面操作直观,美观大方。
  • 纯净无残留:启用时自动创建专属数据表,禁用时彻底删除,不在数据库留下任何冗余数据。
  • 数据轻松迁移:内置导入/导出功能,方便备份和恢复友链数据。

使用方法

1. 下载与安装

可从以下链接下载该插件:点此下载

下载 .zip 压缩包后,在 WordPress 后台的“插件”—>“安装插件”页面上传并启用。

2. 插入短代码 (Shortcode)

在任意页面或文章中插入短代码即可展示友情链接。

如何在编辑器中插入?

  • Gutenberg (区块编辑器):添加“自定义 HTML”区块,将短代码粘贴进去即可。
  • Classic Editor (经典编辑器):直接在文本编辑模式下粘贴短代码。

未来计划

计划将此插件移植到 Typecho 平台。

致谢

在插件的开发过程中,AI 提供了巨大帮助,特此感谢科技的力量。

经过两天的密集调试,目前插件运行稳定,暂未发现明显 Bug。欢迎提出宝贵的意见和建议,或是一同参与改进,让它在保持简洁、美观、易于使用的同时可以变得更好。

“林海爱折腾”上线

2025年8月4日 16:10

林海爱折腾”这个站点酝酿很久,在2025年7月31日终于正式上线了。

很多次告诉自己不要再折腾了,可是当出现让自己感兴趣的东西时,还是忍不住要动手。比如,遇到一个样式钟意的主题,就必须动手修改一番,直到它成为自己最喜欢的样子;又比如,心血来潮利用 AI 制作了一个样式精美的友情链接展示插件;在折腾 VPS 的过程中,也总会遇到些值得记录和分享的问题。

我的主博客(lhcy.org)是一个非常棒的平台,记录着我的生活与感悟。但我不希望让这些时效性强、略显硬核的技术类文字冲淡它的主题。因此,我建立了“林海爱折腾”这个全新的博客,专门用来记录我在技术世界里的每一次探索、每一次尝试和每一次“折腾”。

至于技术选型,这个新站最终选择了 Typecho。熟悉我的朋友可能知道,我的主博客曾因插件生态等原因从 Typecho 迁移到了 WordPress。但时过境迁,如今 Typecho 的许多问题要么可以绕过,要么得到了解决,它依然是我心中轻量、高效的代表。它现在使用的主题源自 Github,在AI的协助下修复了十几个 Bug 并按我的心意调整后,它重获了新生。

也许你会问,我自己也发布过三个 Typecho 主题,为何不直接用呢?不怕笑话,时过境迁,心境变了,我已经不喜欢当初的样式了。当然,如果你喜欢,它们在 PHP 8.x 环境下依然能稳定运行。

“折腾”不止,探索不息。希望“林海爱折腾”这个小站,能成为我记录技术足迹的专属空间,也希望能在这里遇到同样热爱探索的你。

VitePress 添加友链界面

VitePress 添加友链界面 &ZeroWidthSpace;

效果预览

友链数据存储 &ZeroWidthSpace;

友链数据通常是经常需要添加和修改的,所以我们不能直接写死到页面上。这里我们单独提一个文件去存储友链数据,并且友链数据的格式基本也是类似的。

新建 links.md 文件,内容如下:

docs/pages/links.md
md
---
layout: weiz-link
title: 我的友链
description: 这是唯知笔记网站的友链界面,xxxxxx

links:
- title: 鸣谢
  desc: 建站中学习和使用了以下博客/网站的技术和分享,特别鸣谢!🫡
  list:
    - name: VitePress
      link: https://vitepress.dev/zh/
      avatar: https://vitepress.dev/vitepress-logo-mini.svg
      irregular: true
      descr: 由 Vite 和 Vue 驱动的静态站点生成器
    - name: VitePress 快速上手教程
      link: https://vitepress.yiov.top/
      avatar: https://vitepress.dev/vitepress-logo-mini.svg
      irregular: true
      descr: 如果你也想搭建它,那跟我一起做吧
- title: 传送门
  desc: 聚集众多优秀独立博客,随机传送 🚀
  list:
    - name: 十年之约
      link: https://foreverblog.cn/go.html
      avatar: https://img.foreverblog.cn/logo_en_default.png
      descr: 十年之约,奔赴某个独立博客的十年
      irregular: true
    - name: Web Teleporter
      link: https://webteleporter.top/
      avatar: https://webteleporter.top/img/logo.png
      descr: 独立博客传送门
---

注:irregular 字段是对特殊图片进行处理

友链页面创建 &ZeroWidthSpace;

Vitepress 中创建单独页面的方法,可以参考 VitePress 新建页面和注册组件

新建组件 &ZeroWidthSpace;

新建一个文件夹 docs/.vitepress/theme/components/WLink 用来存放友链组件

vue
<template>
  <div id="main">
    <div class="title">
      <h1>我的友链</h1>
    </div>
    <div class="content">
      <div class="link" v-for="(item, index) of linksData" :key="index">
        <div class="title-wrapper">
          <h3>{{ item.title }}</h3>
        </div>
        <p>{{ item.desc }}</p>
        <div class="link-list">
          <el-row class="container-row" :gutter="24">
            <el-col v-for="temp of item.list" :key="temp.link" class="link-wrapper" :xs="24" :sm="12" :md="6">
              <LinkSite :data="temp" />
            </el-col>
          </el-row>
        </div>
      </div>
    </div>
    <div class="message">
      <div class="title-wrapper">
        <h3>留链吗</h3>
      </div>
      <p>留恋的小伙伴,想要和我做友链 💞</p>
      <div class="card">
        <p>留言请参照置顶评论里的格式,siteshot 字段非必需</p>
        <Twikoo />
      </div>
    </div>
  </div>
</template>

<script setup lang='ts'>
import { useData } from 'vitepress'
import LinkSite from './LinkSite.vue'
import Twikoo from '../WTwikoo/index.vue'
import { LinkList } from '../../type/WLink'

const { frontmatter: fm } = useData()

const linksData = fm.value.links as LinkList[]
</script>

<style>
.message .twikoo {
  margin-top: 0;
}
</style>
<style lang='scss' scoped>
.content {
  margin-top: var(--weiz-spacing-8xl);
  margin-bottom: var(--weiz-spacing-12xl);
}
.title-wrapper {    
  margin: var(--weiz-spacing-8xl) 0;
  height: 1px;
  background: var(--vp-c-text-5);
  position: relative;
  > h3 {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%) translateY(-50%);
    background: var(--vp-c-bg-soft);
    padding: 0 var(--weiz-spacing-8xl);
    font-size: var(--weiz-font-size-xl);
    font-weight: var(--weiz-font-weight-bold);
    line-height: var(--weiz-text-xl-line-height);
    text-align: center;
  }
  &+p {
    margin-bottom: var(--weiz-spacing-6xl);
    font-weight: var(--weiz-font-weight-medium);
    text-align: center;
  }
}
.link-list .el-col {
    margin-bottom: var(--weiz-spacing-6xl);
}
.card {
  padding: var(--weiz-spacing-6xl);
  border-radius: var(--weiz-card-border-radius);
  background-color: var(--vp-c-bg);
  box-shadow: var(--weiz-shadow);
  > p {
    margin-bottom: var(--weiz-spacing-6xl);
  }
}
</style>
vue
<template>
  <div class="link-item">
    <a :href="data.link" :title="data.name" target="_blank">
      <div class="link-icon">
        <img v-if="!imageFailed" :class="{ irregular: data.irregular }" :src="data.avatar" @error="handleImageError()" :alt="data.name" />
        <!-- 替代内容:显示首字母 -->
        <span v-else class="iconPlaceholder">{{ data.name.charAt(0) }}</span>
      </div>
      <div class="link-info">
        <div class="link-name">{{ data.name }}</div>
        <div class="link-desc" :title="data.descr">{{ data.descr }}</div>
      </div>
    </a>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { Link } from '../../type/WLink'

const props = defineProps<{ data: Link }>()
const data = props.data

// 记录图片加载状态
const imageFailed = ref(false)

// 处理图片加载失败
const handleImageError = () => {
  imageFailed.value = true // 更新加载状态
}
</script>

<style lang="scss" scoped>
.link-item {
  position: relative;
  overflow: hidden;
  width: 100%;
  height: 100px;
  display: inline-block;
  border-radius: var(--weiz-card-border-radius);
  background-color: var(--vp-c-bg);
  box-shadow: var(--weiz-shadow);
  &:hover {
    .link-icon > img,
    .iconPlaceholder {
      transform: scale(2.4);
      &.irregular {
        transform: scale(1.6);
      }
    }
    .link-info {
      margin-left: 20px;
    }
  }
  > a {
    position: relative;
    z-index: 1;
    height: 100%;
    display: flex;
    align-items: center;
  }
  .link-icon {
    flex: 0 0 auto;
    width: 100px;
    height: 100%;
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: var(--weiz-transition-6);
    > img {
      width: 60px;
      height: 60px;
      border-radius: 50%;
      vertical-align: top;
      object-fit: cover;
      transition: var(--weiz-transition-6);
      &[src^="https://vitepress.dev/"]
      {
        border-radius: 0;
      }
      &.irregular {
        object-fit: contain;
      }
    }
    .iconPlaceholder {
      font-size: var(--weiz-font-size-3xl);
      font-weight: var(--weiz-font-weight-bold);
      display: inline-block;
      transition: var(--weiz-transition-6);
    }
  }
  .link-info {
    flex: 1;
    height: 100%;
    display: flex;
    flex-direction: column;
    justify-content: center;
    transition: var(--weiz-transition-6);
  }
  .link-name {
    width: 100%;
    font-size: var(--weiz-font-size-st);
    line-height: var(--weiz-text-st-line-height);
    font-weight: var(--weiz-font-weight-semibold);
    margin-bottom: var(--weiz-spacing-2xl);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    transition: var(--weiz-transition-6);
  }
  .link-desc {
    width: 100%;
    padding-right: var(--weiz-spacing-6xl);
    font-weight: var(--weiz-font-weight-semibold);
    color: var(--vp-c-text-2);
    line-height: var(--weiz-text-xs-line-height);
    overflow: hidden;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 3;
    line-clamp: 3;
    transition: var(--weiz-transition-6);
  }
}
</style>
ts
export interface LinkList {
  // 标题
  title: string
  // 描述
  desc: string
  // 列表
  list: Link[]
}

export interface Link {
  // 站点名称
  name: string
  // 站点链接
  link: string
  // 头像/站点logo
  avatar: string
  // 头像不规则
  irregular?: boolean
  // 站点描述
  descr: string
  // 站点缩略图
  siteshot?: string
}

组件注册 &ZeroWidthSpace;

新建的组件需要在主题配置中心进行注册,注册后就可以在 md页面 中使用了。比如我们 links.md 文件中的开头 layout: weiz-link

docs/.vitepress/theme/index.ts
ts
import WLink from './components/WLink/index.vue' // 友链页

export default {
  enhanceApp({ app }) {
    // 注册全局组件
    app.component('weiz-link', WLink)
  }
}

附带评论 &ZeroWidthSpace;

在组件内集成评论,直接使用评论组件,比如我的是 <Twikoo /> 评论。
Twikoo 评论的集成方式,可参考 VitePress 集成 Twikoo 评论

VitePress 优化代码块样式

VitePress 优化代码块样式 &ZeroWidthSpace;

主要目标:1. 代码块支持显示所属文件,并显示文件类型图标 ;2. 将默认代码块样式修改为 mac风格

效果展示

实现 &ZeroWidthSpace;

1. 安装 vitepress-plugin-group-icons &ZeroWidthSpace;

VitePress 官方也在用的代码块插件,直接实现我们的第1个小目标

sh
pnpm add vitepress-plugin-group-icons

配置 config,并导入主题配置中

ts
import { defineConfig } from 'vitepress'
import { groupIconMdPlugin, groupIconVitePlugin } from 'vitepress-plugin-group-icons'

export default defineConfig({
  markdown: {
    config(md) {
      md.use(groupIconMdPlugin)
    },
  },
  vite: {
    plugins: [
      groupIconVitePlugin()
    ],
  }
})
ts
import Theme from 'vitepress/theme'
import 'virtual:group-icons.css'

export default Theme

2. 修改为mac风格 &ZeroWidthSpace;

新建 code.scss 文件并导入主题配置中

scss
:root {
  --macos-window-red: #FE5450;
  --macos-window-yellow: #FFB23B;
  --macos-window-green: #30C045;
}

<!--@include: @/.vitepress/theme/style/code.scss#code-block-->
ts
import './style/code.scss'

VitePress 集成 Twikoo 评论

VitePress 集成 Twikoo 评论 &ZeroWidthSpace;

Twikoo 是一个简洁、安全、免费的静态网站评论系统。

主要特点:免费搭建,部署简单,功能很完善,隐私护安全,通知发邮件,管理有内嵌,总之免费又方便

关于后端部署,大家可以看官网,或者这篇 VitePress 资源汇总 - 使用 Twikoo 评论系统。 推荐使用 Vercel 部署 (免费,需配置域名加速访问) 或者 Netlify 部署(免费)。

这篇主要讲 Vitepress 前端如何集成。

预览 &ZeroWidthSpace;

集成步骤 &ZeroWidthSpace;

1. 安装 twikoo &ZeroWidthSpace;

sh
pnpm install twikoo

2. 初始化 twikoo 组件 &ZeroWidthSpace;

.vitepress/theme/components/Twikoo.vue
vue
<template>
  <div id="twikoo"></div>
</template>

<script setup lang="ts">
import { onMounted, watch } from 'vue'
import { useRoute } from 'vitepress'

const route = useRoute()

const initTwikoo = async () => {
  // 判断是否在浏览器环境中
  if (typeof window !== 'undefined') {
    const twikoo = await import('twikoo')
    twikoo.init({
      envId: 'https://twikoo.xxx.com/', // 换成你自己配置的域名
      el: '#twikoo'
    })
  }
}

// 监听路由刷新评论
watch(route, () => {
  initTwikoo()
})

onMounted(() => {
  initTwikoo()
})
</script>

3. 组件插入 Layout 插槽 &ZeroWidthSpace;

.vitepress/theme/components/Layout.vue
vue
<script setup lang="ts">
import DefaultTheme from 'vitepress/theme'
import Twikoo from './Twikoo' //评论组件
</script>

<template>
  <DefaultTheme.Layout>
    <template #doc-after>
      <Twikoo />
    </template>
  </DefaultTheme.Layout>
</template>

美化样式 &ZeroWidthSpace;

1. 配置 twikoo &ZeroWidthSpace;

twikoo 配置面板里的插件页签,选择代码高亮主题 coy,代码复制插件 copyButton

2. 自定义 css &ZeroWidthSpace;

以下代码中使用的部分变量,可利用开发者工具在本站查找或自己配置。

.vitepress/theme/style/custom.scss
scss
<!--@include: @/.vitepress/theme/style/custom.scss#Twikoo-->

3. css 注入主题配置 &ZeroWidthSpace;

.vitepress/theme/index.ts
ts
// 全局样式
import './style/custom.scss'

参考文档 &ZeroWidthSpace;

Twikoo 官方文档

VitePress 集成 twikoo 参考解决方案

❌