了解add_rewrite_rule


11

我正在尝试add_rewrite_rule着从URL提取参数并将其传递给请求。看到过很多与此相关的文章,但似乎无法使其正常运行。

如果url以某个字符串开头,我想将其从url中删除,并将其作为查询参数传递。

请求网址示例:

http://domain.com/foo/my_page

这将转化为

http://domain.com/my_page?param=foo

如果不存在“ foo”,它应该作为正常请求通过。此逻辑应适用于我网站上的任何页面网址或自定义帖子类型的网址(基本上是foo / *)。如果URL有“ foo”将其剥离,然后将其传递给Wordpress,则认为这将是通过。

我已经有'param'作为允许的query_vars了。

总共,它需要为以下工作:

  • / foo / my_page(页面)
  • / foo / my_folder / my_page(子页面)
  • / foo / example_type(自定义帖子存档)
  • / foo / example_type / example_post(自定义帖子单)

是否有任何URL,包括帖子,类别,标签等,不仅是page帖子类型,还是任何页面?层次结构中的父/子页面如何?
米洛

@Milo我已经为您澄清了这一点。我仅使用页面和自定义帖子类型(存档页面和单个页面)。
路易W

Answers:


8

适用于您的示例的基本规则:

function wpd_foo_rewrite_rule() {
    add_rewrite_rule(
        '^foo/([^/]*)/?',
        'index.php?pagename=$matches[1]&param=foo',
        'top'
    );
}
add_action( 'init', 'wpd_foo_rewrite_rule' );

这将使用后面的所有内容foo/并将其设置pagename为查询的内容,然后param获取静态值foo。如果您需要不同的网址格式,则每个独特的格式都需要额外的规则。有关可在重写规则中设置的各种查询变量,请参阅WP_Query文档。添加新规则后,不要忘记刷新重写规则。这可以通过访问“永久链接设置”页面来完成。

现在访问您的示例URL:

http://domain.com/foo/my_page

将加载正确的页面,但其行为不会完全类似于访问:

http://domain.com/my_page?param=foo

因为使用内部重写时,param是在$wp_query查询对象(而不是$_GET超全局变量)中设置的。如果您需要使用在中寻找值的代码,则$_GET需要额外的步骤来设置该值:

function wpd_foo_get_param() {
    if( false !== get_query_var( 'param' ) ){
        $_GET['param'] = get_query_var( 'param' );
    }
}
add_action( 'parse_query', 'wpd_foo_get_param' );

要考虑的另一种方法是使用端点,因此/foo/应该在URL的末尾而不是作为前缀。这样做的好处是,API add_rewrite_endpoint简化了添加所需的所有规则的操作,包括启用分页。


感谢您的通过解释。似乎已关闭,可用于页面,但自定义帖子存档和单个网址给我一个404错误。
路易W

是的,就像我说的那样,您需要添加与每个模式匹配的其他规则。我不知道这些网址在您的设置中是什么样的。
米洛

我有一个名为“项目”的自定义页面类型,该页面类型具有一个存档和单个页面。你能举个例子吗,我可以做所有其他例子。
路易W

此外,它似乎不适用于子页面。
路易W

1
编辑您的问题以添加每个需要规则的URL模式的示例。我并不真的担心我的答案会被接受,有时候我可以通过给他们一些东西来欺骗人们回答他们自己的问题。
米洛

6

好的,我已经为所有三种类型的请求提供了工作示例。为了使它们工作,需要花大量的时间进行实验和弄乱。我想Milo擅长促使人们回答自己的问题。

经过无数次更改并刷新了永久链接后,我意识到找出add_rewrite_url之外的URL更加容易,一旦它们起作用,然后定义重写。例子是index.php?param=foo&post_type=example_type

另一件事很明显,但是在此处添加它可能会对其他人有所帮助。在定义页面/子页面通配符规则之前,必须定义自定义帖子类型add_rewrite_rule规则。我在那个上浪费了很多时间,并认为这是导致我不明白为什么规则不起作用的主要原因。

这是满足我所有需求的3条规则。页面/子页面规则被合并为一个规则。

// Custom Post Archive
add_rewrite_rule(
    '^foo/example_type/?$',
    'index.php?param=foo&post_type=example_type',
    'top'
    );

// Custom Post Individual
add_rewrite_rule(
    '^foo/example_type/([^/]*)/?$',
    'index.php?param=foo&example_type=$matches[1]',
    'top'
    );

// Pages, Top-Level and Sub-Pages
// This MUST be placed in the code AFTER custom post add_rewrite_rule
add_rewrite_rule(
    '^foo/(.+)/?$',    
    'index.php?param=foo&pagename=$matches[1]',
    'top'
    );

另外,我所做的是设置一个循环以添加多个自定义帖子类型规则。请记住,在定义页面/子页面通配符规则之前,必须定义自定义帖子类型add_rewrite_rule规则。

$custom_types = array('example_type', 'projects', 'people');

foreach($custom_types as $type) {

    // Custom Post Archive
    add_rewrite_rule(
        '^foo/'.$type.'/?$',
        'index.php?param=foo&post_type='.$type,
        'top'
        );

    // Custom Post Individual
    add_rewrite_rule(
        '^foo/'.$type.'/([^/]*)/?$',
        'index.php?param=foo&'.$type.'=$matches[1]',
        'top'
        );

}

当试图更好地了解Wordpress如何查询页面/帖子时,Milo传递的Rewrite Analyzer非常有用。


演出晚了,但是我能帮你找个例子吗?请注意,我完全不了解add_rewrite_rule的$ tag参数。不知道这意味着什么。我也无法理解使用pagename = $ matches [1]'的示例。嗯?我有一个类似domain.com/detail?id=2&it=3的URL。我希望页面为domain.com/detail/2-3/。你是否愿意?
黛比·库斯
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.