上一篇文章写到了 WordPress 升级 4.2 版本后部分主题出现了大量 404 请求的问题,匆忙解决也没深究原因。今天继续调试主题却发现了评论表情不显示了,看来又是 4.2 惹的祸了!
于是埋头折腾,总算把问题解决了,为了方便遇到和我一样问题的站长,张戈特意将修复方法整理成 PHP 补丁,降低修复难度,如果你也遇到此类问题,且往下看。
一、前因后果
这次 WordPress 升级 4.2 总体来说没有以前版本升级来得顺畅,目前已发现如下 3 个问题:
- 有部分主题的前台会产生大量的 404 错误请求(站外资源);
- 评论表情名称变更导致表情无法显示或者无法通过钩子更改;
- 外观-->菜单-->显示选项-->点不出来(已有修复方法,猛戳直达==>)。
第 1 个问题:分析了一下原因,和以前出现的谷歌字体加载卡出翔的情况类似,部分主题可能触发了 4.2 新增的 CDN 功能,在前台插入了国外 CDN 资源,不巧却被厚实 GFW 关门闭客了,而且居然还有重试机制,于是就产生了大量的错误请求!
第 2 个问题:其实是因为 4.2 对评论表情的重构(样式变更、名称变更、CDN 机制等)造成的。和第 1 个问题有所关联,都不约而同的和 4.2 下的 emoji 关键标签挂上了钩。emoji 这个玩意我暂时还没有去研究是啥新玩意,但从目前的情况来看,这个玩意暂时不适合天朝环境。。。
张戈博客上一篇文章《解决 WordPress 升级 4.2 后调用国外图片导致大量 404 请求的问题》已经粗略分享了解决办法,不过在下文中还会分享一个整体修复补丁。
正对第 2 个问题,下面说一下手动修复方法。
二、修复思路
表情名称重构了,所以我们需要找到那个表情过滤函数,然后改变它。我们知道评论表情里面有名为 mrgreen 的表情代号,所以最笨最有效的方法就是在 WordPress 全局搜索存在这个关键词的 php 文件(可以在 Linux 下 grep,也可以在 Windows 下借用 UE 或 Editor ++等),幸不辱命,总算顺藤摸瓜找到症结所在!
①、表情名称变更
问题截图:
通过搜索,我找到了这个将代号过滤成表情文件的函数 smilies_init ,位于 wp-includes/functions.php 文件中。
新版本代码:
明显把文件名称给改了,所以修复方法就是用老版代码替换新版本代码即可。
②、表情尺寸异常
解决表情不显示问题之后,发现这表情尺寸也醉了:
先让我感叹一下,老外的视力素质真的都这么好吗?反正我是觉得太小了。。。
还是老方法,全局搜索 height: 1em; max-height: 1em ,立竿见影!在 wp-includes/formatting.php 找到 3 处相关代码。
先手动修改后发现还是不凑效,于是继续检查,发现网站前台还输出了一个表情样式定义:
<style type="text/css"> img.wp-smiley, img.emoji { display: inline !important; border: none !important; box-shadow: none !important; height: 1em !important; width: 1em !important; margin: 0 .07em !important; vertical-align: -0.1em !important; background: none !important; padding: 0 !important; } </style>
于是继续全局搜索以上代码中的关键词,于是又找到了 print_emoji_styles() 函数,在通过函数名找到调用地方,手动注释后发现可以解决问题:
接下来就是发现问题就依葫芦画瓢解决问题问题的过程,最终全部搞定!
动手能力强的朋友估计已经去折腾去了,如果你觉得这样很麻烦,那就继续往下看吧!
三、修复补丁
这样修改不但麻烦,而且一旦 WP 更新,统统失效,所以张戈整理成一个 php 补丁,分享给大家,只要集成到主题中就可以解决这些问题了!
具体代码如下:
<?php /** * 修复 WordPress 升级 4.2 带来的各种问题 By 张戈博客 * 原文地址①:https://zhang.ge/5034.html * 原文地址②:https://zhang.ge/5035.html * 修复说明: * ①、部分主题出现大量 404 请求 * ②、修复表情路径异常问题 * ③、后续遇到问题将继续更新 * */ remove_action( 'wp_head','print_emoji_detection_script',7); //解决 4.2 版本部分主题大量 404 请求问题 remove_action('admin_print_scripts', 'print_emoji_detection_script'); //解决后台 404 请求 remove_action( 'init', 'smilies_init', 5); //移除 4.2 版本表情钩子 remove_action( 'wp_print_styles', 'print_emoji_styles' ); //移除 4.2 版本前台表情样式钩子 remove_action( 'admin_print_styles', 'print_emoji_styles'); //移除 4.2 版本后台表情样式钩子 remove_action( 'the_content_feed', 'wp_staticize_emoji'); //移除 4.2 emoji 相关钩子 remove_action( 'comment_text_rss', 'wp_staticize_emoji'); //移除 4.2 emoji 相关钩子 remove_action( 'comment_text', 'convert_smilies', 20 ); //移除 4.2 表情相关钩子 remove_action( 'the_content', 'convert_smilies' ); //移除 4.2 表情相关钩子 remove_action( 'the_excerpt', 'convert_smilies' ); //移除 4.2 表情相关钩子 add_action( 'comment_text', 'convert_smilies_diy', 20); //自定义表情相关钩子 add_action( 'the_content', 'convert_smilies_diy' ); //自定义表情相关钩子 add_action( 'the_excerpt', 'convert_smilies_diy' ); //自定义表情相关钩子 add_action( 'init', 'smilies_init_old', 5 ); //自定义表情钩子 //原函数 smilies_init 位于 wp-includes/functions.php function smilies_init_old() { global $wpsmiliestrans, $wp_smiliessearch; // don't bother setting up smilies if they are disabled if ( !get_option( 'use_smilies' ) ) return; if ( !isset( $wpsmiliestrans ) ) { $wpsmiliestrans = array( ':mrgreen:' => 'icon_mrgreen.gif', ':neutral:' => 'icon_neutral.gif', ':twisted:' => 'icon_twisted.gif', ':arrow:' => 'icon_arrow.gif', ':shock:' => 'icon_eek.gif', ':smile:' => 'icon_smile.gif', ':???:' => 'icon_confused.gif', ':cool:' => 'icon_cool.gif', ':evil:' => 'icon_evil.gif', ':grin:' => 'icon_biggrin.gif', ':idea:' => 'icon_idea.gif', ':oops:' => 'icon_redface.gif', ':razz:' => 'icon_razz.gif', ':roll:' => 'icon_rolleyes.gif', ':wink:' => 'icon_wink.gif', ':cry:' => 'icon_cry.gif', ':eek:' => 'icon_surprised.gif', ':lol:' => 'icon_lol.gif', ':mad:' => 'icon_mad.gif', ':sad:' => 'icon_sad.gif', '8-)' => 'icon_cool.gif', '8-O' => 'icon_eek.gif', ':-(' => 'icon_sad.gif', ':-)' => 'icon_smile.gif', ':-?' => 'icon_confused.gif', ':-D' => 'icon_biggrin.gif', ':-P' => 'icon_razz.gif', ':-o' => 'icon_surprised.gif', ':-x' => 'icon_mad.gif', ':-|' => 'icon_neutral.gif', ';-)' => 'icon_wink.gif', // This one transformation breaks regular text with frequency. // '8)' => 'icon_cool.gif', '8O' => 'icon_eek.gif', ':(' => 'icon_sad.gif', ':)' => 'icon_smile.gif', ':?' => 'icon_confused.gif', ':D' => 'icon_biggrin.gif', ':P' => 'icon_razz.gif', ':o' => 'icon_surprised.gif', ':x' => 'icon_mad.gif', ':|' => 'icon_neutral.gif', ';)' => 'icon_wink.gif', ':!:' => 'icon_exclaim.gif', ':?:' => 'icon_question.gif', ); } if (count($wpsmiliestrans) == 0) { return; } /* * NOTE: we sort the smilies in reverse key order. This is to make sure * we match the longest possible smilie (:???: vs :?) as the regular * expression used below is first-match */ krsort($wpsmiliestrans); $spaces = wp_spaces_regexp(); // Begin first "subpattern" $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 . '|$)'; // End previous "subpattern" $wp_smiliessearch .= '|(?<=' . $spaces . '|^)'; // Begin another "subpattern" } $subchar = $firstchar; $wp_smiliessearch .= preg_quote($firstchar, '/') . '(?:'; } else { $wp_smiliessearch .= '|'; } $wp_smiliessearch .= preg_quote($rest, '/'); } $wp_smiliessearch .= ')(?=' . $spaces . '|$)/m'; } //原函数 convert_smilies 位于 wp-includes/formatting.php function convert_smilies_diy( $text ) { global $wp_smiliessearch; $output = ''; if ( get_option( 'use_smilies' ) && ! empty( $wp_smiliessearch ) ) { // HTML loop taken from texturize function, could possible be consolidated $textarr = preg_split( '/(<.*>)/U', $text, -1, PREG_SPLIT_DELIM_CAPTURE ); // capture the tags as well as in between $stop = count( $textarr );// loop stuff // Ignore proessing of specific tags $tags_to_ignore = 'code|pre|style|script|textarea'; $ignore_block_element = ''; for ( $i = 0; $i < $stop; $i++ ) { $content = $textarr[$i]; // If we're in an ignore block, wait until we find its closing tag if ( '' == $ignore_block_element && preg_match( '/^<(' . $tags_to_ignore . ')>/', $content, $matches ) ) { $ignore_block_element = $matches[1]; } // If it's not a tag and not in ignore block if ( '' == $ignore_block_element && strlen( $content ) > 0 && '<' != $content[0] ) { $content = preg_replace_callback( $wp_smiliessearch, 'translate_smiley_diy', $content ); } // did we exit ignore block if ( '' != $ignore_block_element && '</' . $ignore_block_element . '>' == $content ) { $ignore_block_element = ''; } $output .= $content; } } else { // return default text. $output = $text; } return $output; } //原函数 translate_smiley 位于 wp-includes/formatting.php function translate_smiley_diy( $matches ) { global $wpsmiliestrans; if ( count( $matches ) == 0 ) return ''; $smiley = trim( reset( $matches ) ); $img = $wpsmiliestrans[ $smiley ]; $matches = array(); $ext = preg_match( '/\.([^.]+)$/', $img, $matches ) ? strtolower( $matches[1] ) : false; $image_exts = array( 'jpg', 'jpeg', 'jpe', 'gif', 'png' ); // Don't convert smilies that aren't images - they're probably emoji. if ( ! in_array( $ext, $image_exts ) ) { return $img; } /** * Filter the Smiley image URL before it's used in the image element. * * @since 2.9.0 * * @param string $smiley_url URL for the smiley image. * @param string $img Filename for the smiley image. * @param string $site_url Site URL, as returned by site_url(). */ //请注意!已将表情路径定义到主题目录下的 images/smilies 文件夹 $src_url = apply_filters( 'smilies_src', get_bloginfo('template_directory').'/images/smilies/'.$img, $img, site_url() ); return sprintf( '<img src="%s" alt="%s" class="wp-smiley" style="/*height: 1em; max-height: 1em;*/" />', esc_url( $src_url ), esc_attr( $smiley ) ); } ?>
将下载的文件解压,并查看代码倒数第 5 行中的表情路径和你主题所用表情是否对应,若不对应请自行根据实际情况修改 /images/smilies 指向你的表情文件夹即可(若没有表情文件,请从本文下载并上传到主题目录亦可)。
然后上传到主题目录,修改主题目录下的 functions.php,在最后一个?>之前新增如下调用代码即可:
//4.2 修复补丁,请注意 patch_to_4.2.php 路径是否正确。 include("patch_to_4.2.php");
保存后,去前台刷新应该就一切正常了。
四、惯例总结
本次 WordPress 升级感觉改动还是挺大的,所以肯定也存在不少 BUG,尤其是在格格不入的天朝环境下更是容易出现一些卡出翔的问题。不过 WordPress 在天朝的使用率如此之高,相信官方很快就会更新下一个版本,来修复诸如此类的问题。
张戈也算是一个狂热的 WordPress 折腾爱好者,所以在官方修复之前先将自己的折腾成功分享出来,让更新出现问题的站长提前解决这些烦人的问题。
好了,就说这么多了,如果你更新后没有这些问题,就当本文分享的是一个解决 WordPress 网站故障的一个思路吧!
哇,这个主题蛮不错的么.
为什么你这有的这三个问题我都没有……
前2个问题和主题有关系,第三个问题理论上都有,目前还不知道原因,修复方法上午已分享。
修复补丁的下载链接失效了 :shock:
多谢反馈,已修复~
可以加一句
不然后台也会一直 s.w.org... 加载中
多谢反馈,一会更新进去。
替换之后下次升级还是会变~
把补丁集成到主题当中就不会了。
4.2.2头像尺寸也异常了。前台后台头像都是100px。博主有办法么
非常好的补丁,出现的所有网络问题秒解决。 :smile:
我的表情大小问题依旧没能解决,有办法吗?
博主太厉害了,按照你的方法果然好用了!
升级到最新版后发现这个图片 怎么解决?
http://s.wordpress.org/images/browsers/firefox.png
没见过。。
原来变了这么多,正诧异我的主题表情怎么废掉了呢。。
:mrgreen: [color=red]太给力了,已解决,谢谢[/color]
看起来挺难解决,慢慢看吧
又帮到我忙了,非常感谢!~
wp5.2下,让文章支持表情,以上代码没成功,找了很多文章,都搞不定,还要请大师出马了,多谢
试试插件:WP-EmojiOne