阅读视图

发现新文章,点击刷新页面。

出租房子的教训: 让中介找人上门换一个水龙头竟然要204英镑!


我老婆在剑桥Bar Hill有一套出租房/Buy to Let,但她不想管理。每次房子出问题需要修理时,中介都会联系我。有房子出租闹心的事情真是多,真的印证了那句话:操着卖白粉的心,挣着卖白菜的钱!每次最怕的就是接到中介的电话,因为一有电话就意味着房子有问题要修/要花钱了。

几天前,中介打电话来说,租户反映厨房水龙头打开时有奇怪的声音,挺吓人的。我当时回复他们说我会找个水管工/Plumber第二天过去看看。但挂了电话后,我联系了我认识的中国装修师傅。他手艺很好,在英国生活了几十年,以前帮我家做过不少装修。不过他这次没时间,也不太愿意接这种小活。

前两年这个师傅给我们家换地板,翻新三个厕所,还有就是阳光房地板,门前加建了个Porch等,最近房子也在重新折腾装修,之后弄完再详细说说。

我懒得在网上(比如 MyBuilder.com)再找其他人,就让中介安排了他们自己的工人。

后来,中介回电说水管工已经在房子里了,并报价修理费为170英镑,加上VAT税后(20%)一共204英镑。如果不修,也要付140英镑的上门费,加税后差不多168英镑。觉得价格有点高,但也只能咬牙同意了。

其实让我不爽的是自己为了省事,最后只能任人宰割。老外只要上门就收钱,我当时虽让中介确认报价,但没问上门费的问题,现在骑虎难下。听说中介找的合同工都比较贵。

那个房子一共让中介找过四五次人修房子(各种问题:上次厨房水管堵了,被收了400多英镑,据说水管工花了三小时通下水道),主要是因为这次我认识的师傅没时间。其实我还认识另一个会修房子的中国人,这样看来,以后可能不会再让中介找人了。

去年冬天,因为恶劣天气,房子顶有一小块掉了,中介找人报价要1800英镑,还好我没同意。后来找了个中国师傅,才花了350英镑,而且当时有Landlord保险还全额报销了。

bar-hill-house-repair-ceiling-scaled 出租房子的教训: 让中介找人上门换一个水龙头竟然要204英镑! 房子 智商税 杂乱 生活 资讯

英国去年冬天刮大风, 房子顶上掉下来一块, 修好后(右图) 完好如初, 花了350英镑, 后来通过房东的出租保险全部索赔成功了.

PS:我发了封邮件给中介小小抱怨了一下。

Hi there,

I hope you’re well. I was surprised by the contractor’s call-out fee today (£140 + VAT) for attending 66 Watermead.

In the future, could you either provide a few options or select the most cost-effective contractor for us? I trust that we’re on the same page.

房子那些事

本文一共 776 个汉字, 你数一下对不对.
出租房子的教训: 让中介找人上门换一个水龙头竟然要204英镑!. (AMP 移动加速版本)

扫描二维码,分享本文到微信朋友圈
75a5a60b9cac61e5c8c71a96e17f2d9c 出租房子的教训: 让中介找人上门换一个水龙头竟然要204英镑! 房子 智商税 杂乱 生活 资讯
The post 出租房子的教训: 让中介找人上门换一个水龙头竟然要204英镑! first appeared on 小赖子的英国生活和资讯.

相关文章:

  1. 按揭贷款(房贷,车贷) 每月还贷计算器 去年给银行借了17万英镑 买了20万7500英镑的房子, 25年还清. 前2年是定率 Fix Rate 的合同 (年利率2.49%). 每个月大概是还 700多英镑. 有很多种还贷的计算方式, 定率/每月固定 是比较常用的. 简单来说就是 每个月交的钱是...
  2. 智能手机 HTC One M9 使用测评 虽然我对手机要求不高, 远远没有像追求VPS服务器一样, 但是怎么算来两年内换了四个手机, 先是三星 S4 用了一年多, 然后 Nokia Lumia 635 Windows Phone, 后来又是 BLU, 半年多前换了...
  3. 在英国给孩子换学校的经历: 孩子离开了村里的小学 由于搬了家, 孩子上学得提前半小时出门了, 因为早上堵, 也得开车半小时才能到. 之前在 Fen Drayton 村庄上小学, 早上8:45学校门开, 9点敲钟孩子排队依次进入教室, 我们由于在村里, 只需要提前5分钟出门和孩子一起走路就可以了. 现在一下子早上变得很匆忙, 得叫孩子起床, 做早饭,...
  4. Adsense 8年了 2006年注册了第一个域名, 2007年3月23日第一次投放ADSENSE广告.到现在8年了. 虽然GOOGLE的条例是不允许公开CPC,CTR等技术指标,但是透露一下收入(好少啊)是可以的.想要请我喝杯咔啡的,点这里. 继续努力. 英文同步:https://helloacm.com/adsense-8-years-statistics/ 本文一共 86 个汉字, 你数一下对不对. Adsense 8年了. (AMP 移动加速版本) 赞赏我的几个理由. ¥...
  5. 同一台服务器上多个WORDPRESS站点的一些设置可以移出去 我自从把所有网站都挪到一处VPS服务器上 就发现很多事情省事很多 可以同时管理多个网站 包括 WORDPRESS博客. 比如我有四个WORDPRESS博客 然后我就把通用的一些资料给移出去 移到 HTTP或者HTTPS都不能直接访问的文件夹里这样就更安全许多. 文件 wp-conn.php 存储了 相同的数据库资料. 1 2...
  6. 英国看电视的 TV License 英国的电视台如BBC, 都是没有插入广告的, 那么怎么维持电视台的运营呢? 英国政府规定, 只要你看电视, 那你就得交一个 TV License, 一个月十几镑, 也不贵, 交完了就可以心安理得的(合法)的看电视频道了. 如果你通过手机, 或者其它方式(上网), 收看即时的英国电视节目, 也是得交的....
  7. 公司请的专业摄影师 公司来了新的CEO管理之后,很多事情都不一样了, 特别是一些公司对外形象的事情就特别的在意, 比如公司网站用上SSL.现在公司还有空闲的位置,请速来(钱多人不傻). 一月份出差回LUTON,刚好公司请来摄影师给高层管理照像放网站上的,于是我也凑了凑热闹(但是却还不够资格被放在公司网站上),不过没关系,放这里也差不多. 人到中年, 沧桑感强了些. 更新更新: 同事用他NB的单反给谢菲尔得办公室的人也拍了一组这样的照片.看起来很不错, 很专业,灯光,道具应有尽有.我已经用在了LINKEDIN页面上,立马高大上. 本文一共 230 个汉字, 你数一下对不对. 公司请的专业摄影师. (AMP...
  8. Leetcode 的在线调试器 最近 leetcode 刷题网站出了一个在线调试器. 个人感觉非常好用. 因为我平时是用 IPAD+蓝牙键盘来刷题, 而在 ipad 上是没有集成的IDE的, 对于调试来说, 只能很原始的让函数退出一个值, 然后尝试不同的输入来发现问题. leetcode在线调试器的好处 理论上来说, 你可以直接在浏览器里解决任何一道...

从 Hugo 迁移至 Ghost 后我都做了什么

从 Hugo 迁移至 Ghost 后我都做了什么

迁移到新的博客系统Ghost上,好似拿到了新玩具⛷️!东瞧瞧西瞅瞅,哪里都透着一点新鲜气儿。将界面与各种功能品鉴一番后,剩下需要迁移的文本内容堆积着,让我不仅又是一阵头疼:

“啊,怎么还要做这么多的事情啊。”

作为能把5分钟前还在和我讲话的人的面孔忘记的失忆症患者😨,我还是得写点东西做个备忘,认真贯彻“好记性不如烂笔头”的传统精神,以免忘记对Ghost动过什么手脚,防止玩脱了博客出错,那乐子可就大了😭。

先讲下都做过什么吧🤗:

  1. 设置Ghost管理面板相关内容

语言、元数据、更改博客的图标、开启搜索、公告栏、订阅、邮件相关(设置事务邮件与时事通讯)、代码注入、更改Waline评论系统、新链接页面打开、修改路由与重定向。

  1. 主题修改

使用的主题在中文状态下依然有部分英语,主要是时间格式的问题。(略微修改,先这样用用吧)。看着别的朋友的Ghost主题都好好看,但是在官方一看,哇,好贵!😖买个主题的授权,域名都能续费好多年了嘞🧨。

Ghost 安装与部署就不写了,毕竟一搜一大堆。

Ghost 管理面板

Ghost管理面板即Ghost Admin,是后端点击下方齿轮后的设置内容。

语言

Publication Language出设置语言为zh,这是Ghost官方的简体中文代码,而不是zh-Hans,好奇怪🤔。

🥳
推荐使用任何Ghost主题时,都在翻译文件拷贝一份翻译为zh.json,与Ghost官方保持一致。

图标

在一些无版权网站上随便找了一个花儿的图标,稍微修改下尺寸便匆匆上架。还是感觉不够好看呀,以后再改进改进!有朋友会做图标吗?👀

开启搜索

Advanced处的Integrations打开Add custom integration,输入名字后复制Admin API key处的内容,再点击Design & branding中的Customize,在Site wide处填入Search API key下的输入框保存激活。

从 Hugo 迁移至 Ghost 后我都做了什么
🥲
不过Ghost的搜索有点问题——中文的搜索力也太弱了。尝尝搜不出文章内的内容,标题也只能以开头来识别。

公告栏

Announcement bar即为公告栏,是我在Ghost中最喜欢的功能之一🎉。在自定义内容后会在博客全部页面的最上端出现一个小小的横幅来提醒来到博客的朋友。

从 Hugo 迁移至 Ghost 后我都做了什么

这里我没有修改,不过想要修改的朋友可以参考Ghost官方修改教程来做个更漂亮的!

How to add an offer banner to a Ghost site
Offers are often shared as a link in an email call to action, during a podcast, or via social media. But what if you want to display a special offer as a banner on your site, so all visitors can access it? Our tutorial gives you everything you need to add a beautiful offer banner to your site.
从 Hugo 迁移至 Ghost 后我都做了什么TutorialsTeam Ghost
从 Hugo 迁移至 Ghost 后我都做了什么

邮件系统

Newsletter的中文名字是时事通讯,不过讲中文的感觉好奇怪:这个名字英文听到的频率总比中文时候多😐。

因为邮件广告的泛滥,现在还支持群发邮件的厂商已经很少了!微软、谷歌等通过SMTP群发邮件会有极大的概率封禁。所以Ghsot也开始背靠邮件方面的“大厂——Mailgun”实现这个功能:Ghost中的邮件群发深度绑定Mailgun,所以在Ghost中实现时事通讯功能,我们只能通过注册Mailgun🤐来解决。

当然,还有一种我从使用Hugo博客时期想到的解决方案,那就是依然检测RSS变动,使用Zaiper联动Mailchimp解决,具体可以看我的《静态博客添加 Newsletter 的几种推荐方案》这篇文章。
静态博客添加 Newsletter 的几种推荐方案
经过朋友的评论启发,尝试为自己的静态博客添加 Newsletter 订阅方式,并先后使用 Mailchimp、Tinyletter、Substack、revue、Briefcake 得出总结。
从 Hugo 迁移至 Ghost 后我都做了什么山茶花舍吕楪
从 Hugo 迁移至 Ghost 后我都做了什么

如果不使用Zaiper,那么还可以自建Listmook,但这种方案推荐使用域名邮箱和服务器(不过Listmook可以使用Railway搭建)。

注册Mailgun

💡
Mailgun需要外币卡!

Mailgun现在每月免费邮件量从5000降至1000。唉,要是老用户就好了😭,还是原来的5000封邮件量限制。这里还有坑,大家需要注意!虽然pricing中有尝试免费计划的选项,但注册后是默认开启的一个月的Foundation计划!!在一个月后会从你卡中扣款!我在去年注册Mailgun时没有注意到这个问题,打开Mailgun的仪表板发现账户被冻结,并且有一张35美金的账单时才发现!幸亏外币卡我都是随用随充的,里面只有剩下的几美元,扣款失败哈哈哈。

所以我们需要:在注册后打开订阅计划页面,手动降级到FLEX计划。

从 Hugo 迁移至 Ghost 后我都做了什么

点击降级后会在下面提示你下个月是FLEX计划,在下个月后会变成上面这张图的样子,就不怕扣费拉🥳!

配置群发

仪表板 点击 senging后domains中点击Add New Domain,绑定mg.域名.com(或其他域名,Mailgun推荐使用mg子域名),Domain region选US或EU都可以,我是US🎉,然后再DNS服务提供商那里修改为Mailgun要求的指向内容。

点击右上角账户,选择API Security,在Mailgun API keys 处点击add new key,复制并保存API Keys

登录Ghost后台,打开Mailgun settings,点击edit更改。

Mailgun region-选择位置,Mailgun domain-你刚才设置的域名,Mailgun private API key处填写Apikeys内容,点击保存即可。

从 Hugo 迁移至 Ghost 后我都做了什么
💡
这时,你可以群发邮件啦,要不先写篇草稿试试能不能发你邮箱🤔?

事务邮件

事务邮件是指博客上的注册、评论、订阅成员的通知。

Mailgun控制台打开Domain Settings-SMTP credentials,点击右上角的Add nwe SMTP user 输入名字,添加完成后右下角会出现提示框,在其中复制密码保存后关闭窗口。

从 Hugo 迁移至 Ghost 后我都做了什么

登录服务器,打开Ghost的配置文件config.production.json

nano config.production.json

修改为:

"mail": { "transport": "SMTP", 
		 "options": { 
			 "service": "Mailgun", 
			 "auth": {
				"user": "你设置的SMTP账户", 
				"pass": "你复制的SMTP密码" 
				} 
			} 
	},

保存后,ghost stop 停止运行,然后ghost start重新启动就好啦。

订阅计划

我一直特别好奇Ghost中此功能是如何运行的,毕竟能接入一个支付系统真的是太酷了!

从 Hugo 迁移至 Ghost 后我都做了什么
💡
因为Stripe没有国内用户的注册方式,正常情况需要护照。

不过我没有使用护照页注册成功并连接到Ghost了,这里不做详解,毕竟要解释的内容太多了😭!如果有需要的朋友可以评论区或通过联系方式告诉我,如果需要开启方式的人比较多,我可以单独写一篇激活方式的文章🤔。

代码注入

添加google分析、prism.js代码高亮、umami分析、新链接页面打开、更改Waline主题色、修改路由与重定向等一大堆内容!

代码注入在Ghost控制台最下面,Code injection处点击edit编辑。

添加Google分析

Google分析处添加账号与媒体资源名称后,点击“数据搜集和修改”,打开数据流点击添加,类型选择网站,在设置完毕后找到追踪代码拷贝。

从 Hugo 迁移至 Ghost 后我都做了什么

然后将代码粘贴于于代码注入的Site header处(分析类JS推荐在header),等一段时间Googke分析首页就会出现内容拉😎!

代码高亮

在初次测试Ghost的各项功能时,我神奇的发现Ghost竟然没有原生支持代码高亮功能,我的天哪!这都2023年了喂😕。

不过没关系,只要有搜索引擎,一切事情都有解决办法🤭:在Ghost官方教程中有写如何设置使用Prism.js。

在代码注入的Header处加入内容:

<!-- prism.js -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/themes/prism-tomorrow.min.css" integrity="sha512-vswe+cgvic/XBoF1OcM/TeJ2FW0OofqAVdCZiEYkd6dwGXthvkSFWOoGGJgS2CW70VK5dQM5Oh+7ne47s74VTg==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/plugins/toolbar/prism-toolbar.min.css" integrity="sha512-Dqf5696xtofgH089BgZJo2lSWTvev4GFo+gA2o4GullFY65rzQVQLQVlzLvYwTo0Bb2Gpb6IqwxYWtoMonfdhQ==" crossorigin="anonymous" referrerpolicy="no-referrer" />

在Footer处加入内容:

<!-- prism.js -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-core.min.js" integrity="sha512-9khQRAUBYEJDCDVP2yw3LRUQvjJ0Pjx0EShmaQjcHa6AXiOv6qHQu9lCAIR8O+/D8FtaCoJ2c0Tf9Xo7hYH01Q==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/plugins/autoloader/prism-autoloader.min.js" integrity="sha512-SkmBfuA2hqjzEVpmnMt/LINrjop3GKWqsuLSSB3e7iBmYK7JuWw4ldmmxwD9mdm2IRTTi0OxSAfEGvgEi0i2Kw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/plugins/toolbar/prism-toolbar.min.js" integrity="sha512-st608h+ZqzliahyzEpETxzU0f7z7a9acN6AFvYmHvpFhmcFuKT8a22TT5TpKpjDa3pt3Wv7Z3SdQBCBdDPhyWA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/plugins/copy-to-clipboard/prism-copy-to-clipboard.min.js" integrity="sha512-/kVH1uXuObC0iYgxxCKY41JdWOkKOxorFVmip+YVifKsJ4Au/87EisD1wty7vxN2kAhnWh6Yc8o/dSAXj6Oz7A==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

保存后就实现了代码高亮的功能拉🎉!而且我贴心的帮你们找到了prism.js实现右上角复制代码的功能,不用再添加额外的代码咯~快谢谢我😋。

在这之后,Ghost的编辑器内输入代码片段时,在右上角的框内填写代码类型,如:html。脚本会贴心的在加载代码片段时只自动加载html格式的代码高亮,加快页面载入速度🥳。

评论系统

Ghost评论系统还是不够完善,本来想试试的,但是用了几天发现有下面几个问题:

  1. 国内网络环境加载缓慢,极端慢🙃!(这个通过cloudflare或国内CDN可以一定程度上环节)
  2. 不能使用表情包:这绝对不能忍🤬!我那么多可爱的表情全浪费了吗?
  3. 评论通知频繁🤫,一个朋友对另一个朋友做出的评论我也会接到通知,不符合逻辑。况且Mailgun每月只有1000封邮件的额度,担心评论系统也使用Mailgun发送邮件会用超免费额度🥺。

不甘心的我在网上高强度搜索,决定在下面几种评论系统选一个比较合适的:

Cusdis:超级轻量,但没有表情包。

Artalk:进去官网就看到文档下面的评论显示404,离了个大谱,信心丢失。

twikoo:各方面都可以,但为什么不选Waline呢?

Waline:还是用原本采用的吧,路径依赖也是蛮好的。还可以试着导入以前的评论。

💡
唉,要是评论系统支持Ghost的账户系统SSO登录就好了,那样可以直接在我博客注册的朋友免去重新输入评论必要信息的麻烦。

想了想,还是用回Hugo上经历许多考验的Waline吧。评论系统是在Vercel平台上免费部署的,但因为Vercel的DNS被污染,以及Serverless平台后端代码执行缓慢的原因,有朋友经常给我留言说评论系统一直出现fetch错误。这次我决定在服务器独立部署Waline,希望能解决这方面的问题。

如果想使用Vercel,可以点击下面的按钮一键部署🎉!

或参考下面的官网部署教程:

部署
Waline 支持多种部署方式,你可以从以下部署平台进行选择。 Vercel (./vercel.md) (默认); 阿里云函数计算 (./aliyun-fc.md); 百度云函数计算 (./baidu-cfc.md); Cloudbase (./cloudbase.md); Deta (./deta.md); Railway (./railway.m…
从 Hugo 迁移至 Ghost 后我都做了什么Waline
从 Hugo 迁移至 Ghost 后我都做了什么
💡
服务器可以参考官网使用learnCloud或使用免费的PostgreSQL:supabaseplanetscale

服务器部署,在服务器上新建docker-compose.yaml文件:

nano docker-compose.yml

输入以下内容:

version: '3'
services:
  waline:
    container_name: waline
    image: lizheming/waline:latest
    restart: always
    ports:
      - 127.0.0.1:8360:8360
    volumes:
      - ${PWD}/data:/app/data
    environment:
      TZ: 'Asia/Shanghai' #时区设置
      #SQLITE_PATH: '/app/data' #使用SQLITE就不需要注释
      #JWT_TOKEN: 'Your token' #SQLITE内容
      SITE_NAME: '站点名字'
      SITE_URL: '站点链接'
      AUTHOR_EMAIL: '博主邮箱'
      LOGIN: 'disable' #是否强制登录 disable为关闭
      DISABLE_USERAGENT: 'true' #是否隐藏评论者的 UA,默认为否
      DISABLE_REGION: 'true' #是否隐藏评论者的归属地
      #AVATAR_PROXY: 'false' #头像的代理地址,设置 false 关闭代理 推荐注释使用下面的内容
      GRAVATAR_STR: 'https://use.sevencdn.com/avatar/{{mail|lower|trim|md5}}' #头像代理替换
      IPQPS: '20' #发言间隔-秒
      SECURE_DOMAINS: 'irithys.com' #安全域名配置 防止他人使用你的评论系统
      #SMTP_HOST: '' #SMTP_HOST、SMTP_PORT两个或直接使用SMTP_SERVICE一个配置
      #SMTP_PORT: ''
      #SMTP_USER: ''
      #SMTP_PASS: ''
      SMTP_SERVICE: 'Aliyun'
      SMTP_SECURE: true #是否使用 SSL 连接 SMTP
      SENDER_NAME: '发件人名字'
      MYSQL_DB: '' #如果使用SQLITE则 MYSQL相关配置都注释掉
      MYSQL_USER: ''
      MYSQL_PASSWORD: ''
      MYSQL_HOST: ''
      MYSQL_PORT: ''
      MYSQL_SSL: 'true'
      MAIL_SUBJECT: ''
      MAIL_TEMPLATE: ''
      MAIL_SUBJECT_ADMIN: ''
      MAIL_TEMPLATE_ADMIN: ''
      

需要修改的数据库相关配置可以参考官方配置

环境变量名称 必填 默认值 备注
MYSQL_DB MySQL 数据库库名
MYSQL_USER MySQL 数据库的用户名
MYSQL_PASSWORD MySQL 数据库的密码
MYSQL_HOST 127.0.0.1 MySQL 服务的地址
MYSQL_PORT 3306 MySQL 服务的端口
MYSQL_PREFIX wl_ MySQL 数据表的表前缀
MYSQL_CHARSET utf8mb4 MySQL 数据表的字符集
MYSQL_SSL false 是否使用 SSL MYSQL 连接数据库
邮件配置参考这里

Waline还可以自定义邮件模板,如果想要自定义,可以参考下面的紫罗兰主题模板内容填入。

从 Hugo 迁移至 Ghost 后我都做了什么

是这个样子!不过因为屏幕原因只能截取到正文内容,上面的封面没有截取到🥺。并且我发现其他朋友使用的这个模版中的代码有些错误,无法在docker-compose.yml文件内使用,不过我已经改正拉!

💡
注意:Vercel中规定环境变量的长度不能超过4KB,所以可能会出现错误,解决办法是修改index.js内的相关内容。

MAIL_SUBJECT:邮件主题

{{parent.nick | safe}},『{{site.name | safe}}』上的评论收到了回复

MAIL_TEMPLATE:邮件模板

<div style="background: url(https://npm.elemecdn.com/sarakale-assets@v1/Article/email/bg2.png);padding:20px 0px 20px;margin:0px;background-color:#d6d6d6;width:100%;"><style type="text/css">@media screen and (max-width:600px){.afterimg,.beforeimg{display:none!important}}</style><div style="border-radius: 10px 10px 10px 10px;font-size:14px;color: #555555;width: 530px;margin:50px auto;max-width:100%;background: #ffffff;"><img class="beforeimg" style="margin-top: -30px;margin-bottom: -120px;width:530px;height:317px;z-index:-100;pointer-events:none" src="https://npm.elemecdn.com/hexo-butterfly-envelope/lib/before.png"><img src="https://npm.elemecdn.com/hexo-butterfly-envelope/lib/violet.jpg" style="width:100%;overflow:hidden;pointer-events:none"><div style="width:100%;background:#f8d1ce;color:#9d2850;border-radius: 10px 10px 0 0;background-image: -moz-linear-gradient(0deg, rgb(67, 198, 184), rgb(255, 209, 244));height: 66px;background: url(https://npm.elemecdn.com/sarakale-assets@v1/Article/email/line034_666x66.png) left top no-repeat;"><p style="font-size:16px;font-weight: bold;text-align:center;word-break:break-all;padding: 23px 32px;margin:0;">您在<a style="text-decoration:none;color: #9d2850;" href="{{site.url}}">『{{site.name | safe}}』</a>上的留言有新回复啦!</p></div><div class="formmain" style="background:#fff;width:96%;max-width:800px;margin:auto auto;border-radius:5px;border: 1px solid #564f4f59;overflow:hidden;pointer-events:none"><div style="margin:40px auto;width:90%;"><p>Hi,{{parent.nick}},您曾在文章上发表评论:</p><div style="background: #eee;margin:20px 0px;padding:15px;border-radius:5px;font-size:15px;color:#555555;">{{parent.comment | safe}}</div><p><strong>{{self.nick}}</strong> 给您的回复如下:</p><div style="background: #eee;margin:20px 0px;padding:15px;border-radius:5px;font-size:15px;color:#555555;">{{self.comment | safe}}</div><p>您可以点击<a style="text-decoration:none; color:#cf5c83" href="{{site.postUrl}}" target="_blank"> 查看回复的完整內容 </a>,欢迎再次光临<a style="text-decoration:none; color:#cf5c83" href="{{site.url}}" target="_blank"> {{site.name}} </a>。<hr /><p style="font-size:14px;color:#b7adad;text-align:center">本邮件为系统自动发送,请勿直接回复邮件哦,可到博文内容回复。<br />https://irithys.com</p></p><img src="https://npm.elemecdn.com/hexo-butterfly-envelope/lib/line.png" style="width:100%;margin:25px auto 5px auto;display:block;pointer-events:none"><p class="bottomhr" style="font-size:12px;text-align:center;color:#999">自动书记人偶竭诚为您服务!</p></div></div><img class="afterimg" style="width:530px;height:317px;margin-top: -155px;z-index:100;"src="https://npm.elemecdn.com/hexo-butterfly-envelope/lib/after.png"></div></div>'

MAIL_SUBJECT_ADMIN:博主邮件主题

{{site.name | safe}} 上有新评论了

MAIL_TEMPLATE_ADMIN:博主邮件模板

<div style="background: url(https://npm.elemecdn.com/sarakale-assets@v1/Article/email/bg2.png);padding:20px 0px 20px;margin:0px;background-color:#d6d6d6;width:100%;"><style type="text/css">@media screen and (max-width:600px){.afterimg,.beforeimg{display:none!important}}</style><div style="border-radius: 10px 10px 10px 10px;font-size:14px;color: #555555;width: 530px;margin:50px auto;max-width:100%;background: #ffffff;"><img class="beforeimg" style="margin-top: -30px;margin-bottom: -120px;width:530px;height:317px;z-index:-100;pointer-events:none" src="https://npm.elemecdn.com/hexo-butterfly-envelope/lib/before.png"><img src="https://npm.elemecdn.com/hexo-butterfly-envelope/lib/violet.jpg" style="width:100%;overflow:hidden;pointer-events:none"><div style="width:100%;background:#f8d1ce;color:#9d2850;border-radius: 10px 10px 0 0;background-image: -moz-linear-gradient(0deg, rgb(67, 198, 184), rgb(255, 209, 244));height: 66px;background: url(https://npm.elemecdn.com/sarakale-assets@v1/Article/email/line034_666x66.png) left top no-repeat;"><p style="font-size:16px;font-weight: bold;text-align:center;word-break:break-all;padding: 23px 32px;margin:0;">您在<a style="text-decoration:none;color: #9d2850;" href="{{site.url}}"target="_blank">{{site.name}}</a>上的文章有了新的评论</p></div><div class="formmain" style="background:#fff;width:96%;max-width:800px;margin:auto auto;border-radius:5px;border: 1px solid #564f4f59;overflow:hidden;pointer-events:none"><div style="margin:40px auto;width:90%;"><p><strong>{{self.nick}}</strong> 回复说:</p><div style="background: #eee;margin:20px 0px;padding:15px;border-radius:5px;font-size:15px;color:#555555;">{{self.comment | safe}}</div><p style="text-align:center;">您可以点击<a style="text-decoration:none;color:#cf5c83" href="{{site.postUrl}}" target="_blank">查看回复的完整內容</a></p><img src="https://npm.elemecdn.com/hexo-butterfly-envelope/lib/line.png" style="width:100%;margin:25px auto 5px auto;display:block;pointer-events:none"><p class="bottomhr" style="font-size:12px;text-align:center;color:#999">自动书记人偶竭诚为您服务!</p></div></div><img class="afterimg" style="width:530px;height:317px;margin-top: -155px;z-index:100;"src="https://npm.elemecdn.com/hexo-butterfly-envelope/lib/after.png"></div></div>

umami分析

umami声称是Google分析的代替品,不过我用它的主要原因是Google分析太难用了😭,经常想找一个功能找不到位置,而umami界面简洁清爽,各项功能排列合理,使用起来比Google分析舒服多了!而且自建也超级方便,甚至可以免费在Vercel上部署。有兴趣的朋友可以参考官网的Vercel部署攻略:

Running on-vercel – umami
从 Hugo 迁移至 Ghost 后我都做了什么

也是一键部署🤩!同样可以使用免费PostgreSQL。

💡
免费PostgreSQL:supabaseplanetscale

新页面打开链接

在代码注入的Footer处加入以下代码:

<!-- Open external links in a new tab by default -->
<script>
  const anchors = document.querySelectorAll('a');
    
  for (x = 0, l = anchors.length; x < l; x++) {
    const regex = new RegExp('/' + window.location.host + '/');
        
    if (!regex.test(anchors[x].href) && anchors[x].href.indexOf('javascript') == -1) {
      anchors[x].setAttribute('target', '_blank');
      anchors[x].setAttribute('rel', 'noopener');
    }
  }
</script>

实现的功能是在博客内点击一个链接时,检测是否为博客内部链接,不是博客内部链接则打开新的标签页跳转(变着法儿的让朋友们留在我的博客里哈哈哈😂)。

路由与重定向

在Ghost中可以方便的修改文章路径与重定向。简单来说,你可以通过下载 Setting - Labs - Beta features 处的重定向与路由文件进行修改上传。

将博客从Hugo迁移到Ghost后,最感到烦躁的就是文章中海量的链接了,文章内部没有什么好办法,只能一篇篇文章慢慢手动修改过去✏️,现在只能悔恨为什么当初非要弄一个看起来很酷但是不支持其他平台的Hugo语法进行内部跳转,换到Ghost后博客的内部链接全部失效,12/22号一整天修改累死我了😭。

重定向

官方参考方案在这里,神奇的是官方推荐使用redirects.yaml文件,但Ghost后台下载的确是一个json文件。

💡
注意,如果你只是单纯的想从/变成/p/这种形式,那么不如使用内容集合

举个例子,redirects.yaml文件是这个形式。编辑yaml文件(推荐使用vscode,yaml文件对空格缩进敏感,vscode可以减少失误,很方便的编辑):

301:
  /from: /to
  domain.com/category/category-slug/: domain.com/tag/tag-slug/
302:
  /from: /to

比如在使用Hugo时,我的全部文章都是domain.com/p/url的形式,但现在使用Ghost时,文章链接全变成了domain.com/url的形式,如果有朋友在自己博客中引用了我的文章内容,并且给出了文章链接,那么别人想要来我博客看看这篇文章时,会找不到原来的旧链接,导致出现404错误——这是我们不愿意看到的😕。那么这时就可以这样:

301:
  /p/保护自己的密码安全自托管或免费部署bitwarden: /bitwarden-1
302:

将丢失的旧链接重定向至新文章链接上。以往我都是使用Nginx跳转的,这真的好方便!省略了超多的步骤🥰。

301代表永久重定向,而302代表临时重定向,根据自己的需要修改,一般改动使用301,我也不知道302是让干嘛的哈哈哈哈😂,编辑好后重新打开Labs页面,选择Upload redirects file上传,左下角会有成功上传提示。

如果想要删除所有重定向,那么重新下面这样子的redirects.yaml空文件重新上传至Ghost即可:

301:

302:

主题汉化

Ghost的汉化可以说是两个极端,一方面极其开放,主题中用到的显示在前台的文字都可以在主题的locales文件夹中找到,只需要简单的将en.json文件拷贝一份,重新命名为zh.json然后自己手动翻译就好🥳。另一方面,又超级封闭,Ghost的一些组件如登、评论等前台界面中显示的文字已硬编码在程序中,导致无法修改😮。

注意:Ghost好像有一个隐形Bug的地方:简体中文的国际化一般叫做zh-Hans,但Ghost很奇怪叫做zh,繁体中文的zh-Hant倒是写得很对,这就导致有些主题的汉化文件与Ghost不一致,在后台Publication Language中选择Site language时,选择官方的zh,主题汉化引用不了,使用主题的,Ghsot又会出现一些官方英文。所以,在这里直接在主题文件这里重新拷贝一份zh.json汉化。

时间表达

我使用的是liebling主题,可能有些稍稍不一样,但代码中的文字表达方式大致相同:

这里:
<span class="m-heading__meta__time">{{date published_at}}</span>
修改为
<span class="m-heading__meta__time">{{date published_at format="YYYY年MM月DD日 HH:mm"}}</span>

具体想修改为那种表达方式,可以看着参考Ghost的 Date 章节来修改 。

Ghost Handlebars Theme Helpers: date
Output date formats in your Ghost publication with the date helper. More about Ghost themes inside ✨
从 Hugo 迁移至 Ghost 后我都做了什么Ghost - The Professional Publishing Platform
从 Hugo 迁移至 Ghost 后我都做了什么

Ghost - 时间助手模块

值得注意的是,Ghost中在date中引用了momentjs,但其中中文的表达方式又不一样。找了好久才知道,需要在其中加入locale="zh-cn"才可以变成中文(又出现了一个不同的代表中文的代码!!🤬)。

<span>{{date published_at locale="zh-cn" timeago="true"}}</span>

结语

呼,终于写完了🥳!还有目录没有做,但是使用Ghost官方教程的内容不会浮动,修改起来好头疼。自己还写过想要自己写一个Ghost主题,现在只完成了第一步:迁移到Ghot上,什么时候开始学习界面设计与Ghost主题开发依然遥遥无期😵‍💫。

就先这样吧?一边用着一边想着怎么修改。Ghost用起来我还蛮喜欢的🎉。

房屋装修记录

&emsp;&emsp;去年5月,我在成都龙泉驿买了一套房子,至此,在成都打拼7年,终于有了一个属于自己的落脚之地。

&emsp;&emsp;房子面积92.45平,总价93万左右,平均下来一平1万多块钱。贷款60万,一个月房贷3807元。

  • 2022年3月24日 与装修公司签合同,付先期30%款项32635.89元
  • 2022年4月17日 正式开工
  • 2022年4月23日 房屋门窗全换,18386元
  • 2022年5月17日 缴纳契税12700元
  • 2022年5月24日 水电完工
  • 2022年5月30日 支付中期65%款项70712元

Be water my friend

我真的很喜欢蹲在现场看装修师傅施工。今年个人经历可谓动荡,竟然先后两次对咖啡馆进行大规模装修,倒也算是满足了我这个特殊爱好。这次装修还是找了上次那位师傅,不过大概现在装修行业人员流动特别频繁吧,他这次带来一起工作的帮工是个陌生面孔。锯台边,师傅从一头把木板向飞转的锯刀推过去,帮工在锯刀的另一头,接住木板免得它弯折。但显然还是配合得不够默契,或许他是想帮忙提升效率,接手的同时用力把木板往自己这边拉,惹得师傅呵斥:「别拽,接住就行!」拉拽这个动作本身很难保证木板的笔直行进,而且速度一旦快起来,师傅那边也无法把持木板的走向。欲速则不达,有些事就只能慢慢来。做帮工,最好的状态是和师傅步调一致,减轻不必要的摩擦力,保留有必要的触感,大概如此吧。

从签订好租房合同到现在已经过去半个月了,装修也进行了一个周,现场依然还是一片狼藉。友人多次到访,直言「看上去没什么进展啊」。装修这种事情,涉及的步骤太多太细碎,是需要一个过程的。眼看着场地越变越乱,陷入停滞,东一下西一下,似乎毫无头绪,的确可能会令人焦躁。不过它总会忽然在某个时间点初现格局,然后速度骤提,甚至一天就有一个大变化。接着,像是进站的火车一样减速,有条不紊地修补,细节于是完善起来,豁然开朗。我喜欢蹲在装修现场有一部分原因正是如此,对最终成果的追求就像是推木板,如果没有足够的阻力,反倒失了实感,甚至连既定方向都无法把握。那些必要的「滞感」,让人更清醒地思考为什么要做,以及如何更好地去做。Be water my friend。

fin.

来写一些好玩的 Hugo 短代码吧

💡
请注意,由于博主已更换博客系统为 “Ghost”,以下代码已无法正常显示。 ——2023年12月22日18:10

Hugo短代码

来写一些好玩的 Hugo 短代码吧

由Hugo官方的文档可知,简码是内容文件中调用内置或自定义模板的简单代码段。那为什么会用到这东西呢🤔?因为:

💡
虽然Markdown的内容格式简单,但有时会达不到创作者的要求。通常,内容作者被迫将原始HTML(例如视频)添加到Markdown内容中。Hugo认为这与 Markdown语法的简单性相矛盾,比如<iframe>之类的标签。Hugo创造了短代码(shortcodes)来规避这些限制。

你会发现,上面这段文字被框起来了🎉,这就是Hugo短代码的实际运用~

短代码是内容文件中的简单片段,Hugo 将使用预定义的模板呈现该片段。请注意,短代码在模板文件中不起作用。如果需要短代码提供的插入功能类型,但在模板中,那很可能需要一个部分模板。除了更简洁的Markdown之外,短代码可以随时更新以反映新的类、技术或标准。在网站生成时,Hugo短代码将轻松合并更改。避免可能复杂的搜索和替换操作。

编写

在Markdown文件中,Hugo短代码通过{{</* shortcodename parameters */>}}的形式引用。前一个单词shortcodename为短代码名称,后一个单词parameters为参数,且排除第一个单词外都是参数,中间使用空格隔开。如果需要多个参数的传递,那么需要使用name="value"的形式传值。

💡
在Hugo中使用短代码,需要在在Hugo根目录下的./layouts/shortcodes/创建shortcodename.html文件,shortcodename为你短代码的名字。

语法

这里先写一些Hugo的简单语法😙,如:

{{ index .Params 0 }}

这句代码表达的意思为获取短代码中的第一个参数,如果是{{ index .Params 1 }}代表第二个,以此轮推。

{{ .Get "text1" }}

此代码表达为获取参数名为text1的参数,如果引用代码为{{</* myshortscode text="文本" */>}},那么传入的参数为“文本”二字。

传入日期需要使用{{/* .Date.Format ( default "2006-01-02") */}},后面为可以格式化的日期样式。

使用{{ /*with .Site.Params.footer.customText */}}语句可以引用站点配置文件中定义的变量值。如{{ /*with .Site.Params.sidebar.subtitle */}}此语句返回为:吕楪在记录自己的生活

分享

在Github与Google一通搜索😵‍💫后收集了很多短代码,连带着自己也照着写了几个😊。

高亮

样式:

{{< mark text="这是一个重点标记" >}}

创建mark.html文件,其中内容编写:

<mark>{{ .Get "text" }}</mark>

这样一个简单的短代码便实现啦,但默认的高亮为荧光黄色,看起来有点刺眼,那么可以在./assets/scss/custom.css中增加mark标记的样式🤭。

{{< notice notice-warning >}}
注意:./assets/scss/custom.css为我使用主题的自定义css文件,其他主题可能不相同。
{{< /notice >}}

mark{
    background: hsla(332, 81%, 58%, 0.879);
}

使用:

{{</* mark text="这是一个重点标记" */>}}

但这个颜色也不好看诶🥲。

缩写

样式:

{{< abbr title="这里有着非常非常非常非常非常非常非常非常长的缩写内容~" text="缩写的文本" >}}

这时,将鼠标放在缩写的文本上方时,会自动浮现出被缩写的内容。

创建abbr.html文件,其中内容编写:

<abbr title="{{ .Get "title" }}">{{ .Get "text" }}</abbr>

使用:

{{</* abbr title="这里有着非常非常非常非常非常非常非常非常长的缩写内容~" text="缩写的文本" */>}}

蛮好玩的样子😙!

文本位置

样式:

{{< align center "文字居中" >}}

会发现上面的文本在文章中心。

创建align.html文件,其中内容编写:

<p style="text-align:{{ index .Params 0 }}">{{ index .Params 1 | markdownify }}</p>

使用:

{{</* align center "文字居中" */>}}

理解起来也非常简单😘,首先align.html内容为一段html5编码,p标签为段落,我们要实现的自由变动文本位置需要使用css样式text-align,这里能用的参数有:center、left、right。

{{ index .Params 0 }}代表读取短代码的第一个参数center{{ index .Params 1 | markdownify }}代表读取短代码中第二个参数,至于markdownify代表通过Markdown处理器运行提供的字符串。markdownifyHugo V0.93版本提供的新功能,旧版本不适用哦。

块引用

样式:

{{< blockquote author="电影" link="https://irithys.com" title="《寻梦环游记》" >}}
死亡不是一切的终点,遗忘才是
{{< /blockquote >}}

创建blockquote.html文件,拷贝以下内容。

<!-- reset scratch variables at the start -->
{{ $.Scratch.Set "bl_author" false }}
{{ $.Scratch.Set "bl_source" false }}
{{ $.Scratch.Set "bl_link" false }}
{{ $.Scratch.Set "bl_title" false }}

{{ if .IsNamedParams }}
  {{ $.Scratch.Set "bl_author" (.Get "author") }}
  {{ $.Scratch.Set "bl_source" (.Get "source") }}
  {{ $.Scratch.Set "bl_link" (.Get "link") }}
  {{ $.Scratch.Set "bl_title" (.Get "title") }}
{{ else }}
  <!-- for the positional version if any -->
{{ end }}

<!-- if title is not set explicitly then we need to beautify the link
     if length of link is more than 32 chars, we will cut it off by 32 and
     then drop everything after the last / if any and put it in into title -->

{{ with $.Scratch.Get "bl_title" }}
  <!-- do nothing -->
{{ else }}
  {{ with $.Scratch.Get "bl_link" }}    <!-- if link is given -->
    {{ range last 1 (split ($.Scratch.Get "bl_link" ) "://") }}  <!-- split by :// and then only take the items after it to remove protocol:// -->
      {{ $.Scratch.Set "title_without_protocol" . }}
    {{ end }}
    {{ range last 1 (split ($.Scratch.Get "title_without_protocol" ) "www.")  }} <!-- also remove the www. at the start if any. we are using a second split because all URLS may not start with it -->
      {{ $.Scratch.Set "title_without_protocol" . }}
    {{ end }}
    {{ $.Scratch.Set "bl_title" ($.Scratch.Get "title_without_protocol") }}

    <!-- if link is longer than 32 bytes we should trim it -->
    {{ if (gt (len ($.Scratch.Get "title_without_protocol") ) 32) }}
      {{ $title := (slicestr ($.Scratch.Get "title_without_protocol") 0 32) }}   <!-- get the first 32 characters of title_without_protocol -->
      {{ $split_by_fw_slash := split $title "/" }}   <!-- now split on / because we want to stop after the last forward slash -->
      {{ $count := (sub (len $split_by_fw_slash) 1) }}   <!-- we want everything but the last part so we adjust the count accordingly -->

      {{ $.Scratch.Set "tempstring" "" }}   <!-- temp variable to hold the concatinated string -->
      {{ range first $count $split_by_fw_slash  }}  <!-- loop through all parts except last and concat them (add / between halves) -->
        {{ $.Scratch.Set "tempstring" ( . | printf "%s%s/" ($.Scratch.Get "tempstring") | printf "%s" ) }}
      {{ end }}
      {{ $.Scratch.Set "bl_title" ( printf "%s..." ($.Scratch.Get "tempstring") | printf "%s" ) }}
    {{ end }}
  {{ end }}
{{ end }}

<blockquote>
  <p>{{ .Inner | markdownify }}</p>
  <footer style="text-align:right">
    <strong>{{ with $.Scratch.Get "bl_author" }}{{ . }}{{ end }}</strong>
    {{ with $.Scratch.Get "bl_source" }}
      <cite>{{ . }}</cite>
    {{ else }}
      {{ with $.Scratch.Get "bl_link" }}
        <cite>
          <a href="{{ . }}" title="{{ . }}" rel="noopener noreferrer">{{ $.Scratch.Get "bl_title" }}</a> <!-- can't have new lines here -->
        </cite>
      {{ else }}
        {{ with $.Scratch.Get "bl_title" }}
          <cite>
            {{ $.Scratch.Get "bl_title" }}</a>
          </cite>
        {{ end }}
      {{ end }}
    {{ end }}
  </footer>
</blockquote>

使用:

{{</* blockquote author="电影" link="https://irithys.com" title="《寻梦环游记》" */>}}
死亡不是一切的终点,遗忘才是
{{</* /blockquote */>}}

隐藏

样式:

{{< detail "点下我呀🎁" >}}
对看到这行文字的人报以深切的祝福🥰!
{{< /detail >}}

创建detail.html文件,拷贝其中内容:

<details>
    <summary>{{ (.Get 0) | markdownify }}</summary>
    {{ .Inner | markdownify }}
</details>

使用:

{{</* detail "点下我呀🎁" */>}}
对看到这行文字的人报以深切的祝福!🥰
{{</* /detail */>}}

标签

这里的标签非常好看!文章第一章节便使用了这个标签。源文件来自@martignoni,但颜色过重,我使用了@荷戟独彷徨的修改版本~

此标签有4个样式~

样式一,警告:
{{< notice notice-warning >}}
警告!这个标签太好看了,我忍不住分享。
{{< /notice >}}

样式二,信息:
{{< notice notice-info >}}
明确的爱,直接的厌恶,真诚的喜欢。站在太阳下的坦荡,大声无愧地称赞自己。
{{< /notice >}}

样式三,贴条:
{{< notice notice-tip >}}
遇到一些需要做提示性语句的位置,可以贴个条。
{{< /notice >}}

样式四,注释:
{{< notice notice-note >}}
我想要的不是解释,而是注释。
{{< /notice >}}

创建notice.html文件,拷贝以下内容:

{{- $noticeType := .Get 0 -}}

{{- $raw := (markdownify .Inner | chomp) -}}

{{- $block := findRE "(?is)^<(?:address|article|aside|blockquote|canvas|dd|div|dl|dt|fieldset|figcaption|figure|footer|form|h(?:1|2|3|4|5|6)|header|hgroup|hr|li|main|nav|noscript|ol|output|p|pre|section|table|tfoot|ul|video)\\b" $raw 1 -}}

{{ $icon := (replace (index $.Site.Data.SVG $noticeType) "icon" "icon notice-icon") }}
<div class="notice {{ $noticeType }}" {{ if len .Params | eq 2 }} id="{{ .Get 1 }}" {{ end }}>
    <div class="notice-title">{{ $icon | safeHTML }}</div>
    {{- if or $block (not $raw) }}{{ $raw }}{{ else }}<p>{{ $raw }}</p>{{ end -}}
</div>

/assets/scss/custom.scss中新加入以下样式:

.notice {
  position:relative;
  padding: 1em 1em 1em 2.5em;
  margin-bottom: 1em;
  border-radius: 4px;
  p:last-child {
      margin-bottom: 0;
  }
  .notice-title {
      position: absolute;
      left: 0.8em;
      .notice-icon {
          width: 1.2em;
          height: 1.2em;
      }
  }
  &.notice-warning {
      background: hsla(0, 65%, 65%, 0.15);
      border-left: 5px solid hsl(0, 65%, 65%);
      .notice-title {
          color: hsl(0, 65%, 65%);
      }
  }
  &.notice-info {
      background: hsla(30, 80%, 70%, 0.15);
      border-left: 5px solid hsl(30, 80%, 70%);
      .notice-title {
          color: hsl(30, 80%, 70%);
      }
  }
  &.notice-note {
      background: hsla(200, 65%, 65%, 0.15);
      border-left: 5px solid hsl(200, 65%, 65%);
      .notice-title {
          color: hsl(200, 65%, 65%);
      }
  }
  &.notice-tip {
      background: hsla(140, 65%, 65%, 0.15);
      border-left: 5px solid hsl(140, 65%, 65%);
      .notice-title {
          color: hsl(140, 65%, 65%);
      }
  }
}

[data-theme="dark"] .notice {
  &.notice-warning {
      background: hsla(0, 25%, 35%, 0.15);
      border-left: 5px solid hsl(0, 25%, 35%);
      .notice-title {
          color: hsl(0, 25%, 35%);
      }
  }
  &.notice-info {
      background: hsla(30, 25%, 35%, 0.15);
      border-left: 5px solid hsl(30, 25%, 35%);
      .notice-title {
          color: hsl(30, 25%, 35%);
      }
  }
  &.notice-note {
      background: hsla(200, 25%, 35%, 0.15);
      border-left: 5px solid hsl(200, 25%, 35%);
      .notice-title {
          color: hsl(200, 25%, 35%);
      }
  }
  &.notice-tip {
      background: hsla(140, 25%, 35%, 0.15);
      border-left: 5px solid hsl(140, 25%, 35%);
      .notice-title {
          color: hsl(140, 25%, 35%);
      }
  }
}

文件中的[data-theme="dark"]为暗色模式下的css样式,虽然我主题带有暗色模式,但没有用。推测应该需要在variables.scss中定义变量然后引用。但应该蛮少人在我博客中使用暗色模式的吧,就先这样用吧。

之后,在./data/目录下新建SVG.toml文件,拷贝以下内容:

notice-warning = '<svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 576 512" fill="hsl(0, 65%, 65%)"><path d="M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zM124 296c-6.6.0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h264c6.6.0 12 5.4 12 12v56c0 6.6-5.4 12-12 12H124z"/></svg>'
notice-info = '<svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 512 512" fill="hsl(30, 80%, 70%)"><path d="M256 8a248 248 0 100 496 248 248 0 000-496zm0 110a42 42 0 110 84 42 42 0 010-84zm56 254c0 7-5 12-12 12h-88c-7 0-12-5-12-12v-24c0-7 5-12 12-12h12v-64h-12c-7 0-12-5-12-12v-24c0-7 5-12 12-12h64c7 0 12 5 12 12v100h12c7 0 12 5 12 12v24z"/></svg>'
notice-note = '<svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 512 512" fill="hsl(200, 65%, 65%)"><path d="M504 256a248 248 0 11-496 0 248 248 0 01496 0zm-248 50a46 46 0 100 92 46 46 0 000-92zm-44-165l8 136c0 6 5 11 12 11h48c7 0 12-5 12-11l8-136c0-7-5-13-12-13h-64c-7 0-12 6-12 13z"/></svg>'
notice-tip = '<svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 512 512" fill="hsl(140, 65%, 65%)"><path d="M504 256a248 248 0 11-496 0 248 248 0 01496 0zM227 387l184-184c7-6 7-16 0-22l-22-23c-7-6-17-6-23 0L216 308l-70-70c-6-6-16-6-23 0l-22 23c-7 6-7 16 0 22l104 104c6 7 16 7 22 0z"/></svg>'

此文件中定义的4个变量为svg矢量图,如果想要用其他的图片也可以换成其他的。

注意:如果在/assets/scss/custom.scss中定义的css样式不起作用,也就是说图标为黑色状态,那么需要在SVG标签中写入fill="hsl(0, 65%, 65%)"之类的颜色标签,此内容和css在定义中定义的颜色相同。

使用:

{{</* notice notice-warning */>}}
警告!这个标签太好看了,我忍不住分享。
{{</* /notice */>}}

这是第一个标签,将notice-warning分别修改为notice-notenotice-infonotice-tip就可以得到其他三个不同样式的标签啦😛。

音乐

样式:

{{< music id="557578993" type="song" server="netease" >}}

首先,引用外部链接需要关闭Hugo的安全模式(必须):

打开根目录的config.yaml文件,修改以下内容:

markup:
    goldmark:
        renderer:
            unsafe: true

当然,如果配置文件为config.toml,则是这种修改方式:

[markup.goldmark.renderer]
unsafe= true
此步骤设置为true,markdown中就可以使用html5标签啦。

新建music.html文件夹,拷贝以下内容:

<!-- require APlayer -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/aplayer/dist/APlayer.min.css">
<style type="text/css">.dark-theme .aplayer{background:#212121}.dark-theme .aplayer.aplayer-withlist .aplayer-info{border-bottom-color:#5c5c5c}.dark-theme .aplayer.aplayer-fixed .aplayer-list{border-color:#5c5c5c}.dark-theme .aplayer .aplayer-body{background-color:#212121}.dark-theme .aplayer .aplayer-info{border-top-color:#212121}.dark-theme .aplayer .aplayer-info .aplayer-music .aplayer-title{color:#fff}.dark-theme .aplayer .aplayer-info .aplayer-music .aplayer-author{color:#fff}.dark-theme .aplayer .aplayer-info .aplayer-controller .aplayer-time{color:#eee}.dark-theme .aplayer .aplayer-info .aplayer-controller .aplayer-time .aplayer-icon path{fill:#eee}.dark-theme .aplayer .aplayer-list{background-color:#212121}.dark-theme .aplayer .aplayer-list::-webkit-scrollbar-thumb{background-color:#999}.dark-theme .aplayer .aplayer-list::-webkit-scrollbar-thumb:hover{background-color:#bbb}.dark-theme .aplayer .aplayer-list li{color:#fff;border-top-color:#666}.dark-theme .aplayer .aplayer-list li:hover{background:#4e4e4e}.dark-theme .aplayer .aplayer-list li.aplayer-list-light{background:#6c6c6c}.dark-theme .aplayer .aplayer-list li .aplayer-list-index{color:#ddd}.dark-theme .aplayer .aplayer-list li .aplayer-list-author{color:#ddd}.dark-theme .aplayer .aplayer-lrc{text-shadow:-1px -1px 0 #666}.dark-theme .aplayer .aplayer-lrc:before{background:-moz-linear-gradient(top, #212121 0%, rgba(33,33,33,0) 100%);background:-webkit-linear-gradient(top, #212121 0%, rgba(33,33,33,0) 100%);background:linear-gradient(to bottom, #212121 0%, rgba(33,33,33,0) 100%);filter:progid:DXImageTransform.Microsoft.gradient( startColorstr='#212121', endColorstr='#00212121',GradientType=0 )}.dark-theme .aplayer .aplayer-lrc:after{background:-moz-linear-gradient(top, rgba(33,33,33,0) 0%, rgba(33,33,33,0.8) 100%);background:-webkit-linear-gradient(top, rgba(33,33,33,0) 0%, rgba(33,33,33,0.8) 100%);background:linear-gradient(to bottom, rgba(33,33,33,0) 0%, rgba(33,33,33,0.8) 100%);filter:progid:DXImageTransform.Microsoft.gradient( startColorstr='#00212121', endColorstr='#cc212121',GradientType=0 )}.dark-theme .aplayer .aplayer-lrc p{color:#fff}.dark-theme .aplayer .aplayer-miniswitcher{background:#484848}.dark-theme .aplayer .aplayer-miniswitcher .aplayer-icon path{fill:#eee}</style>
<script src="https://cdn.jsdelivr.net/npm/aplayer/dist/APlayer.min.js"></script>
<!-- require MetingJS -->
<script src="https://cdn.jsdelivr.net/npm/meting@2.0.1/dist/Meting.min.js"></script>

<!-- 注意!!我因为APlayer与meting-js都是以插件形式引入的,所以不需要写上面这些 -->
{{ if .IsNamedParams }}
    <meting-js
      id="{{ .Get "id" }}"
      server="{{ .Get "server" }}"
      type="{{ .Get "type" }}"
      fixed="{{ if .Get "fixed" }}{{ .Get "fixed" }}{{ else }}false{{ end }}"
      mini="{{ if .Get "mini" }}{{ .Get "mini" }}{{ else }}false{{ end }}"
      autoplay="{{ if .Get "autoplay" }}{{ .Get "autoplay" }}{{ else }}false{{ end }}"
      loop="{{ if .Get "loop" }}{{ .Get "loop" }}{{ else }}none{{ end }}"
      theme="{{ if .Get "autoplay" }}{{ .Get "autoplay" }}{{ else }}#255579{{ end }}"
      volume="{{ if .Get "volume" }}{{ .Get "volume" }}{{ else }}0.6{{ end }}"
      prelosd="{{ if .Get "prelosd" }}{{ .Get "prelosd" }}{{ else }}auto{{ end }}"
      mutex="{{ if .Get "mutex" }}{{ .Get "mutex" }}{{ else }}true{{ end }}"
      list-folded="{{ if .Get "list-folded" }}{{ .Get "list-folded" }}{{ else }}true{{ end }}">
    </meting-js>
{{ end }}

使用:

{{</* music id="557578993" type="song" server="netease" */>}}

此处的id为音乐的网址id,如我上面引用的音乐,地址为https://music.163.com/#/song?id=557578993server代表用的哪家的服务,netease代表网易,还可以使用有腾讯tencent,酷狗kugou,百度baidu

长毛象

样式:

{{< mastodon status="109336902159860386" >}}

新建mastodon.html文件,拷贝以下内容:

{{ .Page.Scratch.Set "include_mastodon" true }}
{{ $server := .Get "server" | default "im.irithys.com" }}
{{ $user := .Get "user" | default "thy" }}
{{ $width := .Get "width" | default "100%" }}
{{ $height := .Get "height" | default "auto"}}
{{ $status := .Get "status" | default "false" }}

{{ if eq ($status) "false" }}
{{ else }}
<iframe src= "https://{{ $server }}/@{{ $user }}/{{ $status }}/embed" class="mastodon-embed" style="max-width: 100%; border: 0" width="{{ $width }}" height="{{ $height }}" allowfullscreen="allowfullscreen"></iframe><script src="https://{{ $server }}/embed.js" async="async"></script>
{{ end }}

这里我在上方预先定义了一些默认的常量,如serveruser,这是因为如果是引用自己的话,每次都传一次也太呆了吧。所以如果其他毛象站的朋友们使用,需要先修改server为自己的服务器,user为自己的用户名

使用:

{{</* mastodon status="109336902159860386" */>}}

只需要将嘟文id传入就好啦😙~

哔站

样式:

{{< bilibili BV1NF411J7JH >}}

创建bilibili.html文件,拷贝以下内容:

{{ $vid := (.Get 0) }}
{{ $videopage := default 1 (.Get 1) }}
{{ $basicQuery := querify "page" $videopage "high_quality" 1 "as_wide" 1 }}
{{ $videoQuery := "" }}

{{ if strings.HasPrefix (lower $vid) "av" }}
    {{ $videoQuery = querify "aid" (strings.TrimPrefix "av" (lower $vid)) }}
{{ else if strings.HasPrefix (lower $vid) "bv" }}
    {{ $videoQuery = querify "bvid" $vid }}
{{ else }}
    <p>Bilibili 视频av号或BV号错误!请检查视频av号或BV号是否正确</p>
    <p>当前视频av或BV号:{{ $vid }},视频分P:{{ $videopage }}</p>
{{ end }}

<div class="video-wrapper">
    <iframe src="https://player.bilibili.com/player.html?{{ $basicQuery | safeURL }}&{{ $videoQuery | safeURL }}"
            scrolling="no"
            frameborder="no"
            framespacing="0"
            allowfullscreen="true"
    >
    </iframe>
</div>

使用:

{{</* bilibili BV1NF411J7JH */>}}

蛮好玩的,B站除了一些需要版权的视频之外,都可以引用哦。

网易云

样式:

{{< netease 557578993 0 >}}

这其实是网易云自带的嵌入,略作修改后就能拿过来用啦。

新建netease.html文件,拷贝以下内容:

<iframe frameborder="no" border="0" marginwidth="0" marginheight="0" width=100% height=86 src="//music.163.com/outchain/player?type=2&id={{ index .Params 0 }}&auto={{ index .Params 1 }}&height=66"></iframe>

使用:

{{</* netease 557578993 0 */>}}

输入的第一个参数为歌曲的id,第二个参数代表是否自动播放,1为自动播放,0为手动播放。

完结

分享完毕😊,在之后我遇到新的Hugo短代码再继续更新此文章😋~我发现国内好多网站都已经不提供嵌入代码了呀,虽然是互联网但是没有一点开放的态度呢🤔。

智能家居?米家全家桶,Yes!

现在家庭装修基本都会考虑要不要装智能家居,但是考虑到成本和安装使用难度,许多人又只能放弃。所以,这里分享一下我家两年前装修时,选择米家智能家居方案的考量和实际安装情况。

一、主要需求

智能家居主要包括:无线网络覆盖、灯光场景模式、背景音乐系统、传感器与设备联动、语音控制、远程控制、电动窗帘和晾衣架、智能门锁。

我家装修后主要是爸妈居住,所以考虑更多的是他们使用的便利程度。这就要求日常使用要稳定不能时不时需要维护,而且使用要简单方便、逻辑直接,控制界面学习难度尽可能低。此外,老妈提出了以后如灯光模式要可以编辑调整的需求,老爸提出了要有背景音乐播放系统的需求,而我自己则是认为要有远程监控家里设备运行的功能,方便我在外地帮助爸妈解决使用中遇到的问题。

综合以上情况,我家的主要需求包括:

  • 千兆内网传输和无线网络 5GHz 信号全覆盖
  • 灯光场景编辑控制,其中实体开关要可以控制场景
  • 背景音乐系统
  • 环境传感器与设备联动
  • 语音和远程控制,其中语音控制不能只依靠手机
  • 电动窗帘、晾衣架,其中晾衣架不需要设备联动
  • 智能门锁、猫眼
  • 预留 NAS 的设备空间
  • 床底要预留扫地机器人进入清扫的高度
  • 各空间除阳台外要无障碍通行不设置门槛,方便未来轮椅的通行,也方便扫地机器人清扫

此外,我家还增加了水管净水和直饮水的需求。

二、方案选择

作为苹果全家桶家庭,最初想到的是 HomeKit 方案。但是支持 HomeKit 的智能家居设备选择余地很少,而且大多数价格高昂。这时候支持 HomeKit 的绿米 Aqara 设备进入了我的视线,这类设备价格适中,且同时支持苹果的 HomeKit 和米家,能发挥苹果家庭 App 操作简单直观(特别是灯光控制方面如下图)和米家 App 功能多样两种优势。

苹果家庭 App 上我家的设备

米家的智能家居很多人都听说过,但是毕竟小米带给很多人的印象还是廉价和手机的印象。特别是在父母辈的眼中,就会有想法:这个东西靠不靠谱、是不是容易坏、坏了怎么办?因为我们是新小区,所以基本上楼上楼下都是同一时间装修的,互相参考一下装修方案是常有的。于是好多邻居看到我家准备装智能家居就觉得自己家里也要搞,所以大家也有差不多的疑虑。

有比较早完成装修的邻居家采用了智能家居厂家提供的一体化解决方案,由厂家负责设计、安装。我家装修前专门去了邻市的几个装修市场考察行情(都在向全国的客户供货,应该比较有代表性),一整套解决方案报价在3-5万元不等,不包括灯的费用,只是线路和控制设备的价格,而别墅之类的就直接十万以上了。

此外,这类设备的可替换性和定制便利度不足。很多设置是写死了不能改的,比如想更换设计新的灯光场景模式,要么得加钱,要么每次换都要找他们来调整。其次是像灯光控制面板、开关这种都是定制的,如果坏了(不能觉得短时间内不会坏就没关系),更换就需要专门联系发货再让安装师傅上门,一来一去就会花很多时间。

而米家就不一样了,自己手机上也能操作编辑,老妈早就用得很熟练了,遇到麻烦我也可以远程在手机上帮忙搞定。如果设备坏了或者想增加一些设备,不急就网上下单,包邮区送货还是很及时的。更何况附近商场就有一家小米的门店,常规的智能开关面板、插座都有货,十分方便。

不过,这不能否定这种一体化智能家居解决方案。智能家居现在很多方案还不太完善,即使如米家这类也开始提供类似设计、安装的服务,这对于一般家庭来说无疑降低了使用的门槛。

三、设计与施工

其实我家主要的智能家居设计工作在于灯路的搭配和无线网络的覆盖,而这两部分归根结底就是强电与弱电的设计施工问题。

1. 无线网络

智能家居联网的设备就会很多,从目前我家的使用情况看平时就有将近15个设备在线,节假日高峰就可能有20个。那么,确保这些设备稳定联网就十分必要了。

首先,弱电柜不再采用传统的嵌入墙壁式弱电箱,这种嵌入式的信息箱无法提供足够的空间放置光猫、路由器、交换机等设备。我们选择在进门的地方预留一个多层的柜子用于放置相关设备,多余的空间可以放置五金工具箱,所有的网线也都在这里汇聚到交换机上。

弱电柜(网上找的示意图)

光猫只负责光信号转换成网络信号,这个 之前的文章 已提及,这里不再赘述。因为网线线路众多,所以路由器的出口就不够用了,需要一台交换机,我家选择了 TP-LINK TL-SG1218P。因为使用无线 AP 发射网络信号,记得选择带有 PoE 功能的交换机,因为需要给无线 AP 供电,而路由器就可以选择使用有线路由器了。不过我家搬家前就在用华硕的 AC86U 路由器,运行十分稳定,搬家后就不更换了。另外,也可以选择 TP-LINK 的有线路由器 + 交换机 + AC 控制器一体机,这样可以少买几个设备。

无线 AP 主要有墙壁面板型和吸顶型两种,根据网上的反馈,面板型的覆盖范围比较有限、容易坏。所以全部采用了吸顶型的,直接放在中央空调的进风口里面(预先网线在天花板布线),墙壁上安装普通的网络面板提供给需要有线连接的电视机等设备。品牌选择上,TP-LINK 算是家用领域比较常见的品牌,不过据说稳定性稍显不足。因为主要是爸妈使用,还是尽量以稳定为主,就选择了稍贵的 Ubnt Unifi UAP-AC-LR 搭配同品牌的 AC 控制器 Ubnt Cloud Key(可以远程监控网络运行)。

网络拓扑图

网线的布线以多多益善为原则,尽量每个房间最少有两路网线,这样一路可以连接智能电视,另外的可以连接机顶盒等设备。主要是让能够有线连接的都接上网线,网络更加稳定。没错,我家电视基本上都联网观看了,有线电视已经好几年没开通了。不过对于我提出的不布置有线电视线路的方案,老爸还是觉得略显激进,最后就只安排了一路通往他们的卧室(虽然大概率是不会用的)。

全家都是用了 iCloud+ 共享空间备份手机资料,爸妈看电视也都是流媒体为主,下载再观看的需求不大。所以家里暂时没有 NAS 之类的需求,不过已经在前面提到的弱电柜预留了 NAS 位置。

2. 灯光控制

米家 Aqara 的灯光开关在设计时主要的思路就是将原本灯光的双控或多控开关改成一个有线开关控制物理上的灯路开闭,另外的无线开关遥控这个有线开关。

依照这种思路,其实电线都可以只布置单控的线路。但是考虑到目前智能家居产品标准不统一,未来十年内我家没有大的装修计划,那么如果未来开始出现新的智能家居方案标准,这种激进的施工方案会给调整更换带来麻烦。所以,最后决定灯路电线的设计施工上按照原本的多控模式,用一个有线开关配合多个无线开关遥控的方案。对于已经装修好的家庭,这也是一种便捷的使用智能家居的方法。

Aqara 的无线开关可以贴墙安装在普通的 86 型开关底盒上。Aqara 的有线开关面板建议选用零火线版本,单火线版本主要是给家中装修比较早没有在开关盒中预埋零线而准备的,现在装修施工请一定记得无论是插座还是开关都要预埋零线。另外,可以将有线开关其中的一个或多个按键转换为无线遥控使用,所以如果一下子算不清楚、搭配不明白每种要买几个,也可以全买有线的开关(当然价格更高)。

调整后的灯路图(局部)

本来打算是在装修公司设计的灯路图上修改后交给设计师重新绘图的,但是设计师看完就疯了,表示你这样画出来了就没必要再出图了,电工师傅也表示照着施工能看明白。其实电工师傅对于第一次安装这种智能开关还是有点疑虑的,怕搞不来。所以安装那天我亲自拿着贴纸在底盒上标注这个安装哪种面板,师傅照着装就行了。安装开关和普通传统的开关没什么区别,甚至因为有部分开关用了无线的,所以可以少接一部分的灯线。

3. 背景音乐系统

我爸想要背景音乐系统,这个我是拒绝的,因为实在找不到可以融入米家系统的设备。播放音乐可以选择小爱音响、客厅的电视机,音效也可以了(反正我家都不是什么发烧友),实在追求高一点可以买 HomePod 嘛,不过谁让老爸需求强烈呢,只能寻找可行的方案了。

在某宝和某东多番查找比较后,选择了向往 HOPE M8S 背景音乐主机搭配 4 个吸顶 750 喇叭。背景音乐主机安装在电视机边上,用来控制喇叭播放音乐,因为算是一个安卓平板,曲库还是很容易获取的。主机可以连接电视机等外部设备,这样也可以播放外部音源。

商家提供的安装图示

唯一比较麻烦的是语音控制,因为米家小爱同学语音控制是无法接入控制背景音乐主机的。如果需要语音控制,可以加钱买另外支持的主机,但依然不支持小爱,而是另外的语音助手。本来就已经同时用 Siri 和小爱同学进行语音控制(因为 Aqara 的网关同时可以接入 HoneKit 和米家),再来一个背景音乐的语音助手,就造成多种系统并存了没必要。想听歌但是不想手动操作主机面板,要么手机蓝牙连接到背景音乐主机上,要么喊一声让小爱同学播放音乐,也不是不能用。

4. 智能联动

要想多个设备智能联动,首先需要一个网关将使用 Zigbee 和蓝牙等信号的开关、插座等设备连接起来接入网络,而小爱音响、扫地机器人这类直接插电的设备是直接接入 Wi-Fi 的。Aqara 现在的网关功能还挺丰富的,基本上把 Zigbee、蓝牙、红外等多信号的设备都可以用一个网关连接了,不过如果范围大尽量多布置几个网关,让设备就近连接到附近的网关上,保证连接质量。

虽然 Aqara 有支持同时接入 HomeKit 和米家的网关,不代表直接可以用 HomeKit 远程控制家中的设备了。HomeKit 在没有家庭中枢设备的情况下,只有当 iPhone、iPad 或 Mac 设备与网关处于同一局域网的情况下,才可以控制网关下面的设备。想要远程控制(离开家里的局域网),就需要一台家庭中枢设备联网放置于家中,满足要求的家庭中枢有:Apple TV、iPad、HomePod。我家是放了一台 Apple TV 4K 在客厅作为家庭中枢,目前使用体验良好,离家后要联入控制家中灯光反应速度还是不错的。

家庭中枢设置

联动除了设置不同的场景模式以外,依据不同的环境状态执行不同的场景模式,就需要各种传感器了。我家主要安装了:人体传感器、门窗传感器、烟雾报警器、天然气报警器(需要预留电路)、水浸传感器,后三者安装在厨房保证安全。

5. 窗帘晾衣架门锁

电动窗帘可以 Aqara 自己的窗帘电机,这样就可以无缝接入米家。不过 Aqara 的电机和轨道价格偏高,杜亚品牌的窗帘电机和轨道倒是口碑不错。但是杜亚的电机遥控器使用的是 443 MHz 的射频信号,想接入米家就需要万能的某宝了。某宝上有一种信号转换器,可以将射频信号转换成红外信号,让小米的红外万能遥控器接收信号。这样就可以在米家上对收到红外信号设置不同的场景,实现远程或者语音控制窗帘开合。

我家虽然选择的是电动的晾衣架,但是没有选择支持米家的设备。因为主要用户老妈表示用不到,晾衣服、收衣服的时候已经站在衣架边上了,按一下遥控器更方便,也没什么远程控制升降的需求。其实晾衣架遥控器也是用射频信号控制的,同样可以用上面提到的信号转换器转换信号后接入米家,这样语音和远程控制也可以实现。

智能门锁主要的需求是指纹解锁、NFC 卡解锁、手机蓝牙解锁、发放临时密码解锁,而且作为安装在入户门上的锁,颜值也是必不可少的。经过挑选,我家选择了支持米家的鹿客 S30 Pro,搭配同品牌的猫眼。就在准备网上下单时,我发现家附近有线下门店在销售这款产品,而且通过他们渠道不仅包安装售后,价格也比线上便宜。于是,在与老板讨价还价后成功拿到了十分优惠的价格,顺便告诉老板他名片上的微信号印错了(笑)。

6. 净水过滤

前面提到的都是强弱电的设计安装,现在越来越多的家庭装修时在水的方面也更重视了。在浏览过许多“什么值得买”上的经验分享以后,就和老爸探讨并设计了我家的净水系统。

设计的水路

没有采用软水机是因为我家这边水质硬度不高,而软水机占用面积大,水路需要将生活用水和饮用水单独分离,过于复杂。图中的过滤瓶在最后施工时也取消了,生活用水通过前置过滤已经足够,饮用水有 RO 净水机搭配管线机即可。这些设备品牌选择余地就特别大了,随便选一个都差不多。

需要注意的是,前置过滤器安装除了要考虑入户时的水压大小,最好在水表后面设计两个并行的水路,一路安装前置过滤器(前后各安装一个阀门方便冲洗过滤器),一路只安装阀门(平时此路阀门常闭)。这样即使前置过滤器坏了(如漏水),也可以直接关闭这一路而使用备用的水路,不会影响日常使用。

❌