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

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

表情评论发表后表情不显示发现越来越多朋友的网站评论上不仅有表情,而且有好几组表情。怀着别人家那么“富裕”而为什么我们家这么“穷”的心情,想着我们也应该要走上“富裕”的道路。 时间:2020年10月14日 评论:32

虽然所有的图标都分好类了,但不是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文件。


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

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


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

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


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代码:


<img src="haha.gif">

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


"文字": {
"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代码如下:


"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文件中图片表情更改如下:


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

现在发表评论表情时评论框会显示::haha::,发表成功也是这样,而不是具体的haha表情图片,这是因为我们还需要对表情短代码与图片进行转义,在functions.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文件,加入下列代码即可。注意表情路径改为你自己的。


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网站的主题作者。
现在的表情图标不是很多,后续慢慢补充,如果大家想要补充什么图标欢迎在下面评论告诉我。

资源下载

OwO表情插件
WordPress / Typecho ……系统 | 2016版本 | 27kb大小 | 下载4次

Ourboke联盟, 小陆花, Sam.Z, 阿和, 老麦, Mr.Chou, 格子老师等人对本文发表了17条热情洋溢的评论。
  1. Ourboke联盟说道: 2 来自天朝的朋友 Firefox Windows 10

    和我WP的教程有点不要一样

    1. 老王说道: 来自天朝的朋友 Safari Mac OS X 10_15_6

      嗯,刚看了一下你那里的,我这个是有几组表情,而且方法是针对评论和文章一起的,你那个是只是针对文章的。

  2. 小陆花说道: 2 来自天朝的朋友 Chrome Linux

    哈哈哈,我的主题自带表情🙈🙈🙈不用折腾了。 ::alu:exclaim::

    1. 老王说道: 来自天朝的朋友 Safari Mac OS X 10_15_6

      你的评论功能比较强大 ::alu:mrgreen::
      你最近发评论邮箱总把u打成i,所以评论直接被隔离了 😂

  3. Sam.Z说道: 1 来自天朝的朋友 Firefox Windows 10

    ::alu:lol:: 可以, 这套手工添加代码比插件更适配, 问下, 你的代码高亮也是手工添加的代码么

    1. 老王说道: 来自天朝的朋友 Safari Mac OS X 10_15_6

      嗯,代码高亮用的Prism,一个js文件和一个css文件,然后使用短代码!

  4. 老麦说道: 1 来自天朝的朋友 Chrome Windows 7

    我就把表情全禁了。我发现我换到wordpress后我的云服务器好吃紧,一是静态资源,二是不会优化。看来我还有很长的路要走,一路折腾。哈哈哈

    1. 老王说道: 来自天朝的朋友 Safari Mac OS X 10_15_6

      WP确实有点耗资源,我也不会优化,所以参考别人的装了一个缓存插件! ::alu:exclaim::

  5. 阿和说道: 5 来自天朝的朋友 QQ浏览器 Windows 7

    又开始折腾了,你最近发的都是代码呀,精力如此旺盛 ::wb:geili::

    1. 老王说道: 来自天朝的朋友 Safari Mac OS X 10_15_6

      其实这个是一直想要实现的,只是之前没有成功,这不突然有了灵感,就搞定了。 ::wb:wl::

      1. 阿和说道: 5 来自天朝的朋友 QQ浏览器 Windows 7

        现在的表情确实比之前简洁了不少,你就继续折腾吧,说不定啥时候我也来搬运下你的新功能 ::wb:guzhang::

        1. 老王说道: 来自天朝的朋友 Safari Mac OS X 10_15_6

          嗯嗯,你那个表情有点不智能,回复时还要复制,太麻烦了 ::alu:meditation::

          1. 阿和说道: 5 来自天朝的朋友 QQ浏览器 Windows 7

            哈哈,确实,我那叫傻瓜式 ::wb:kaixin::
            话说你邮件回复里的“查阅详情”链接有点问题。。。

  6. Mr.Chou说道: 4 来自天朝的朋友 Chrome Windows 10

    我的数据库虽已支持emoji,但没有把所以图标列出来..能简则简;
    为了将来可能换主题减少工作量。

    1. 老王说道: 来自天朝的朋友 Safari Mac OS X 10_15_6

      嗯,我是太闲了! ::alu:exclaim::
      其实都是单独的文件,换主题直接搬过去即可! ::alu:cool::

  7. 格子老师说道: 1 来自天朝的朋友 Chrome Windows 10

    厉害了!!!

    1. 老王说道: 来自天朝的朋友 Safari Mac OS X 10_15_6

      格子老师,好久不见!你的网站咋访问不了??

发表评论

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