记一次为NexT主题提交PR的经过

最近在折腾个人博客,我选择了 Hexo + NexT 的方案。

博客地址:nobug.world

Hexo 的版本是: hexo: 7.2.0

NexT 主题的版本是:next-theme/hexo-theme-next: 🎉 Elegant and powerful theme for Hexo. (github.com)

起因

这搭建博客的过程中,我希望在所有的文章的末尾都加上我个人公众号的推广二维码图片。

扫码_搜索联合传播样式-标准色版

幸运的是,只需要在 NexT 主题的 _config.yml 配置文件中设置 follow_me 配置项中的 WeChat 即可,配置方式如下:

1
2
3
4
5
6
7
# Subscribe through Telegram Channel, Twitter, etc.
# Usage: `Key: permalink || icon` (Font Awesome)
follow_me:
#Twitter: https://twitter.com/username || fab fa-twitter
#Telegram: https://t.me/channel_name || fab fa-telegram
WeChat: /images/wechat_channel.png || fab fa-weixin
#RSS: /atom.xml || fa fa-rss

其中 /images/wechat_channel.png 是公众号推广图片的地址。

其中,images 是主题中的目录,即:themes\next\source\images

如何下载公众号推广图片

登录微信公众平台,在 设置与开发 > 公众号设置 > 下载二维码 中即可下载到二维码的图片。

将对应的图片修改名称为 wechat_channel.png,并放置到对应的目录中即可。

执行 hexo s -g 命令,在本地预览文章,效果如下:

image-20240831204940929

在文章末尾,增加了 欢迎关注我的其他发布渠道 的组件,其中包含我们配置的微信公众号,将鼠标移动到微信的图标上,即可展示二维码的图片。

但是展示的二维码图片很小,相机无法识别出二维码。

问题排查

先查看原图的像素有 2092 * 624,正常来说这个像素不应该只有这么小的图片。

image-20240831205131507

接着 F12 打开开发者工具,检查这个图片的元素,发现在 CSS 属性中定义了 max-width: 180px

image-20240831210115583

直接在开发者工具中修改该值为:max-width: 500px

image-20240831210521179

再次查看二维码图片的效果:

image-20240831210618171

当前大小的图片已经足够被相机识别了。

所以问题的原因就是 max-width 的默认值对于微信公众推广图片来说太小了。

当然,为了避免使用这种宽高比很大的图片,我们还可以截图,仅保留二维码的部分,而 max-width 的值依然为默认的 180px ,则效果如下所示:

image-20240831211449357

在这种情况下,二维码是足够大,也能够被正确识别的。但是似乎又少了一点微信的标志性的特色。

此外,还可以发现,二维码中有底层元素的 logo 的 ”印子“:

image-20240831212046068

image-20240831212708999

image-20240831212018720

在某些情况下可能会影响二维码的识别。

此外,我们同时还发现当 max-width 的值过大时,二维码显示被下方的评论组件 “截断”,效果如下:

image-20240901083926322

这里的 ”印子“ 是因为我设置了 AddToAny ,设置后会生成分享按钮,可用于将文章链接分享至微信或其他第三方应用。

1
2
3
4
5
# AddToAny Share. See: https://www.addtoany.com
addtoany:
enable: true
buttons:
- wechat

探索解决方案

二维码图片显示不完整问题

我们先关注”印子“和当max-width 的值过大时图像显示不完整的问题,这种问题应该是:本应在下层展示的元素却和上层元素发生了重叠。发生这种情况的原因应该是这两个元素没有明确指定上下层关系。那么我们可以考虑显示指定这两个元素的上下层关系。

因为我并不熟悉前端,那么这种问题我们就问一下 GPT :

image-20240831214049853

在回复中,我们看到其使用 z-index 属性来实现这个需求,那么我们可以在开发者工具中直接添加这个 CSS 属性:

image-20240831214438826

效果如下:

image-20240831214504348

image-20240901084257134

可以看到,现在已经达到了我们想要的效果:

  • 下层的 logo 不会在二维码上留下 “印子”
  • 评论组件不会 “截断” 二维码图片
  • 得到了清晰完整的二维码图片

微信公众号推广图宽度问题

接着,我们再尝试修改最大宽度的默认值,使其支持带有明显微信特色的公众号推广图。

fork 并拉取 NexT 主题的代码:next-theme/hexo-theme-next: 🎉 Elegant and powerful theme for Hexo. (github.com)

在 IDE 中打开代码文件,并搜索 social-item-img 关键词,找到这个样式是在 source\css\_common\components\post\post-followme.styl 文件中:

1
2
3
4
5
6
7
.social-item-img {
display: none;
left: 50%;
max-width: $post-reward-img-width;
position: absolute;
transform: translate(-50%, 20px);
}

可以看到,max-width 是读取 post-reward-img-width 变量的值,从变量的名称来看这个是与 reward (打赏)有关的变量。

reward 是主题中支持打赏的配置:

1
2
3
4
5
6
7
8
9
10
11
12
# Donate (Sponsor) settings
# Front-matter variable (nonsupport animation).
reward_settings:
# If true, a donate button will be displayed in every article by default.
enable: true
animation: false

reward:
wechatpay: /images/wechatpay.png
#alipay: /images/alipay.png
#paypal: /images/paypal.png
#bitcoin: /images/bitcoin.png

这里设置了微信赞赏码,效果如下:

image-20240901080233487

这里应该是复用了打赏相关的变量。我们也确实在同一路径找到了打赏对应的 CSS 文件: \source\css\_common\components\post\post-reward.styl

其中也确实用到了 $post-reward-img-width 变量:

1
2
3
4
5
6
img {
display: inline-block;
margin: .8em 2em 0;
max-width: 100%;
width: $post-reward-img-width;
}

其中 max-width: 100%;:此属性限制了图像的最大宽度为包含它的元素的宽度的100%。查看源代码并使用开发者工具检查元素可以知道其父元素的宽度是自适应的。

所以这里图片的宽度一般都是由 $post-reward-img-width 变量确定的。

搜索该变量,找到其在 \source\css\_variables\base.styl 文件中定义,且值为 180px

1
$post-reward-img-width        = 180px;

修改代码

通过上面的分析,我们可以知道,需要修改的地方只有一处,即 source\css\_common\components\post\post-followme.styl 文件中的 .social-item-img 选择器:

1
2
3
4
5
6
7
.social-item-img {
display: none;
left: 50%;
max-width: $post-reward-img-width;
position: absolute;
transform: translate(-50%, 20px);
}

需要做的修改是:

  • 增加 z-index 属性
  • 定义 max-width 属性值的变量

增加 z-index 属性

这个比较简单增加在 .social-item-img 选择器中添加就行:

1
2
3
4
5
6
7
8
.social-item-img {
display: none;
left: 50%;
max-width: $post-reward-img-width;
position: absolute;
transform: translate(-50%, 20px);
z-index: 1;
}

定义 max-width 属性值的变量

$post-reward-img-width 变量是与 reward 打赏场景相关的,这里是 follow me 关注的场景,所以可以考虑新建一个变量。

新建变量名为:post-followme-img-width

将新变量也定义在 \source\css\_variables\base.styl 文件中:

1
2
$post-reward-img-width        = 180px;
$post-followme-img-width = 460px;

修改 .social-item-img 选择器,max-width 引用$post-followme-img-width

1
2
3
4
5
6
7
8
.social-item-img {
display: none;
left: 50%;
max-width: $post-followme-img-width;
position: absolute;
transform: translate(-50%, 20px);
z-index: 1;
}

这里我选择的值是 460px,显示效果如下:

image-20240901092041031

提交 PR

提交代码:

1
2
3
git commit -m 'Support displaying wider follow-me QR code images'

git push origin master

到我们 fork 的仓库中,创建 PR:

image-20240901095057904\

查看社区对 PR 的要求,并按需填写 PR 信息。

保存后,提交的 PR 地址:Support displaying wider follow-me QR code images by Jiajun-Peng · Pull Request #837 · next-theme/hexo-theme-next (github.com)