»

WordPress长文章分页伪静态链接修改,适合以“年-月-文章名”为链接格式的

    WordPress  
访问htaccess前端Wp Super CacheSEOwindows主机web.config网络安全IISCDN访客CLB身份认证工作WordPress插件伪静态浏览器腾讯云加速Apache查询数据库网站优化爬虫百度云加速WP Rocket

当使用 WordPress 写文章时,如果单篇文章过长,可以考虑进行分页处理。WordPress 内置了一个分页的代码,只需要在文本书写页面、需要分页的地方输入<!--nextpage-->即可。

但是问题来了,通常我们给 WordPress 进行了网址伪静态处理,例如给文章和页面加了 .html 后缀,例如将 /2021/11/09/new-post 的文章修饰成 /2021/11/09/new-post.html 。但如果该文章进行了分页处理,那么,第二页通常就会变成 /2021/11/09/new-post.html/2/ (或 /2021/11/09/new-post.html/2)这种格式,而改变了后缀为 .html 的形式。我们需要的第二页是类似于 /2021/11/09/new-post-2.html 这种格式。

如何做呢?

需要修改重写规则。

知更鸟曾写过一篇关于这个问题的文章,但是由于分页设置的伪静态操作涉及到很多具体环境,无法形成统一的公式,所以只能具体情况具体分析具体解决了。本文主要是针对采用 /%year%/%monthnum%/%postname%.html 这种格式的固定连接的用户,也就是 /年/月/文章名字.html 这种格式。

本文是在知更鸟文章中代码的基础上进行的修改操作。

首先,你应当了解自己 WordPress 系统中固定连接(伪静态链接重写规则)修改的大致情况。可以通过向主题 functions.php 中添加如下代码查看:

  1. add_filter( 'rewrite_rules_array', 'show_rewrite_rules' );   
  2. function show_rewrite_rules( $rules ) {  
  3.   echo nl2br( var_export( $rules, true ) );  
  4.   die;  
  5. }  

打开后台 /wp-admin/options-permalink.php 页面查看,复制里面的内容,取消上述代码。

本文禁止住转载。任何形式转载请联系作者(时光在路上 www.timezls.com)。时光在路上保留所有权利

你会有如下发现,控制 .html 固定连接显示成 .html/2/ 类似格式规则的代码主要有以下几个(可能你的情况与下列有不同):

1. '([0-9]{4})/([0-9]{1,2})/([^/]+).html(?:/([0-9]+))?/?$' => 'index.php?year=$matches[1]&monthnum=$matches[2]&name=$matches[3]&page=$matches[4]',
2. '[0-9]{4}/[0-9]{1,2}/[^/]+.html/([^/]+)/?$' => 'index.php?attachment=$matches[1]',
3. '(.?.+?).html(?:/([0-9]+))?/?$' => 'index.php?pagename=$matches[1]&page=$matches[2]',

一眼就可以看出第一行是我们所需要修改的。

其实第2个也是需要修改的,下面会讲到。

本文禁止住转载。任何形式转载请联系作者(时光在路上 www.timezls.com)。时光在路上保留所有权利

 

重写规则需要修改成如下格式:

'([0-9]{4})/([0-9]{1,2})/([^/]+)-([0-9]+).html$' => 'index.php?year=$matches[1]&monthnum=$matches[2]&name=$matches[3]&page=$matches[4]'

 

而且,为了防止重复链接指向同一文章,我们也需要移除原有的重写规则:([0-9]{4})/([0-9]{1,2})/([^/]+).html(?:/([0-9]+))?/?$ 。因为移除了该规则,导致正常文章无法显示,所以要新增规则:

'([0-9]{4})/([0-9]{1,2})/([^/]+).html$' => 'index.php?year=$matches[1]&monthnum=$matches[2]&name=$matches[3]' 

 

本文禁止全文转载。任何形式转载请联系作者(时光在路上 www.timezls.com) Copyright © 2024. All Rights Reserved

另外,也应把 [0-9]{4}/[0-9]{1,2}/[^/]+.html/([^/]+)/?$ 移除,这个是查看附件的页面链接,反正也没啥用。多了这个反而会出现查看 /年/月/文章名字.html/2/  的时候301跳转到 /年/月/文章名字.html/2/1 的情况,默认找附件去鸟~ 把它移除,那么就会直接返回404,而不会自动301跳转。

代码如下:

本文禁止无授权转载 - 时光在路上 www.timezls.com 保留所有权利

 

  1. // 添加分页处理规则,适合 /%year%/%monthnum%/%postname%.html 分页链接修正   
  2. class Rewrite_Inner_Page_Links_id{  
  3.     function __construct(){  
  4.         if( !is_admin() || defined( 'DOING_AJAX' ) ) :  
  5.             add_filter( 'wp_link_pages_link', array$this, 'inner_page_link_format' ), 10, 2 );  
  6.             add_filter( 'redirect_canonical', array$this, 'cancel_redirect_for_paged_posts' ), 10, 2 );  
  7.         endif;  
  8.         if( is_admin() ) :  
  9.             add_filter( 'rewrite_rules_array', array$this, 'pagelink_rewrite_rules' ) );  
  10.             register_activation_hook( __FILE__array$this, 'flush_rewrite_rules' ) ) ;  
  11.             register_deactivation_hook( __FILE__array$this, 'flush_rewrite_rules' ) );  
  12.         endif;  
  13.     }  
  14.     function flush_rewrite_rules(){  
  15.         flush_rewrite_rules();  
  16.     }  
  17.     // 修改post分页链接的格式,替换  
  18.     function inner_page_link_format( $link$number ){  
  19.         if$number > 1 ){  
  20.             if( preg_match( '%<a href=".*\.html\/\d*\/"%', $link ) ){  
  21.                 $link = preg_replace( "%(\.html)\/(\d*)%""-$2$1"$link );  
  22.             }  
  23.         }  
  24.         return $link;  
  25.     }  
  26.     // 为新的链接格式增加重定向规则,移除原始分页链接的重定向规则,防止重复收录  
  27.     function pagelink_rewrite_rules( $rules ){  
  28.         foreach ($rules as $rule => $rewrite) {  
  29.             if ( $rule == '([0-9]{4})/([0-9]{1,2})/([^/]+).html(?:/([0-9]+))?/?$' //正常页面  /%year%/%monthnum%/%postname%.html  
  30.                  || $rule == '[0-9]{4}/[0-9]{1,2}/[^/]+.html/([^/]+)/?$' // 这个是查看附件的页面,没啥用,多了反而麻烦,见文章中的解释  
  31.             ) {  
  32.             unset($rules[$rule]);  
  33.             }  
  34.         }  
  35.         $new_rule['([0-9]{4})/([0-9]{1,2})/([^/]+)-([0-9]+).html$'] = 'index.php?year=$matches[1]&monthnum=$matches[2]&name=$matches[3]&page=$matches[4]';  
  36.         $new_rule['([0-9]{4})/([0-9]{1,2})/([^/]+).html$'] = 'index.php?year=$matches[1]&monthnum=$matches[2]&name=$matches[3]';   
  37.         return $new_rule + $rules//这里的顺序很重要,先$new_rule 之后才是原来的$rules,从上到下读取,否则设置无效,404页面  
  38.     }  
  39.     // 禁止WordPress将页面分页链接跳转到原来的格式  
  40.     function cancel_redirect_for_paged_posts( $redirect_url$requested_url ){  
  41.         global $wp_query;  
  42.         if( is_single() && $wp_query->get( 'page' ) > 1 ){  
  43.             return false;  
  44.         }  
  45.         return true;  
  46.     }  
  47. }  
  48. new Rewrite_Inner_Page_Links_id();  

 

以上就是主要代码,添加到主题的 functions.php 中。

代码分享链接: pan.baidu.com/s/1v9UnNKdRRtYlR71wGStJVg 提取码: 31ay 。

 

更简单的解决方式

还有一种更简单一些方法。大概思路是:在原有重写规则的基础上加入新的分页面格式的重写规则,不去改变原有的重写规则。那么,如何处置多网址指向同一页面的情况?即 /年/月/文章名字.html/2//年/月/文章名字-2.html 都指向同一页面。我们需要做的是禁止查看或抓取 /年/月/文章名字.html/2/ 这个页面即可。这个操作可以在服务器端设置,而不用理会 WordPress 系统怎样设置了重写规则。

主要代码如下:

  1. //添加分页重写规则  
  2. function add_custom_post_rewrite_rules( $rules ) {  
  3.   $custom_rules = array(  
  4.     '([0-9]{4})/([0-9]{1,2})/([^/]+)-([0-9]+).html$' => 'index.php?year=$matches[1]&monthnum=$matches[2]&name=$matches[3]&page=$matches[4]',  
  5.   );  
  6.   $rules = array_merge$custom_rules$rules ); //合并数组,注意先后顺序,自定义$custom_rules在前,原来的规则$rules在后,否则无效  
  7.   return $rules;  
  8. }  
  9. add_filter( 'post_rewrite_rules', 'add_custom_post_rewrite_rules' );  
  10.   
  11. //修改输出的分页链接格式  
  12. function custom_wp_link_pages( $args = '' ) {  
  13.   $args .= ( $args ? '&' : '' ) . 'echo=0'; // 三目运算符和echo设置,关于参数echo,下面有解释
  14.   $links = wp_link_pages( $args );  
  15.   $links = preg_replace_callback( '|([0-9]{4}/[0-9]{1,2}/)([^/]+)(\.html)(/)([0-9]+)|', 'custom_page_link', $links );  
  16.   echo $links;  
  17. }  
  18.   
  19. function custom_page_link($matches) {  
  20.   return $matches[1].$matches[2].'-'.$matches[5].$matches[3];  
  21. }  

 

本文禁止全文转载。任何形式转载请联系作者(时光在路上 www.timezls.com) Copyright © 2024. All Rights Reserved

而后,你需要在自己的主题文件中调用自定义函数 custom_wp_link_pages()

文章分页的时候,一般的主题都会在 <?php the_content(); ?> (输出文章内容)的下面有这样的语句 <?php wp_link_pages(); ?> (或者是已经添加了不同参数的类似输出语句),例如在主题模板文件 single.php 中能找到上述语句。这时需要做的就是把 wp_link_pages() 改为自定义函数 custom_wp_link_pages()

如果你想对分页输出样式进行修饰美化,可以改成类似于如下形式的代码(点击查看):

 

  1. <?php  
  2.   
  3. custom_wp_link_pages('before=<div class="page-links"><p>分页阅读:</p>&after=</div>&next_or_number=number&link_before=<span>&link_after=</span>');  
  4.   
  5. ?>  

或者:

本文禁止全文转载。任何形式转载请联系作者(时光在路上 www.timezls.com) Copyright © 2024. All Rights Reserved

  1. <?php  
  2.   
  3. custom_wp_link_pages('before=<strong>&after=</strong>&next_or_number=next&previouspagelink=上一页&nextpagelink=');   
  4. echo "&nbsp;";  
  5. custom_wp_link_pages('before=<span class="wp-pagenavi">&after=</span>&next_or_number=number');   
  6. echo "&nbsp;";  
  7. custom_wp_link_pages('before=<strong>&after=</strong>&next_or_number=next&previouspagelink=&nbsp&nextpagelink=下一页');   
  8.   
  9. ?>  

 

具体样式可根据需要自行修改。本文末尾提供了其中的参数和相关解释。

本文禁止全文转载。任何形式转载请联系作者(时光在路上 www.timezls.com) Copyright © 2024. All Rights Reserved

 

最后的步骤,禁止出现 /年/月/文章名字.html/2/ 这种格式,可以将其在服务器端设置成返回 404。以 Windows IIS 服务器举例,设置代码如下:

  1. <configuration>  
  2. <system.webServer>  
  3. <rewrite>  
  4.     <rules>  
  5.         <rule name="no such url found" stopProcessing="true">  
  6.             <match url="(.*)" ignoreCase="true" />  
  7.                 <conditions logicalGrouping="MatchAny">  
  8.                     <add input="{PATH_INFO}" pattern="^([0-9]{4}\/[0-9]{1,2}\/)([^\/]+).html\/[0-9]" />  
  9.                 </conditions>  
  10.                 <action type="CustomResponse" statusCode="404" subStatusCode="0" statusReason="File Not Found" statusDescription="The requested file was not found." />  
  11.         </rule>  
  12.     </rules>  
  13. </rewrite>  
  14. </system.webServer>  
  15. </configuration>  

 

---- 附:

wp_link_pages( string|array $args = '' ) 的解释:

基本用法:

  1. <?php  
  2. $defaults = array(  
  3.     'before' => '<p>' . __('Pages:') ,  
  4.     'after' => '</p>',  
  5.     'link_before' => '',  
  6.     'link_after' => '',  
  7.     'next_or_number' => 'number',  
  8.     'separator' => ' ',  
  9.     'nextpagelink' => __('Next page') ,  
  10.     'previouspagelink' => __('Previous page') ,  
  11.     'pagelink' => '%',  
  12.     'echo' => 1  
  13. );  
  14. wp_link_pages( $defaults ); ?>  

 

参数解释:

$args:(string|array)(可选)默认参数的数组或字符串,默认为空: ''

本文禁止全文转载。任何形式转载请联系作者(时光在路上 www.timezls.com) Copyright © 2024. All Rights Reserved

  • 'before':(string) 字符串类型。添加到每个链接前的HTML或文本,默认是 <p> Pages:.
  • 'after':(string) 字符串类型。 显示在每个链接后的HTML或文本,默认是 </p>.
  • 'link_before':(string) 字符串类型。显示在锚文本前的HTML或文本,位于 <a> 标签内。默认为空。
  • 'link_after':(string) 字符串类型。显示在锚文本后的HTML或文本。默认为空。
  • 'aria_current':(string) 字符串类型。aria-current 属性的值。可能的值为 pagesteplocationdatetimetruefalse。默认为 page
  • 'next_or_number':(string) 字符串类型。表明是否使用分页或页码,有效值有两个可供选择:numbernext。默认为 number.
  • 'separator':(string) 字符串类型。 分页链接之间的文本(如果可用),默认为空格。
  • 'nextpagelink':(string) 字符串类型。下一页链接的链接文本,默认为 Next Page 。
  • 'previouspagelink':(string) 字符串类型。上一页链接的链接文本,默认为 Previous Page
  • 'pagelink':(string) 字符串类型。格式化分页页码字符串。参数字符串中的 % 会替换成分页页码。所以 Page % 会生成 “Page 1”“Page 2”, 等等。默认为 %,仅为页码。
  • 'echo':(int|bool) 整型或布尔型。选择是要返回结果还是直接输出。可接受的写法包括 1(或true)或者0(或false),默认为 1(或true),返回NULL或返回内容。如果设置为 0,则直接输出格式化的HTML。注:不过本文需要格式化的html代码,但是,如果设置成 'echo=false' 并不能生效,所以还是 写为 'echo=0' 比较稳妥。

 

本文禁止全文转载。任何形式转载请联系作者(时光在路上 www.timezls.com) Copyright © 2024. All Rights Reserved

上述代码链接:pan.baidu.com/s/14-eKogZhOapXcbxwQ9mvrQ 提取码: gu3w 

时光在路上扫码阅读、分享
  • 版权声明:该文章由 时光在路上 发表,共 8052字。除非特别标注来源,否则为原创。详见《版权声明》部分。
  • 转载请注明:文章标题和文章链接 - 时光在路上 - 也可直接“复制本文链接” 或 使用右边二维码分享本文 →