我正在为自己的快速开发开发开发一个插件,创建一个自定义帖子类型。此帖子类型的“列表”显示在插件创建和管理的特定页面上。此页面可以放置在站点页面层次结构中的任何位置,因此如果站点管理员更改列表页面位置,则需要更新单个帖子的slug。
在init
, 为此,我将以下重写规则分配给自定义帖子类型(为简洁起见,对代码进行了修剪):
$post_type_slug = "/" . get_page_uri( $page_id );
register_post_type( \'post_type_name\',
...
\'rewrite\' => array( \'slug\' => $post_type_slug, \'with_front\' => true),
...
)
);
这对于最初设置一切似乎都非常有效。当用户保存“列表”页面时,我运行以下代码来更新重写规则:
add_action( \'save_post\', array(__CLASS__, \'flush_permalinks\'), 2000 );
function flush_permalinks( $post_id ) {
if($post_id == get_option( $custom_page_id )){
flush_rewrite_rules(false);
}
}
然而,当用户更改页面位置时,新更新的永久链接返回404(即使列表页面正确显示链接)。但是,如果我再次保存该页面,它将非常有效!我已尝试更改
save_post
行动(从1年到2000年),但这似乎没有改变。我还尝试了硬刷新和软刷新重写规则,但这也不会改变两个保存(第一个保存不会更改重写规则,但第二个会更改)的行为。
关于我可能做错了什么有什么建议吗?
最合适的回答,由SO网友:Michael Ecklund 整理而成
我知道这个问题已经得到了回答,但我觉得好像还没有完全清楚实际的解决方案是什么。
下面是我的回答,补充一些澄清。
他是对的。。。无法刷新重写规则save_post
, 因为动作挂钩是在init
动作挂钩已启动。
正如您所知,Post类型和分类是在init
钩
TLDR; 你不能flush_rewrite_rules();
在…上save_post
行动挂钩。
有一个解决方法。。。
您需要将选项值设置为1开save_post
行动挂钩。然后选中值为1的选项并刷新重写规则init
行动挂钩。
Example:
function mbe_late_init_example() {
if ( ! $option = get_option( \'my-plugin-flush-rewrite-rules\' ) ) {
return false;
}
if ( $option == 1 ) {
flush_rewrite_rules();
update_option( \'my-plugin-flush-rewrite-rules\', 0 );
}
return true;
}
add_action( \'init\', \'mbe_late_init_example\', 999999 );
function mbe_save_post_example( Int $post_id = null, \\WP_Post $post_object = null ) {
if ( ! $post_id || ! $post_object ) {
return false;
}
# Specific Post Type
if ( $post_object->post_type != \'my-plugin-settings\' ) {
return false;
}
# Specific Post Object (OPTIONAL)
if ( $post_object->post_name != \'general-settings\' ) {
return false;
}
update_option( \'my-plugin-flush-rewrite-rules\', 1 );
return true;
}
add_action( \'save_post\', \'mbe_save_post_example\', 10, 2 );
SO网友:Eric K
我能够解决这个问题。“save\\u post”操作似乎发生在init
正在注册自定义帖子类型。因此,在请求之前不会更新post类型的重写段塞flush_rewrite_rules
, 基本上没有更新。这也解释了为什么第二次保存帖子时它会起作用,因为帖子类型有机会更新其重写规则。
因此,我通过更改代码来解决这个问题:
add_action( \'save_post\', array(__CLASS__, \'flush_permalinks\'));
function flush_permalinks( $post_id ) {
if($post_id == get_option( $custom_page_id )){
update_option( \'unique_page_updated_key\', \'true\');
}
}
然后,我在
register_post_type
代码:
if((bool)get_option( \'unique_page_updated_key\' )){
flush_rewrite_rules();
update_option( \'unique_page_updated_key\', \'false\');
}
这可以防止在每个
init
.