解决 WordPress 微信小程序文章内代码显示、图片非 CDN 地址、图片附带链接的问题

文章目录[隐藏]

最近一直在开发后台基于 WordPress 的微信小程序(用的是守望轩的开源模板),遇到了很多问题: wxParse 转换后文章中的代码显示不正常;由于 WordPress 的样式让图片附带了媒体链接;由于 API 的原因获取到的图片地址也不是 CDN 的地址等等。为了解决这些问题修了好几夜的仙,这里呢,就给出我的解决方法:主要就是在小程序把获得的文章内容的响应传给 wxParse 之前用正则表达式替换响应的内容。遇到同样问题的可以参考一下。

wxParse 真的是不完善,本篇文章在小程序里都加载不出来,猜测含有太多“<pre>”和“<code>”标签的代码导致解析炸了 :(黑线) 无奈,真希望微信官方能出一个转换工具。

首先说明一点:不要直接复制代码,我写这篇文章的原因就是想说清其中的原理,我也是照着正则表达式的教程折腾了好几个晚上,要一点一点地去测试。

JavaScript 正则表达式教程:http://www.runoob.com/js/js-regexp.html

代码显示

首先说一下代码显示的问题吧,我博客用的是修改后的 PureHighlightJs 插件来语法高亮的,因此代码使用的是“<pre><code>”标签。结果经过 wxParse 解析后在小程序中变为一行。经过一段时间的调试分析后发现应该是把“<pre>”作为一层,里面的所有内容就变为这一层里的了,因此换行啥的也都不起作用了。当时想到直接修改文章,可是这样成本太大了,一修改代码语法高亮就没了;然后又想到修改 API,让微信获取到不带“<pre>”标签的文章内容,这样就要修改 WordPress 自带的 REST 功能了,有点复杂,像我这种小白搞不了;接着就想能不能修改 wxParse 工具呢,看了 GitHub 上该项目后发现作者已经不再支持了,文档啥的也都不全面,这条也不行;最后呢,我想可不可以修改微信请求 API 后获取到的响应呢?研究了一波模板后发现得到的响应就是一个字符串,然后将该字符串传递给 wxParse 解析为 json,这就给修改提供了可能。原来的函数(在 pages/detail/detail.js 中)是这样的:

//获取文章内容
    fetchDetailData: function (id) {
        var self = this;
        var getPostDetailRequest = wxRequest.getRequest(Api.getPostByID(id));
        var res;
        var _displayLike = 'none';
        getPostDetailRequest
            .then(response => {
                res = response;
                WxParse.wxParse('article', 'html', response.data.content.rendered, self, 5);
                if (response.data.total_comments != null && response.data.total_comments != '') {
                    self.setData({
                        commentCount: "有" + response.data.total_comments + "条评论"
                    });
                };

其中第10行的代码就是将得到的响应中的文章内容部分(response.data.content.rendered )传递给 wxParse ,我的思路呢,就是用 replace 函数将字符串中的“<pre>”标签给替换掉。怎么得到响应的具体内容呢?可以用微信开发者工具调试界面的“Network”部分,当小程序进入某一篇文章时,会有一个以文章 ID 为名的请求(例如“https://blog.sunriseydy.top/wp-json/wp/v2/posts/1055”),得到的响应就是文章的相关数据,在“content”的“rendered”中就是文章的内容,这里我以刚才的那个请求为例,响应内容其中一部分是这样的:

"content":{"rendered":"<p>\u524d\u51e0\u5929 Ubuntu 18.04 \u53d1\u5e03\u4e86\uff0c\u6211\u4e5f\u7b2c\u4e00\u65f6\u95f4\u5b89\u88c5\u4f53\u9a8c\u4e86\u4e00\u628a\uff0c\u7531\u4e8e\u81ea\u5e26\u7684\u90a3\u4e2a\u706b\u72d0\u6d4f\u89c8\u5668\u6211\u5e76\u4e0d\u559c\u6b22\uff0c\u5728\u8c37\u6b4c\u5b98\u7f51\u4e0b\u7684 Chrome \u5b89\u88c5\u5305\u4e5f\u662f deb \u683c\u5f0f\u7684\uff0c\u8fd9\u91cc\u5c31\u987a\u4fbf\u8bb0\u5f55\u4e00\u4e0b Ubuntu \u600e\u4e48\u5b89\u88c5 deb \u5305\u548c\u4fee\u590d\u4f9d\u8d56\u3002\u5176\u5b9e\u547d\u4ee4\u5f88\u7b80\u5355\uff1a<\/p>\n<pre class=\"pure-highlightjs\"><code class=\"bash\">sudo dpkg -i ***********.deb\r\n#\u5982\u679c\u51fa\u73b0\u4f9d\u8d56\u95ee\u9898\uff1a\r\nsudo apt-get -f install\r\n#\u518d\u91cd\u65b0\u5b89\u88c5 deb \u5305\r\nsudo dpkg -i ***********.deb \r\n<\/code><\/pre>\n<p>\u5177\u4f53\u7684\u5185\u5bb9\u5982\u4e0b\uff1a<\/p>\n<p>

重点就是文章代码部分:

<pre class=\"pure-highlightjs\"><code class=\"bash\">sudo dpkg -i ***********.deb\r\n#\u5982\u679c\u51fa\u73b0\u4f9d\u8d56\u95ee\u9898\uff1a\r\nsudo apt-get -f install\r\n#\u518d\u91cd\u65b0\u5b89\u88c5 deb \u5305\r\nsudo dpkg -i ***********.deb \r\n<\/code><\/pre>

可以看到代码是在“<pre><code>”标签中的,其中某些特殊字符被转义掉了,接下来就是要用正则表达式来匹配了,具体的写法如下:

response.data.content.rendered.replace(/<pre[^>]*>/g, "").replace(/<\/pre>/g, "")

经过这两次替换,不论你“<pre>”和“</pre>”中的属性是啥,都会被匹配并被替换为空字符。

可是呀,将“<pre>”标签去掉后在小程序中代码还是显示为一行,“<code>”标签中的换行并没有被解析,因此,我们还要做一次替换,将“<code>”标签中的“\r\n”替换为“<p>\n</p>”,为什么要替换为这个呢?观察之前的响应内容中发现文章中所有的换行都是“<p>\n</p>”,而代码中的换行都是“\r\n”。因此要在之前的替换语句后再加一个:

response.data.content.rendered.replace(/<pre[^>]*>/g, "").replace(/<\/pre>/g, "").replace(/\r\n(?!<\/code>)/g, "<p>\n<\/p>")

后面的“(?!<\/code>)”主要是防止代码最后一行和“</code>”之间的换行也被替换,避免了在小程序中代码最后一行和下面的内容隔了两行(因为“</code>”后面紧跟着一个换行,不需要“</code>”前的换行了)。

还有要注意的是,如果你文章代码中的换行不是“\r\n”的话要对上面的正则表达式进行修改。

这样子修改之后小程序中的代码显示效果就是这样的:

小程序文章代码显示效果
小程序文章代码显示效果

虽然不能做到横向滑动,不过这样子也勉强可以,毕竟要引导用户到原文阅读。

图片问题

图片问题有点多,最主要的就是小程序文章中获取到的图片地址是博客地址而不是 CDN 的,我原本想更改原作者的插件 API ,将图片的地址换为 CDN 的,研究了几天 PHP 和 WordPress 的函数也没搞懂,最后还是在小程序端做文章,同样是替换响应的文章内容,在上一部分代码问题的替换代码中后面再加上一个 replace 函数:

replace(/(<img[^>]*src=\"https:\/\/)blog/g,"$1cdn")

这里我说明一下,我原来的图片地址是 src=“https://blog.sunriseydy.top/*******”,而 CDN 地址是“https://cdn.sunriseydy.top”,因此我的只要将“blog”替换为“cdn”就行了。你的不一定是这样,要更改为相应的正则表达式,提醒一下,注意观察响应内容中的地址是什么样子的。

还有一个问题就是 WordPress 文章添加图片时默认附带了一个链接,链接到图片地址,在守望轩微信小程序模板中链接是有点击复制或者点击打开的动作的,对于图片,如果附带了链接,那么用户在点击的时候不仅预览了图片,也复制或者打开了图片地址。为了避免这个问题,就要去掉图片附带的链接。方法呢,还是用正则表达式替换:

replace(/<a href=[^>]*>(<img[^>]*\/>)<\/a>/g, "$1")

这样子就将“<img>”标签前的“<a>”和后面的“</a>”给去掉了。

总结

这里给出我最终修改后的函数:

WxParse.wxParse('article', 'html', response.data.content.rendered.replace(/<pre[^>]*>/g, "").replace(/<\/pre>/g, "").replace(/\r\n(?!<\/code>)/g, "<p>\n<\/p>").replace(/<a href=[^>]*>(<img[^>]*\/>)<\/a>/g, "$1").replace(/(<img[^>]*src=\"https:\/\/)blog/g,"$1cdn"), self, 5);

再次强调:不要直接复制,我写这篇文章的原因就是想说清其中的原理,我也是照着正则表达式的教程折腾了好几个晚上,要一点一点地去测试。

好啦,结束啦 :(太开心)


版权说明:
作品 sunriseydy 采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。
文章内容如未说明均为原创,欢迎转载,但请注明原作者(sunriseydy)和原文链接(https://blog.sunriseydy.top/technology/server-blog/wordpress/wordpress-wxminiprogram-code-image-problem/)
部分来自互联网的文章,如有侵权,请联系我,24小时内删除,谢谢

手机打开扫一扫即可访问本页面

感谢您的支持,SunriseYDY 会继续努力的!

扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

日出一点一 | 在探索的路上永不止步

分享到微博 分享到QQ 微信赞赏 在手机上阅读 点赞 2

评论一下呗亲

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