欢迎关注大数据技术架构与案例微信公众号:过往记忆大数据
过往记忆博客公众号iteblog_hadoop
欢迎关注微信公众号:
过往记忆大数据

WordPress所有分页URL由/page/n/变成/page-n.html实现

  最近,本博客由于流量增加,网站响应速度变慢,于是将全站页面全部静态化了;其中采取的方式主要是
(1)、把所有https://www.iteblog.com/archives/\d{1,}全部跳转成https://www.iteblog.com/archives/\d{1,}.html,比如之前访问https://www.iteblog.com/archives/1983链接会自动跳转到https://www.iteblog.com/archives/1983.html
(2)、所有https://www.iteblog.com/page页面会跳转到https://www.iteblog.com/page/,比如现在访问https://www.iteblog.com/support链接会自动跳转到https://www.iteblog.com/support/
上面这样做的目的就是方便将所有页面完全静态化处理,这样会使网站访问速度有明显的提升。


如果想及时了解Spark、Hadoop或者Hbase相关的文章,欢迎关注微信公共帐号:iteblog_hadoop

现在我想把WordPress的分页页面的URL上也加上html后缀,也就是将https://www.iteblog.com/page/2/链接变成https://www.iteblog.com/page-2.html,而且所有URL上带有 page 的全部变成这样,如下:

https://www.iteblog.com/archives/category/spark/page/2/ => https://www.iteblog.com/archives/category/spark/page-2.html

https://www.iteblog.com/archives/tag/spark/page/2/ => https://www.iteblog.com/archives/tag/spark/page-2.html

https://www.iteblog.com/archives/date/2017/02/page/2/ => https://www.iteblog.com/archives/date/2017/02/page-2.html

因为这样做可以把同一种类的页面全部放在一起,这样方便页面静态化管理。但是我在网上找了好久也没发现如何实现这个功能,只能自己实现了!不过皇天不负有心人,最后经过各种尝试终于实现了这个效果。本文将分享我是如何实现的。

将所有分页URL由/page/n/变成/page-n.html

  这步我认为是最复杂的,因为我们需要将所有分页的URL由/page/n/变成/page-n.html,我尝试了很多办法都没有效果。最后我想到了使用user_trailingslashit钩子,如下:

add_filter('user_trailingslashit', 'ppm_fixe_trailingslash', 10, 2);
function ppm_fixe_trailingslash($url, $type){
  if ('single' === $type){
    return $url;
  }
  if('paged' === $type && preg_match('/page\/(\d{1,})$/', $url, $matchs) && $matchs){
        return 'page-' . $matchs[1] . '.html';
  }
  return trailingslashit($url);
}

上面代码的意思是如果页面的类型是single(也就是普通的文章页),什么也不做直接返回;如果类型是paged,这就是我这篇文章要说的分页页面/page/n/,而且URL满足/page\/(\d{1,})$/格式(也就是/page/2/),然后我就会将/page/n/变成/page-n.html。经过上面代码的替换,分页页面的URL生成如下:

<div class="pagination"><ul><li class="prev-page"></li><li class="active"><span>1</span></li><li><a href='https://www.iteblog.com/archives/category/spark/page-2.html'>2</a></li><li><a href='https://www.iteblog.com/archives/category/spark/page-3.html'>3</a></li><li><a href='https://www.iteblog.com/archives/category/spark/page-4.html'>4</a></li><li><a href='https://www.iteblog.com/archives/category/spark/page-5.html'>5</a></li><li><a href='https://www.iteblog.com/archives/category/spark/page-6.html'>6</a></li><li><span> ... </span></li><li><a href='https://www.iteblog.com/archives/category/spark/page-27.html'>27</a></li><li class="next-page"><a href="https://www.iteblog.com/archives/category/spark/page-2.html" >下一页</a></li><li><span>共 27 页</span></li></ul></div>

这个看起来很符合我们的要求。但是当我们随机进入一个翻页页面,生成的URL代码如下:

<div class="pagination"><ul><li class="prev-page"><a href="https://www.iteblog.com/archives/category/spark/page-2.html" >上一页</a></li><li><a href='https://www.iteblog.com/archives/category/spark/page-2.html'>1</a></li><li class="active"><span>2</span></li><li><a href='https://www.iteblog.com/archives/category/spark/page-2.html/page-3.html'>3</a></li><li><a href='https://www.iteblog.com/archives/category/spark/page-2.html/page-4.html'>4</a></li><li><a href='https://www.iteblog.com/archives/category/spark/page-2.html/page-5.html'>5</a></li><li><a href='https://www.iteblog.com/archives/category/spark/page-2.html/page-6.html'>6</a></li><li><a href='https://www.iteblog.com/archives/category/spark/page-2.html/page-7.html'>7</a></li><li><span> ... </span></li><li><a href='https://www.iteblog.com/archives/category/spark/page-2.html/page-27.html'>27</a></li><li class="next-page"><a href="https://www.iteblog.com/archives/category/spark/page-2.html/page-3.html" >下一页</a></li><li><span>共 27 页</span></li></ul></div>

我擦,URL变得不正常了,你访问哪个翻页,其余的翻页URL都会加上这个分页的URL,比如我现在访问的是第二页,其余的URL都加上了page-2.html,变成了https://www.iteblog.com/archives/category/spark/page-2.html/page-6.html,这显然不是我要的!这个又研究了好久,最后用ob_start解决了。

ob_start可以获取所有生成的html,所有我们可以在这里面进行一些操作,我们只需要把多余的路径去掉即可,实现代码如下:

function callback($content) {
        preg_match('/<a.*?href=["|\'](.*?)(\/page-\d{1,}\.html?)\/?(page-\d{1,}\.html)?(.*?)["|\'].*?>/',$content,$matches);
        if($matches) return str_replace($matches[2], "",$content);
        return $content;
}
ob_start("callback");

这样我们把所有类似于https://www.iteblog.com/archives/category/spark/page-2.html/page-6.html的页面替换成https://www.iteblog.com/archives/category/spark/page-6.html了,多余的/page-2.html被替换成空字符串了,好了大功告成了!现在所有分页的URL全部由/page/n/变成/page-n.html,这正是我需要的。

添加URL规则

  不过你以为现在就完了吗?现在我们所有的分页URL全部已经变成了/page-n.html,但是你现在去访问这个URL,你肯定得到的是404!以为WordPress还是使用默认的URL规则,比如我们访问分类页面的URL肯定是还是https://www.iteblog.com/archives/category/spark/page/2/,你直接访问https://www.iteblog.com/archives/category/spark/page-2.html是不行的!我们需要重写这个规则(rewrite rules)(不知道如何重写?看《如何在WordPress中自定义URL规则(rewrite rules)》),我们需要将分类的URLindex.php?category_name=$matches[1]&paged=$matches[2]重写到archives/category/(.*)/page-([0-9]{1,}).html$;如果你仔细分析WordPress分页URL的话,你会发现所有的分页页面都带有paged,所有我们只需要把所有带有paged的URL重写即可,所有的重写实现如下:

function add_rewrite_rules($aRules){
        $aNewRules = array(
                'archives/category/(.*)/page-([0-9]{1,}).html$' => 'index.php?category_name=$matches[1]&paged=$matches[2]',
                'archives/tag/(.*)/page-([0-9]{1,}).html$' => 'index.php?tag=$matches[1]&paged=$matches[2]',
                'archives/type/([^/]+)/page-([0-9]{1,}).html$' => 'index.php?post_format=$matches[1]&paged=$matches[2]',
                'archives/wpwsl_template/([^/]+)/page-([0-9]{1,}).html$' => 'index.php?post_type=wpwsl_template&name=$matches[1]&paged=$matches[2]',
                'page-([0-9]{1,}).html?$' => 'index.php?&paged=$matches[1]',
                'search/(.+)/page-([0-9]{1,}).html$' => 'ndex.php?s=$matches[1]&paged=$matches[2]',
                'archives/author/([^/]+)/page-([0-9]{1,}).html$' => 'index.php?author_name=$matches[1]&paged=$matches[2]',
                'archives/date/([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})/page-([0-9]{1,}).html$' => 'index.php?year=$matches[1]&monthnum=$matches[2]&day=$matches[3]&paged=$matches[4]',
                'archives/date/([0-9]{4})/([0-9]{1,2})/page-([0-9]{1,}).html$' => 'index.php?year=$matches[1]&monthnum=$matches[2]&paged=$matches[3]',
                'archives/date/([0-9]{4})/page-([0-9]{1,}).html$' => 'index.php?year=$matches[1]&paged=$matches[2]',
                'archives/([0-9]+).html/page-([0-9]{1,}).html$' => 'index.php?p=$matches[1]&paged=$matches[2]',
                '(.?.+?)/page-([0-9]{1,}).html$' => 'index.php?pagename=$matches[1]&paged=$matches[2]'
        );
        $aRules = $aNewRules + $aRules;
        return $aRules;
}
add_filter('rewrite_rules_array', 'add_rewrite_rules');

好了,到这里,分页页面已经全部正常访问了!

这里再多说几句,如果你网站已经运行了好久,那么搜索引擎可能已经收录了你相应分页的URL记录,为了不让这些页面进来出现404错误,你需要在WEB服务器(比如Nginx)上做永久的跳转,也就是301跳转,这样就不会影响你的网站。为了简便,这里我介绍一下如何在Nginx里面编写301规则,如下:

rewrite ^/archives/tag/(.+)/page/([0-9]+)/$ /archives/tag/$1/page/$2.html permanent;

上面把所有tag的翻页URL跳转到带有html后缀的链接;其余的URL可以类似这么写。但是这样写很啰嗦,其实我们可以直接用下面一句即可实现同样的效果:

rewrite (.*)?/page/([0-9]+)/?$ /page-$2.html permanent;

这样所有带有page的URL全部都会跳转到带有html后缀的URL上,最后重启Nginx服务器,大功告成啦!

本博客文章除特别声明,全部都是原创!
原创文章版权归过往记忆大数据(过往记忆)所有,未经许可不得转载。
本文链接: 【WordPress所有分页URL由/page/n/变成/page-n.html实现】(https://www.iteblog.com/archives/1983.html)
喜欢 (9)
分享 (0)
发表我的评论
取消评论

表情
本博客评论系统带有自动识别垃圾评论功能,请写一些有意义的评论,谢谢!
(2)个小伙伴在吐槽
  1. 你好,我想知道您的 不带html的网址怎么跳转到带html网址的,我现在就遇到了这个问题,不能成功跳转,请赐教一下代码。谢谢

    刘晨2018-09-03 10:39 回复
  2. 使用ob_start删掉多余路径时有个问题,因为首页并没有page-1.html这样的后缀,导致当前处于首页时,第二页的页码没有page-2.html这样的链接,请问这个问题该怎么解决?谢谢

    雨小睡2018-03-31 16:59 回复