ChrisKim
Do not go gentle into that good night.
颢天

给博客添加表情包过程的分享

今天在网上逛到有些大佬的博客,发现他们有各种各样的表情包,特别是有 b 站的表情包,用起来真是亲切。而本站虽说有表情包功能,但我不太喜欢 Alu 表情包的这个风格,感觉辨识度太低了,都不知道每个表情是啥意思,而且表情数量也少,完全不能满足交流功能。于是我就想给博客加点其他表情,没想到这简简单单加个表情真是非常曲折,在这里分享下我的经验,可能能帮助到各位。

本站表情包用的是 WP Alu2Button 这个插件,原因是 MDx 主题对这个插件做了适配(现在回过头来看,好像也只是检测了个函数名,没啥特别的),用这个插件的话就能和主题的评论框完美融合。

所以我自然而然地想到直接魔改插件… 看了下插件的源码,很明显就能看出,表情列表就是靠这个函数来解决的,前面是表情码,后面是对应的图片,存在插件目录里面。

function alu_smilies_reset() {
    global $wpsmiliestrans, $wp_smiliessearch;

    if ( !get_option( 'use_smilies' ) )
        return;

    $wpsmiliestrans = array(
        ':mrgreen:' => 'icon_mrgreen.gif',
        ':neutral:' => 'icon_neutral.gif',
        ':twisted:' => 'icon_twisted.gif',
        // ……略……
        ':|' => 'icon_neutral.gif',
        ':!:' => 'icon_exclaim.gif',
        ':?:' => 'icon_question.gif',
    );
}
add_action('init','alu_smilies_reset');

当我把我的表情按格式填入这个数组里后,表情列表确实出现了我新加入的表情,但是发送出去的表情码原封不动的是字符,没有成功替换成表情图片。我就纳闷了,表情列表都显示了新表情,怎么发出去之后却不行了?什么玩意。

然后就是折磨的开始了,四处搜寻资料,来回看了好多遍这插件的源码,甚至把主题适配插件的部分源码都看了下。虽说我是一点也不会 PHP,但是代码长得还挺像 Python 的,勉强能看懂在干啥。

搞了半天我发现一个特点,以前插件的表情码比如 :mrgreen: 我改成对应自己的表情图片是可以的,但是我自己没法添加新的表情码,这就离谱了。

然后我又去搜索 WordPress 表情的原理,然后发现了这插件用的表情码其实是 WordPress 内置好的,这个插件无非是把它对应的图片修改成了 Alu 表情包。这给我了点启发,难道是说只有 WordPress 内置表情码才能正确替换为表情包,而我不能新加表情码吗?

然后我就去翻 WordPress 的源代码,因为不知道这功能写到哪个文件里了,于是我就直接在 wp-includes 里面搜索了一波 :mrgreen: 这个表情码,因为你定义表情替换规则肯定有这个关键词。果不然在 functions.php 里面写了 smilies_init() 这个函数。

但是我一看,这函数的对应部分和插件那个函数一模一样,那这插件是哪里有问题了呢?我注意到这个函数的注释:

Plugins may override the default smiley list by setting the $wpsmiliestrans to an array, with the key the code the blogger types in and the value the image file.

好家伙,这注释都说明了插件是可以覆盖 WordPress 内置的表情的,并且插件的代码确实重写了 $wpsmiliestrans 这个数组啊,怎么却不能成功显示呢?再看下一行注释:

The $wp_smiliessearch global is for the regular expression and is set each time the function is called.

说的是 $wp_smiliessearch 是正则表达式,在每次调用该函数的时候会被设定。然后我就突然发现,这插件的代码调用覆盖表情的函数之后,重写了 $wpsmiliestrans 这个数组,所以表情列表可以正常显示,但是插件没有重新设定 $wp_smiliessearch,导致替换表情的正则表达式仍然只匹配 WordPress 默认的表情码。

发现这个之后,我立马把 WordPress 源码的这个函数整个复制到插件里面,比原来的函数多了以下内容,然后改成插件对应的函数名,再把我的新表情列表塞进去,保存刷新,好家伙,果不然可以正常显示了。

$wpsmiliestrans = apply_filters( 'smilies', $wpsmiliestrans );
if ( count( $wpsmiliestrans ) == 0 ) {
	return;
}
krsort( $wpsmiliestrans );
$spaces = wp_spaces_regexp();
$wp_smiliessearch = '/(?<=' . $spaces . '|^)';
$subchar = '';
foreach ( (array) $wpsmiliestrans as $smiley => $img ) {
	$firstchar = substr( $smiley, 0, 1 );
	$rest      = substr( $smiley, 1 );
	// New subpattern?
	if ( $firstchar != $subchar ) {
		if ( '' !== $subchar ) {
			$wp_smiliessearch .= ')(?=' . $spaces . '|$)';
			$wp_smiliessearch .= '|(?<=' . $spaces . '|^)';
		}
		$subchar           = $firstchar;
		$wp_smiliessearch .= preg_quote( $firstchar, '/' ) . '(?:';
	} else {
		$wp_smiliessearch .= '|';
	}
	$wp_smiliessearch .= preg_quote( $rest, '/' );
}
$wp_smiliessearch .= ')(?=' . $spaces . '|$)/m';

因为 WordPress 源码的这个函数每次运行会重新设定匹配规则,而插件的函数并不会重新设定匹配规则,导致只能用 WordPress 设定好的匹配规则。修改后,插件每次也会设定新的匹配规则,所以我再插件里加的表情包就能正常匹配并显示了。

本文链接:https://www.zouht.com/2837.html
本文使用:CC BY-NC-SA 4.0 许可
没有标签
首页      随笔      给博客添加表情包过程的分享

发表评论

textsms
account_circle
email

  • 博主真会折腾 [支持]
    那么,这个表情框在移动端似乎不能显示完全,应该加一个 overflow: scroll
    (还好我站兼用 Twikoo 评论系统,内置多种表情包,省去折腾。不过我还记得当初用 Valine 评论系统时折腾了许久)

    2月前 回复
    • ChrisKim

      @CasecoRI: 靠,还真是… [笑哭] 我手机长期 75% 看网站没发现这个 bug,看来`max-height`还得开得更大(其实我是修改了的,原来那个只能显示一行 [无语]

      2月前 回复
  • 另外,全平台通用的 emoji 不香吗?😝

    2月前 回复

颢天

给博客添加表情包过程的分享
今天在网上逛到有些大佬的博客,发现他们有各种各样的表情包,特别是有 b 站的表情包,用起来真是亲切。而本站虽说有表情包功能,但我不太喜欢 Alu 表情包的这个风格,感觉辨识度太低了,…
扫描二维码继续阅读
2022-04-04