Posted in: IT, Website/Blog

WordPress给评论框添加原生的表情(Smiley)插入功能

Smiley 和 Emoji

Smiley 其实不是 Emoji,虽然现在看起来几乎一模一样,详见 WordPress 官网说明

大家去看一下自己的 WordPress 目录下面的 /wp-includes/images/smilies,可以看到有22个 gif 文件,它们就是 WordPress “上古时代”留下来的 Smiley,样子十分丑陋,长得像这样(列举3个):

但本文描述的 Smiley 是类似于官网上这样的 WordPress 官网说明。事实上这是现代浏览器渲染产生的新字体(而不是像之前那样的 gif 图片,并且 Windows 和 MacOS/iOS 平台有各自的渲染特点。)

🙂 😀 🙁 😮 😯 😕 😎 😡 😛 😐 😉 😆 😳 😥 👿 😈 🙄 ❗ ❓ 💡 ➡

渲染结果示意图:

Win7 渲染结果
MacOS/iOS 渲染结果

背景

现如今网上能搜到的资料都是描述怎样给评论框插入 Emoji 表情,但由于 Emoji 需要远程连接服务器渲染 SVG,速度很慢,因此国内几乎所有站点都会选择将该功能禁用。

另一种方法是使用第三方表情,感觉和系统不太协调,不想用。

我猜想一定有办法用上原生表情,于是搜了一些古老的资料,大体是这样介绍的:

把这个smiley.php放在使用的模板目录下,然后修改模板的comments.php文件,在 textarea之前添加如下一句PHP:include(TEMPLATEPATH . ‘/smiley.php’);

这个神秘的 smiley.php 我也找到了,其实它不是 php 代码,而是一个 JS 函数 + 一些 HTML代码。

<script type="text/javascript" language="javascript">
    function grin(tag) {
        var myField;
        tag = ' ' + tag + ' ';
        if (document.getElementById('comment') && document.getElementById('comment').type == 'textarea') {
            myField = document.getElementById('comment');
        } else {
            return false;
        }
        if (document.selection) {
            myField.focus();
            sel = document.selection.createRange();
            sel.text = tag;
            myField.focus();
        }
        else if (myField.selectionStart || myField.selectionStart == '0') {
            var startPos = myField.selectionStart;
            var endPos = myField.selectionEnd;
            var cursorPos = endPos;
            myField.value = myField.value.substring(0, startPos)
                          + tag
                          + myField.value.substring(endPos, myField.value.length);
            cursorPos += tag.length;
            myField.focus();
            myField.selectionStart = cursorPos;
            myField.selectionEnd = cursorPos;
        }
        else {
            myField.value += tag;
            myField.focus();
        }
    }
</script>
<a href="javascript:grin(':?:')"><img src="/wp-includes/images/smilies/icon_question.gif" alt="" /></a>
<a href="javascript:grin(':razz:')"><img src="/wp-includes/images/smilies/icon_razz.gif" alt="" /></a>
<a href="javascript:grin(':sad:')"><img src="/wp-includes/images/smilies/icon_sad.gif" alt="" /></a>
<a href="javascript:grin(':evil:')"><img src="/wp-includes/images/smilies/icon_evil.gif" alt="" /></a>
<!-- 以下省略,就是22个图标 -->

开头是一个叫做grin的JS函数,作用是把表情插入光标所在位置。后面就是22个表情图标了。

照葫芦画瓢

之前那种古老的办法需要去修改主题 comment.php,把上面的代码加载在<textarea>之前,但很多现代主题已经不在 comment.php里面直接暴露 <textarea>了,所以并不方便像之前那么修改。于是我用 JQuery来修改(可以放head或foot)。

// 前面的grin函数照抄
jQuery(document).ready(function( $ ){
       $('< a title="酷" href="javascript:grin('+"':cool:'"+')"> :cool: ').insertBefore("#comment");
       $('< a title="发怒" href="javascript:grin('+"':mad:'"+')"> :mad: ').insertBefore("#comment");
       $('< a title="路过" href="javascript:grin('+"':neutral:'"+')"> :neutral: ').insertBefore("#comment");
// 以下均为22个图标,以此类推,注意实际使用时把 < a 改成 <a
 });

Chrome 的 bug

现代版的 Smiley 能在所有平台的 Firefox、IE11、Safari等浏览器上使用,也能在 Win10 的 Chrome上使用,但在 Win7/8 的 Chrome 中是有渲染问题的,详见此bug

Unicode

经网友提醒,这实际上上就是Unicode字符(Wordpress只不过多了把像smile这样的英文单词直接转换成表情的能力)。因此可以把上述JS代码中的单词全部替换成Unicode字符,而且不局限于这22个表情了,理论上任意字符都可以。但要注意两点:

  1. 两者本质是有区别的,Smiley是一些ASCII字符(英文单词+标点符号),然后由Wordpress和浏览器一起协力渲染成表情,存在数据库中的还是ASCII字符。而Unicode就需要MySQL数据库的相应字段是utf8mb4编码了,否则存不进去。
  2. Win7的Chrome和IE11是有点问题的。Chrome可以安装插件,IE11可以安装字体。参见小提示

总结

希望大家没有被绕晕

本质渲染
古老SmileyASCII字符(英文单词+冒号)链接到丑陋的gif图像
现代SmileyASCII字符(英文单词+冒号)由Wordpress转换成Unicode
UnicodeUnicode字符由操作系统字体+浏览器完成,不同平台效果不同
EmojiUnicode字符由浏览器远程获取SVG格式图像,各种平台效果相同

最后更新于 2021 年 1 月 21 日 作者 springwood

Comments (22) on "WordPress给评论框添加原生的表情(Smiley)插入功能"

      1. 😀 😀 对的,一样的。不过你博客有个bug,“在此浏览器中保存我的姓名、电子邮件和站点地址”勾选了也没用

        1. 刚才我做了一个简单的修复:每次页面加载时读取cookie,如果cookie存在就用js写入用户信息。至于cookie的写入、删除之类的还是由wordpress系统自己完成。麻烦你试一下 😉

      1. 不错。

        更新:是被过滤了么?我插入了表情但是提交后没有了。

        再更新:编辑的时候如果插入 emoji 会编辑失败但是没有报错。

        1. 我明白了,因为编辑评论的功能是用其他插件实现的 。我过会儿再修改一下。

        2. OK了,经过一番排查,发现是MySQL数据库的编码方式有问题,现在已经修正。 😛

    1. 嗯,可惜我平时用MacOS,工作单位统一是Win7云桌面,接触不到win10了。

    1. 其实unicode最方便。PS:兄台的评论不知怎么被Akismet标记为垃圾了,我现在才发现 😳 。

    1. 你是不是win7系统+chrome浏览器?可以参见我菜单栏里面提示页面,是因为缺少字体。

哥斯拉进行回复 取消回复

您的电子邮箱地址不会被公开。 必填项已用*标注