纯代码给WordPress文章和评论添加OwO表情教程

之前折腾过一次评论表情,源码来自网络,可以说是非常强大,表情图标可以说是和手机系统一样充裕,但对于网站评论用就显得太过于杂乱了。

表情

评论发表后表情不显示

发现越来越多朋友的网站评论上不仅有表情,而且有好几组表情。怀着别人家那么“富裕”而为什么我们家这么“穷”的心情,想着我们也应该要走上“富裕”的道路。


虽然所有的图标都分好类了,但不是12类别中的每个图标都会用到,增加用户发表评论的时间,对于网站的体验感来说是非常差的。
Wordpress表情
这两天本来想着精简一下,但修改源码时发现里面代码比较复杂,有些图标使用的还是背景定位来实现的,查找位置非常麻烦,有些代码根据正常删减竟然出现整个都不显示了,最后不得不放弃,也因此想着更换另外一种表情。 ::alu:arrow::

于是便找到了今天的主角OwO表情,其实上次也想着折腾过,但当时只想着搬运(复制/粘贴),没有仔细研究,以致于后面没有成功直接就放弃了。
OwO表情
OwO是一款可爱且实用的js表情符号插件。OwO表情符号插件可以在文本域或输入框中输入表情符号,它支持颜文字、Emoji、图片等,支持移动端,表情数据从一个可以自定义的json接口读取。

配置方法

下载OwO表情插件文件,并把OwO.json、OwO.min.css和OwO.min.js放入自己网站适当的位置。

下载地址见文末。

在页面中引入OwO.min.css和OwO.min.js文件。

html

<link rel="stylesheet" href="OwO.min.css">
<script src="OwO.min.js"></script>

打开主题文件夹下面的comment.php文件,找到textarea并在class项加上OwO-textarea,同时加上表情符号容器。最后代码类似下面:

html

<!-- 目标元素 -->
<textarea class="OwO-textarea"></textarea>
<!-- 表情符号容器 -->
<div class="OwO"></div>

初始化插件,在底部加上下面的代码。

js

var OwO_demo = new OwO({
logo: 'OωO表情',
container: document.getElementsByClassName('OwO')[0],
target: document.getElementsByClassName('OwO-textarea')[0],
api: './OwO.json',
position: 'down',
width: '100%',
maxHeight: '250px'
});

参数说明如下:

  1. logo:按钮上的文本,默认为”OωO表情”
  2. container:OwO表情符号的容器
  3. target:OwO表情符号的目标textarea或input元素(注意与textarea的class名称一致)
  4. api:OwO表情符号使用的json数据(注意与自己的文件路径一致)
  5. position:OwO表情符号body的位置
  6. width:OwO表情符号body的宽度

注意事项

图片表情:位置及格式必须与上面js文件中的一致
至此表情基本配置完成并可以正常使用了,但发现发表文字表情都会在评论框上显示,而发表图片表情时就会显示图片的html代码:

html

<img src="haha.gif">

这样在评论框不仅太占地方,而且也不美观。研究OwO.json时会发现显示的内容就是json文件中的icon数据。

json

"文字": {
"type": "emoticon",
"container": [
{
"icon": "^_^",
"text": "xwz"
}
]
},
"Emoji": {
"type": "emoji",
"container": [
{
"icon": "😂",
"text": "haha"
}
]
},
"图片表情": {
"type": "image",
"container": [
{
"icon": "<img src=\"//wanghao.me/haha.gif\">",
"text": "haha"
}
]
}

扩展应用

在网友@CFanLost的Typecho程序网站上发表评论表情时只显示表情名称短代码,于是想着在Wordpress中应该也是可以这样操作的,因为json文件中的emoticon和emoji类型表情所见即所得,只有图片表情需要修改,所以只需要在js中加一下if判断就可以了,类似结构如下:

if type = image
‘<img src=”icon.gif”>’
else
‘icon’

修改完成后完整的OwO.min.js代码如下:

js

"use strict";
var _createClass = function () {
function defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}

return function (Constructor, protoProps, staticProps) {
if (protoProps) defineProperties(Constructor.prototype, protoProps);
if (staticProps) defineProperties(Constructor, staticProps);
return Constructor;
};
}();

function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}

(function () {
var OwO = function () {
function OwO(option) {
var _this = this;

_classCallCheck(this, OwO);

var defaultOption = {
logo: 'OwO表情',
container: document.getElementsByClassName('OwO')[0],
target: document.getElementsByTagName('textarea')[0],
position: 'down',
width: '100%',
maxHeight: '235px',
api: 'https://api.anotherhome.net/OwO/OwO.json'
};

for (var defaultKey in defaultOption) {
if (defaultOption.hasOwnProperty(defaultKey) && !option.hasOwnProperty(defaultKey)) {
option[defaultKey] = defaultOption[defaultKey];
}
}

this.container = option.container;
this.target = option.target;

if (option.position === 'up') {
this.container.classList.add('OwO-up');
}

var xhr = new XMLHttpRequest();

xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) {
_this.odata = JSON.parse(xhr.responseText);

_this.init(option);
} else {
console.log('OwO data request was unsuccessful: ' + xhr.status);
}
}
};

xhr.open('get', option.api, true);
xhr.send(null);
}

_createClass(OwO, [{
key: 'init',
value: function init(option) {
var _this2 = this;

this.area = option.target;
this.packages = Object.keys(this.odata); // fill in HTML

var html = '\n <div class="OwO-logo">' + option.logo + '</div>\n <div class="OwO-body" style="width: ' + option.width + '">';

for (var i = 0; i < this.packages.length; i++) {
html += '\n <ul class="OwO-items OwO-' + this.odata[this.packages[i]].name + ' OwO-items-' + this.odata[this.packages[i]].type + '" style="max-height: ' + (parseInt(option.maxHeight) - 53 + 'px') + ';">';
var opackage = this.odata[this.packages[i]].container;

for (var _i = 0; _i < opackage.length; _i++) {
if (this.odata[this.packages[i]].type === 'image') {
html += '\n <li class="OwO-item" title="' + opackage[_i].text + '" data-input="' + this.odata[this.packages[i]].name + ":" + opackage[_i].icon + '">' + '<img data-original="' + 'https://www.wanghao.me/wp-content/themes/love/assets/plugins/0w0/images/' + opackage[_i].icon + '.gif" src="" icon="' + opackage[_i].text + '"></li>';
} else {
html += '\n <li class="OwO-item" title="' + opackage[_i].text + '">' + opackage[_i].icon + '</li>';
}
}

html += '\n </ul>';
}

html += '\n <div class="OwO-bar">\n <ul class="OwO-packages">';

for (var _i2 = 0; _i2 < this.packages.length; _i2++) {
html += '\n <li><span>' + this.packages[_i2] + '</span></li>';
}

html += '\n </ul>\n </div>\n </div>\n ';
this.container.innerHTML = html; // bind event

this.logo = this.container.getElementsByClassName('OwO-logo')[0];
this.logo.addEventListener('click', function () {
_this2.toggle();
});
this.container.getElementsByClassName('OwO-body')[0].addEventListener('click', function (e) {
var target = null;
var type = 0;

if (e.target.classList.contains('OwO-item')) {
target = e.target; //console.log("文字表情");
} else if (e.target.parentNode.classList.contains('OwO-item')) {
target = e.target.parentNode; //target = e.target;
//console.log("图片表情");
}

if (target) {
var startPos = _this2.area.selectionStart;
var endPos = _this2.area.selectionEnd;
var areaValue = _this2.area.value;
var insertContent;

if (target.dataset.hasOwnProperty("input")) {
insertContent = " ::" + target.dataset.input + ":: ";
} else {
insertContent = target.innerHTML;
}

_this2.area.value = areaValue.slice(0, startPos) + insertContent + areaValue.slice(endPos); //console.log("areaValue" + areaValue); 编辑器的内容
//console.log("target" + insertContent); //插入的内容

_this2.area.selectionStart = startPos + insertContent.length;
_this2.area.selectionEnd = startPos + insertContent.length;

_this2.area.focus(); //定位到光标位置

_this2.toggle();
}
});
this.packagesEle = this.container.getElementsByClassName('OwO-packages')[0];

var _loop = function _loop(_i3) {
(function (index) {
_this2.packagesEle.children[_i3].addEventListener('click', function () {
_this2.tab(index);
});
})(_i3);
};

for (var _i3 = 0; _i3 < this.packagesEle.children.length; _i3++) {
_loop(_i3);
}

this.tab(0);
}
}, {
key: 'toggle',
value: function toggle() {
// console.log("toggle");
if (this.container.classList.contains('OwO-open')) {
this.container.classList.remove('OwO-open');
} else {
this.container.classList.add('OwO-open');
}

var secret = document.getElementById("secret_comment");

if (secret) {
if (secret.offsetParent === null) {
secret.style.display = "block";
} else {
secret.style.display = "none";
}
} //懒加载该区域类的图片

try {
$("img").lazyload({
effect: "fadeIn"
});
} catch (e) {
// console.log(this.container.classList);
if (this.container.classList.contains("OwO-open")) {
var a = this.container.querySelectorAll(".OwO-items.OwO-items-show>li img");
[].forEach.call(a, function (a) {
var b = a.dataset.original;
b && (a.src = b, a.removeAttribute("data-src"));
});
}
}
}
}, {
key: 'tab',
value: function tab(index) {
// console.log("tab");
//切换选项卡对于的ul区域显示
var itemsShow = this.container.getElementsByClassName('OwO-items-show')[0];

if (itemsShow) {
itemsShow.classList.remove('OwO-items-show');
}

this.container.getElementsByClassName('OwO-items')[index].classList.add('OwO-items-show'); //切换选项卡的选中状态

var packageActive = this.container.getElementsByClassName('OwO-package-active')[0];

if (packageActive) {
packageActive.classList.remove('OwO-package-active');
}

this.packagesEle.getElementsByTagName('li')[index].classList.add('OwO-package-active'); //懒加载该区域类的图片

try {
$("img").lazyload({
effect: "fadeIn"
});
} catch (e) {
if (this.container.classList.contains("OwO-open")) {
var a = this.container.querySelectorAll(".OwO-items.OwO-items-show>li img");
[].forEach.call(a, function (a) {
var b = a.dataset.original;
b && (a.src = b, a.removeAttribute("data-original"));
});
}
}
}
}]);

return OwO;
}();

if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
module.exports = OwO;
} else {
window.OwO = OwO;
}
})();

代码比较多,大家仔细研究,并根据自己的主题修改表情图片位置及格式。
然后json文件中图片表情更改如下:

json

"图片表情": {
"type": "image",
"container": [
{
"icon": "haha",
"text": "haha"
}
]
}

现在发表评论表情时评论框会显示::haha::,发表成功也是这样,而不是具体的haha表情图片,这是因为我们还需要对表情短代码与图片进行转义,在functions.php文件中加入下列代码:

php

add_filter('smilies_src','custom_smilies_src',1,10);
function custom_smilies_src ($img_src, $img, $siteurl){
return get_bloginfo('template_directory').'/assets/images/smiles/'.$img;
//注意表情图片路径
}
function disable_emojis_tinymce( $plugins ) {
return array_diff( $plugins, array( 'wpemoji' ) );
}
function smilies_reset() {
global $wpsmiliestrans, $wp_smiliessearch;
if ( !get_option( 'use_smilies' ))
return;
$wpsmiliestrans = array(
'::haha::' => 'haha.gif',
);
}
smilies_reset();

现在试试是不是可以愉快的发表表情了,样式及代码路径等根据自己的主题来适配。

上面是关于评论加入表情按钮和发表评论添加表情的方法,当然还可以在发表文章时插入表情符号。

文章中插入表情符号

同样打开functions.php文件,加入下列代码即可。注意表情路径改为你自己的。

PHP

function fa_get_wpsmiliestrans() {
global $wpsmiliestrans;
$wpsmilies = array_unique($wpsmiliestrans);
$output = '';
foreach ($wpsmilies as $alt => $src_path) {
$output.= '<a class="add-smily" data-smilies="' . $alt . '"><img class="wp-smiley" style="height:24px;width:24px;" src="' . get_bloginfo('template_directory') . '/assets/plugins/0w0/images/' . rtrim($src_path, "gif") . 'gif" /></a>';
}
return $output;
}
add_action('media_buttons_context', 'fa_smilies_custom_button');
function fa_smilies_custom_button($context) {
$context = '';
$context.= '<style>.smilies-wrap{background:#fff;border: 1px solid #ccc;box-shadow: 2px 2px 3px rgba(0, 0, 0, 0.24);padding: 10px;position: absolute;top: 60px;width: 375px;display:none}.smilies-wrap img{height:24px;width:24px;cursor:pointer;margin-bottom:5px} .is-active.smilies-wrap{display:block}</style> <a id="insert-media-button" style="position:relative; line-height:36px" class="button insert-smilies add_smilies" title="添加表情" data-editor="content" href="javascript:;">^_^ 添加表情</a><div class="smilies-wrap">' . fa_get_wpsmiliestrans() . '</div><script>jQuery(document).ready(function(){jQuery(document).on("click", ".insert-smilies",function() { if(jQuery(".smilies-wrap").hasClass("is-active")){jQuery(".smilies-wrap").removeClass("is-active");}else{jQuery(".smilies-wrap").addClass("is-active");}});jQuery(document).on("click", ".add-smily",function() { send_to_editor(" " + jQuery(this).data("smilies") + " ");jQuery(".smilies-wrap").removeClass("is-active");return false;});});</script>';
return $context;
}

参考资料

OwO表情插件:https://github.com/DIYgod/OwO
Emojipedia: https://emojipedia.org
Handsome-static:https://github.com/ihewro/handsome-static
新浪微博表情api: https://api.weibo.com/2/emotions.json?source=1362404091

这种表情图标样式及功能其实一直是我想要的,只是一直以来因为自己的能力问题没有实现,今天终于解决了!在此感谢插件作者(江湖人称狗哥)和CFanLost及其Typecho网站的主题作者。
现在的表情图标不是很多,后续慢慢补充,如果大家想要补充什么图标欢迎在下面评论告诉我。

资源下载

那年 • 今日
老王发布于2021-04-05 17:01
楚客追梦情难休,万里追寻志未酬。

赞助 点赞 0

Boke.One, Ourboke联盟, 小陆花, Sam.Z, 阿和, 老麦, Mr.Chou, 格子老师等人对本文发表了19条热情洋溢的评论。
  • Boke.One说道: LV.0
    太麻烦了,算了
    1. 老王说道:
      回复 Boke.One: 看着麻烦,其实折腾起来很简单的!😀
  • Ourboke联盟说道: LV.2
    和我WP的教程有点不要一样
    1. 老王说道:
      回复 Ourboke联盟: 嗯,刚看了一下你那里的,我这个是有几组表情,而且方法是针对评论和文章一起的,你那个是只是针对文章的。
  • 小陆花说道: LV.2
    哈哈哈,我的主题自带表情🙈🙈🙈不用折腾了。 ::alu:exclaim::
    1. 老王说道:
      回复 小陆花: 你的评论功能比较强大 ::alu:mrgreen:: 你最近发评论邮箱总把u打成i,所以评论直接被隔离了 😂
  • Sam.Z说道: LV.1
    ::alu:lol:: 可以, 这套手工添加代码比插件更适配, 问下, 你的代码高亮也是手工添加的代码么
    1. 老王说道:
      回复 Sam.Z: 嗯,代码高亮用的Prism,一个js文件和一个css文件,然后使用短代码!
  • 老麦说道: LV.2
    我就把表情全禁了。我发现我换到wordpress后我的云服务器好吃紧,一是静态资源,二是不会优化。看来我还有很长的路要走,一路折腾。哈哈哈
    1. 老王说道:
      回复 老麦: WP确实有点耗资源,我也不会优化,所以参考别人的装了一个缓存插件! ::alu:exclaim::
  • 阿和说道: LV.5
    又开始折腾了,你最近发的都是代码呀,精力如此旺盛 ::wb:geili::
    1. 老王说道:
      回复 阿和: 其实这个是一直想要实现的,只是之前没有成功,这不突然有了灵感,就搞定了。 ::wb:wl::
      1. 阿和说道: LV.5
        回复 老王: 现在的表情确实比之前简洁了不少,你就继续折腾吧,说不定啥时候我也来搬运下你的新功能 ::wb:guzhang::
        1. 老王说道:
          回复 阿和: 嗯嗯,你那个表情有点不智能,回复时还要复制,太麻烦了 ::alu:meditation::
          1. 阿和说道: LV.5
            回复 老王: 哈哈,确实,我那叫傻瓜式 ::wb:kaixin:: 话说你邮件回复里的“查阅详情”链接有点问题。。。
  • Mr.Chou说道: LV.4
    我的数据库虽已支持emoji,但没有把所以图标列出来..能简则简; 为了将来可能换主题减少工作量。
    1. 老王说道:
      回复 Mr.Chou: 嗯,我是太闲了! ::alu:exclaim:: 其实都是单独的文件,换主题直接搬过去即可! ::alu:cool::
  • 格子老师说道: LV.1
    厉害了!!!
    1. 老王说道:
      回复 格子老师: 格子老师,好久不见!你的网站咋访问不了??
  • 发表回复

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