如何添加自定义重写规则并指向特定模板

时间:2021-06-10 作者:Run

如何添加自定义重写规则,以便捕获以下路径:

/products/imports/filters
/products/imports/elements
/products/imports/parts
并将其指向模板文件,例如:

sector.php
我的代码:

function sector_rewrite_rule() {
    add_rewrite_rule(
        \'(.?.+?)/([^/]*)/([^/]*)/?$\',
        \'index.php?pagename=$matches[1]/$matches[2]&sector=$matches[3]\',
        \'top\'
    );
}
add_action(\'init\', \'sector_rewrite_rule\', 10, 0);
但当我尝试使用上面的URL时,我得到了404。

我创建了一个名为imports 创建于products 已经:

products/
   imports/
所以我想抓住这一页后面的任何单词:

/products/imports/

3 个回复
最合适的回答,由SO网友:Serkan Algur 整理而成

您需要创建query_var 对于sector 您需要使用RegEX创建一个重写规则。我为此创建了一个插件。创建文件并添加到wp-content/plugins 文件夹并将其激活。

<?php

/*
Plugin Name: Custom Rewrite
Plugin URI: https://serkanalgur.com.tr
Description: Custom Rewrite
Version: 1
Author: Serkan Algur
Author URI: https://www.serkanalgur.com.tr
License: GPLv2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
*/

class FilterRewriteRule
{
    public function init()
    {
        $this->InitRewriteRules();
        add_filter(\'query_vars\', [$this,\'add_query_for_sector\']);
        add_filter(\'template_include\', array($this, \'filter_template\'), 99);
    }

    private function add_query_for_sector($vars)
    {
        $vars[] = \'sector\';
        return $vars;
    }

    private function InitRewriteRules()
    {
        add_rewrite_rule(
            \'products/import/([^/]*)/?$\',
            \'index.php?pagename=products/import&sector=$matches[1]\',
            \'top\'
        );

        add_rewrite_rule(
            \'products/import/page/([0-9]{1,})/([^/]*)/?$\',
            \'index.php?paged=$matches[1]&pagename=products/import&sector=$matches[2]\',
            \'top\'
        );
    }

    public function filter_template($template)
    {
        global $wp;
        if (get_query_var(\'sector\') && is_page(\'import\')) {
            $custom_template = locate_template(\'sector.php\');
            if ($custom_template) {
                return $custom_template;
            }
        }
        return $template;
    }
}

register_activation_hook(__FILE__, function () {
    $writing_ideas = new FilterRewriteRule();
    $writing_ideas->init();
    flush_rewrite_rules();
});

add_rewrite_rule 添加具有分页支持的重写规则。filter_template 找到您的sector.php 文件并将请求重定向到此文件。query_vars 添加sector 查询WordPress系统。

SO网友:Sally CJ

尝试以下步骤,这些步骤对我很有效:

使用更具体的重写规则RegEx模式(如so),确保当前URL路径的形式为products/imports/<word>:

function sector_rewrite_rule() {
    add_rewrite_rule(
        // matches products/imports/filters, but not products/imports/filters/foo
        \'^products/imports/([^/]+)/?$\',

        // ensure pagename is in the form of <parent>/<child>
        \'index.php?pagename=products/imports&sector=$matches[1]\',

        \'top\'
    );
}
sector 作为公共查询变量,通过query_vars hook: (公共查询变量是将从GET/URL和POST参数中读取的变量)

add_filter( \'query_vars\', \'sector_query_vars\' );
function sector_query_vars( $vars ) {
    $vars[] = \'sector\';

    return $vars;
}
sector.php 模板用于products/imports/<word> 端点。所以既然我们的目标是一个页面(类型为page), 那我就用page_template hook, 但是你可以用template_include hook 如果您想:

add_filter( \'page_template\', \'my_sector_page_template\' );
function my_sector_page_template( $template ) {
    if ( is_page( \'imports\' ) && get_query_var( \'sector\' ) ) {
        // this assumes the template is in the active theme directory
        // and just change the path if the template is somewhere else
        $template = locate_template( \'sector.php\' ); // use a full absolute path
    }

    return $template;
}
完成上述步骤1后,请记住刷新重写规则!只需访问永久链接设置页面,无需单击保存更改按钮。

此外,如果您需要支持分页(例如。products/imports/filters/page/2), 然后需要调整上述重写规则RegEx模式and 对此进行查询。

SO网友:Sally CJ

另一种解决方案是,如果您担心稍后会更改页面slug,那么可以使用add_rewrite_endpoint(), 但这意味着URL需要一个额外的路径,例如。/sector 如中所示example.com/products/imports/sector/filters.

因此,步骤是相同的,只是不再需要手动挂接query_vars 因为add_rewrite_endpoint() 默认情况下,将自动为您执行此操作:

注册sector 所有页面的端点:

add_action( \'init\', \'my_sector_init\' );
function my_sector_init() {
    add_rewrite_endpoint( \'sector\', EP_PAGES );
}
请记住删除add_action(\'init\', \'sector_rewrite_rule\', 10, 0); 在代码中。。正如我之前说过的,刷新重写规则!:)

加载sector.php 这些自定义端点页面上的模板:

add_filter( \'page_template\', \'my_sector_page_template\' );
function my_sector_page_template( $template ) {
    if ( get_query_var( \'sector\' ) ) {
        $template = locate_template( \'sector.php\' );
    }

    return $template;
}

使用时的其他选项add_rewrite_rule() 使用特定的页面段塞或路径,将页面ID存储在变量(或数据库选项,如果需要)中,并将上一个路径存储在post元数据中,并且每当更新页面或其父级时,特别是如果更改段塞,则可以通过编程刷新重写规则。

因此,根据我最初的回答,在步骤1中,我们将调用flush_rewrite_rules() only if applicable:

function sector_rewrite_rule() {
    $page_id = 123;

    // Ensure that the post exists.
    if ( ! get_post( $page_id ) ) {
        return;
    }

    $post_ancestors = get_post_ancestors( $page_id );
    $previous_slug  = get_post_meta( $page_id, \'_prev_path\', true );

    // Build the hierarchical path.
    $post_ancestors[] = $page_id;
    $current_slug = implode( \'/\', array_map( function ( $id ) {
            return get_post_field( \'post_name\', $id );
    }, $post_ancestors ) );

    add_rewrite_rule(
        \'^\' . preg_quote( $current_slug ) . \'/([^/]+)/?$\',
        \'index.php?page_id=\' . $page_id . \'&sector=$matches[1]\',
        \'top\'
    );

    global $pagenow; // this is defined on admin pages
    if ( \'options-permalink.php\' !== $pagenow && $current_slug !== $previous_slug ) {
        update_post_meta( $page_id, \'_prev_path\', $current_slug );
        flush_rewrite_rules();
    }
}
步骤2保持不变,但步骤3将保持不变(注意$page_id):

add_filter( \'page_template\', \'my_sector_page_template\' );
function my_sector_page_template( $template ) {
    $page_id = 123;

    if ( is_page( $page_id ) && get_query_var( \'sector\' ) ) {
        $template = locate_template( \'sector.php\' );
    }

    return $template;
}
因此,您可以尝试这些,只需替换$page_id 使用正确的ID。

相关推荐