使用 Change Permalink Helper 解决修改固定链接后的问题
本文最后更新于 210 天前,其中的信息可能已经有所发展或是发生改变。
本文章中使用的 Change Permalink Helper 为修改版本,请注意

今天根据 Yoast!SEO 进行 SEO 优化处理的时候修改了 WordPress 的固定链接。然后不出意外的:

使用 Change Permalink Helper 解决修改固定链接后的问题插图
404 Not Found

这可不是什么好消息,死链对于 SEO 的影响巨大,但是 WordPress 并不会自动重定向旧的固定链接格式到新的永久链接格式。

于是,我从 WordPress 插件中心找到了 Change Permalink Helper 这个插件,但是,这个插件有两个问题:

  • 由于多年没有更新,已经在最新版本的 WordPress 无法使用了
  • 只支持从文章名转换到其他固定链接格式 (这不符合我的使用需求,毕竟我是从朴素型要转换到文章名格式的

自己动手,丰衣足食

说干就干,开始分析插件,由于此插件使用 GPLv3+ 开源协议,可以在 WordPress 的 SVN 仓库中找到 CPH 的源代码

<?php # -*- coding: utf-8 -*-
/**
 * Plugin Name: Change Permalink Helper
 * Plugin URI:  https://wordpress.org/plugins/change-permalink-helper
 * Text Domain: change-permalink-helper
 * Domain Path: /languages
 * Description: It checks the Permalink and redirects to the new URL, if it doesn't exist. It sends the header message "moved permanently 301"
 * Version:     1.1.1
 * Author:      Frank B眉ltge
 * Author URI:  https://bueltge.de/
 * License:     GPLv3+
 */

//avoid direct calls to this file, because now WP core and framework has been used
if ( ! function_exists( 'add_action' ) ) {
	header( 'Status: 403 Forbidden' );
	header( 'HTTP/1.1 403 Forbidden' );
	exit();
}

if ( ! class_exists( 'ChangePermalinkHelper' ) ) {
	class ChangePermalinkHelper {

		/**
		 * Constructor.
		 */
		public function __construct() {

			add_action( 'plugins_loaded', array( $this, 'onLoad' ) );
		}

		/**
		 * I18n possibility, currently only for the translation service on wordpress.org/plugins/change-permalink-helper
		 */
		public function i18n() {
		
			load_plugin_textdomain( 'change-permalink-helper', false, basename( dirname( __FILE__ ) ) . '/languages' );
		}
		
		/**
		 * Run in the WP environment, only front end.
		 */
		public function onLoad() {

			if ( is_admin() ) {
				return;
			}
			add_action( 'template_redirect', array( $this, 'is404' ) );
		}

		/**
		 * Return header message.
		 *
		 * @return bool
		 */
		public function is404() {

			if ( ! is_404() ) {
				return FALSE;
			}

			global $wpdb;
			// get slug from url, preserve url-parameter
			$request_array = explode( '?', $_SERVER['REQUEST_URI'] );
			$slug = htmlspecialchars( basename( $request_array[0]) );
			$params = isset( $request_array[1]) ? $request_array[1] : null;
			
			$id   = $wpdb->get_var(
				$wpdb->prepare( "
						SELECT ID 
						FROM $wpdb->posts
						WHERE post_name = '%s'
						AND post_status = 'publish'
					", $slug )
			);

			if ( $id == null ) {
				$url = get_permalink( $id );
				if ($params) {
					$url .= '?' . $params;
				}
				header( 'HTTP/1.1 301 Moved Permanently' );
				header( 'Location: ' . $url );

				return FALSE;
			}

			return TRUE;
		}

	} // end class

	$ChangePermalinkHelper = new ChangePermalinkHelper();
}

由于 WordPress 的 API 修改(大概?),header 重定向已经在我的环境下不起作用了。

因此我们要修改为使用 WordPress 的原生重定向代码:

wp_redirect($url, 301, "Change Permlink Helper");

现在,该插件的重定向已经可以工作了。

但是,还有一个问题:我们需要让插件支持从 朴素型 重定向到其他类型的固定链接格式。

因此,我们需要修改一下 URL 解析部分的代码:

...
			// search for post_name
			$id   = $wpdb->get_var(
				$wpdb->prepare( "
						SELECT ID 
						FROM $wpdb->posts
						WHERE post_name = '%s'
						AND post_status = 'publish'
					", $slug )
			);
			// search for ID
		  if($id == null){
			$id   = $wpdb->get_var(
				$wpdb->prepare( "
						SELECT ID 
						FROM $wpdb->posts
						WHERE ID = '%d'
						AND post_status = 'publish'
					", $slug )
			);
		  }
...

现在,插件就可以支持朴素型的查找了,但是代价是会多一个 SQL 查询。如果有大佬,可以尝试合并为一个 SQL 查询。不过我的站点流量也不大,多一个查询也无所谓了(

完整成品

<?php # -*- coding: utf-8 -*-
/**
 * Plugin Name: Change Permalink Helper
 * Plugin URI:  https://wordpress.org/plugins/change-permalink-helper
 * Text Domain: change-permalink-helper
 * Domain Path: /languages
 * Description: It checks the Permalink and redirects to the new URL, if it doesn't exist. It sends the header message "moved permanently 301"
 * Version:     1.1.1
 * Author:      Frank Bültge
 * Author URI:  https://bueltge.de/
 * License:     GPLv3+
 */

//avoid direct calls to this file, because now WP core and framework has been used
if ( ! function_exists( 'add_action' ) ) {
	header( 'Status: 403 Forbidden' );
	header( 'HTTP/1.1 403 Forbidden' );
	exit();
}

if ( ! class_exists( 'ChangePermalinkHelper' ) ) {
	class ChangePermalinkHelper {

		/**
		 * Constructor.
		 */
		public function __construct() {

			add_action( 'plugins_loaded', array( $this, 'onLoad' ) );
		}

		/**
		 * I18n possibility, currently only for the translation service on wordpress.org/plugins/change-permalink-helper
		 */
		public function i18n() {
		
			load_plugin_textdomain( 'change-permalink-helper', false, basename( dirname( __FILE__ ) ) . '/languages' );
		}
		
		/**
		 * Run in the WP environment, only front end.
		 */
		public function onLoad() {

			if ( is_admin() ) {
				return;
			}
			add_action( 'template_redirect', array( $this, 'is404' ) );
		}

		/**
		 * Return header message.
		 *
		 * @return bool
		 */
		public function is404() {
		
			if ( ! is_404() ) {
				
				return FALSE;
			}
			global $wpdb, $wp, $wp_rewrite;
			// get slug from url, preserve url-parameter
			$request_array = explode( '?', $_SERVER['REQUEST_URI'] );
			$slug = htmlspecialchars( basename( $request_array[0]) );
			$params = isset( $request_array[1]) ? $request_array[1] : null;
			// search for post_name
			$id = $wpdb->get_var(
				$wpdb->prepare( "
						SELECT ID 
						FROM $wpdb->posts
						WHERE post_name = '%s'
						AND post_status = 'publish'
					", $slug )
			);
			// search for ID
		  if($id == null){
			$id = $wpdb->get_var(
				$wpdb->prepare( "
						SELECT ID 
						FROM $wpdb->posts
						WHERE ID = '%d'
						AND post_status = 'publish'
					", $slug )
			);
		  }
			if ( $id ) {	
				$url = get_permalink( $id );
				if ($params) {
					$url .= '?' . $params;
				}
				wp_redirect($url, 301, "Change Permlink Helper");
				return FALSE;
			}

			return TRUE;
		}

	} // end class

	$ChangePermalinkHelper = new ChangePermalinkHelper();
}

成品使用方法

首先安装官方的 Change Permalink Helper,然后使用 WordPress 的插件编辑器,编辑 change-permalink-helper/change_permalink_helper.php 这个文件,并使用上述的代码替换。

测试环境

时过境迁,本文中的代码不可能一直有用,下面列出本文在撰写时的测试环境

WordPress:5.8.2

PHP:PHP 8.0 with JIT enabled

MySQL:5.7.34

测试效果

点击这个链接,看看会不会自动跳转吧 🙂 https://www.ghostchu.com/archives/254

除特殊说明以外,本站原创内容采用 知识共享 署名-非商业性使用 4.0 许可。转载时请注明来源,以及原文链接
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
呼呼
派蒙
巴巴托斯
上一篇
下一篇