问题描述


我已经和 Update 3 一起工作了。我所误解的是,我相信重写规则会将 designers/?designer=some-designer&bid=9 改为/designers/some-designer 。但这当然是相反的。


我一直在做一些研究,但我不太了解如何使用 add_rewrite_rule()

 This post 非常接近我需要的,但是我真的需要很多代码吗?

我当前的链接是这样的:http://www.norwegianfashion.no/designers/?designer=Batlak-og-Selvig&bid=9 我想要的是这个 http://www.norwegianfashion.no/designers/Batlak-og-Selvig/

  1. 如何使用 add_rewrite_rule()
  2. 我需要通过设计师 ID(bid) 。使用 re.write 规则时,如何在 URL 中显示该怎么做?

更新 1

 I found this 这是一个更多的解释。但它不工作:

function add_rewrite_rules( $wp_rewrite )
{
    $new_rules = array(
        '('.$template_page_name.')/designers/(.*?)/?([0-9]{1,})/?$' => 'designers.php?designer='.
        $wp_rewrite->preg_index(1).'&bid='.
        $wp_rewrite->preg_index(2)
    );
       // Always add your rules to the top, to make sure your rules have priority
    $wp_rewrite->rules = $new_rules + $wp_rewrite->rules;
}
add_action('generate_rewrite_rules', 'add_rewrite_rules');

function query_vars($public_query_vars) {

    $public_query_vars[] = "designer";
    $public_query_vars[] = "bid";
    return $public_query_vars;
}
add_filter('query_vars', 'query_vars')

更新 2

这是我试过的另一个解决方案,Jan Fabry suggesten 在另一个线程中。我把它放在我的 functions.php 中,但没有效果。

add_action('generate_rewrite_rules', 'add_rewrite_rules');
add_filter('query_vars', 'query_vars');

/* Custom re-write rules for desigenrs
------------------------------------------------------------------------------*/
function add_rewrite_rules( $wp_rewrite )
{
    add_rewrite_rule('^designers/([^/]*)/([^/]*)$ /designers/?designer=$1&bid=$2 [L]', 'top');
    flush_rewrite_rules(false);
}


function query_vars($public_query_vars) {

    $public_query_vars[] = "designer";
    $public_query_vars[] = "bid";
    return $public_query_vars;
}

更新 3 I found a few examples here 以及。但这不是工作:(

add_filter('rewrite_rules_array','wp_insertMyRewriteRules');
add_filter('query_vars','wp_insertMyRewriteQueryVars');
add_filter('init','flushRules');

// Remember to flush_rules() when adding rules
function flushRules(){
    global $wp_rewrite;
    $wp_rewrite->flush_rules();
}

// Adding a new rule
function wp_insertMyRewriteRules($rules)
{
    $newrules = array();
    $newrules['(designers)/(d*)$'] = 'index.php?pagename=designers&designer=$matches[1]';
    return $newrules + $rules;
}

// Adding the bid var so that WP recognizes it
function wp_insertMyRewriteQueryVars($vars)
{
    array_push($vars, 'designer');
    return $vars;
}

更新 4 我也尝试过这个解决方案,但还没有成功。

add_filter('search_rewrite_rules', 'designers_createRewriteRules');

function designers_createRewriteRules($rewrite) {
global $wp_rewrite;

// add rewrite tokens
$designer_token = '%designers%';
$wp_rewrite->add_rewrite_tag($designer_token, '(.+)', 'designers=');

$bid_token = '%bid%';
$wp_rewrite->add_rewrite_tag($bid_token, '(.+)', 'bid=');

$keywords_structure = $wp_rewrite->root . "designers/$designer_token/$bid_token";
$keywords_rewrite = $wp_rewrite->generate_rewrite_rules($keywords_structure);

return ( $rewrite + $keywords_rewrite );

}

更新 5 似乎没有添加我的重写规则。执行以下新规则:print_r($wp_rewrite),不包括我的新的重写规则。

更新 6 我测试了 Jan 的解决方案。但是 URL 不会改变:(

/* Initiation script for NF template
------------------------------------------------------------------------------*/
add_action('after_setup_theme','norwegianfashion_setup');

if ( ! function_exists( 'norwegianfashion_setup' ) ):

  function norwegianfashion_setup() {
    /* Here I do a lot of stuff */

    // SEO friendly URL for desigenrs
    add_action( 'init', 'wpa5413_init' );
    add_filter( 'query_vars', 'wpa5413_query_vars' );
  }

endif;


/* Custom re-write rules for desigenrs
------------------------------------------------------------------------------*/
function wpa5413_init()
{
    // Remember to flush the rules once manually after you added this code!
    add_rewrite_rule(
        'designers/([^/]+)/?',
        'index.php?pagename=designers&designer=$matches[1]',
        'top' );
}

function wpa5413_query_vars( $query_vars )
{
    $query_vars[] = 'designer';
    return $query_vars;
}

如果有人能够帮助我解决这个问题,我真的很感激。

最佳解决方案

一些重写规则的背景

WP Rewrite 系统看起来很复杂,但实际上并不难理解它如何工作。它用于解析漂亮的 URL(/designers/),就像它们是 non-pretty(/index.php?pagename=designers) 一样。基本思想是,您有一个重写规则列表,可以匹配传入 URL 的正则表达式,并将其重写为其他 URL,主要以 index.php 和一些查询变量的形式。这些变量被设置为与 URL 匹配的正则表达式的部分。规则从顶部到底部进行评估,因此如果两个规则可能匹配,则第一个”wins” 。

这些重写规则通过调用 flush_rewrite_rules()存储在数据库中,但由于生成和写入这些规则是一项昂贵的操作,因此您不应该在每个 init 上执行。相反,您只能在更改规则时执行此操作:可能在插件激活 (使用 register_activation_hook()) 或手动访问 「固定链接设置」 页面 (because it’s hard to do this automatically on theme activation) 时。如果不刷新规则,调用 add_rewrite_rule()没有任何效果。即使在刷新规则后,也可以在每个 init 上调用 add_rewrite_rule()

有很多方法可以添加重写规则,如果只想添加一条规则,可以使用 add_rewrite_rule()来实现。因为帖子,页面,分类法的规则导致了多个规则,所以它们是用 add_rewrite_tag()add_permastruct()等高级函数创建的,但是我们在这里的简单例子不需要这些规则。

还有一些过滤器,因此您还可以使用 generate_rewrite_rulesgenerate_rewrite_rules_array 钩子添加规则。这些给你非常详细的控制完整的规则,但是再次,如果你只想添加一个规则,add_rewrite_rule()就够了。

我创建了 a little plugin that allows you to analyze the current rewrite rules,当然,我建议您在尝试更改任何内容时使用它。

从 URL 获取您的额外信息

我们以您给出的例子为基础。您有设计师品牌 Batlak og Selvig,数量为 (bid)9 。您不希望该 URL 中的此 ID,而只需要该名称。我们称之为 URL-friendly 版本的名称 (无空格或特殊字符)slugBatlak-og-Selvig

一般来说,网址应包含所有信息来标识您要在页面上显示的内容。您可以使用 Cookie 或 POST 请求来存储要显示的实际设计师 ID,但如果有人共享链接,则通过邮件,Facebook,Twitter 发送或只是通过电话大声朗读,这将分解。如果您不想在 URL 中使用数字标识符,则应确保该插件是唯一的:然后首先根据该插件进行 ID 的查找,然后像以前一样继续。

所以我们现在学到的是,我们要为 「/designers/之后的任何直到下一个/」 的模式添加重写规则,并将”anything” 保存在 designer_slug 查询变量中。在你的情况下,我相信你也想使用这个页面的 designers 作为一般的页面内容,所以我们也会告诉 WordPress 。

add_action( 'init', 'wpa5413_init' );
function wpa5413_init()
{
    // Remember to flush the rules once manually after you added this code!
    add_rewrite_rule(
        // The regex to match the incoming URL
        'designers/([^/]+)/?',
        // The resulting internal URL: `index.php` because we still use WordPress
        // `pagename` because we use this WordPress page
        // `designer_slug` because we assign the first captured regex part to this variable
        'index.php?pagename=designers&designer_slug=$matches[1]',
        // This is a rather specific URL, so we add it to the top of the list
        // Otherwise, the "catch-all" rules at the bottom (for pages and attachments) will "win"
        'top' );
}

唯一要做的就是告诉 WordPress 还要将 designer_slug 保存在查询变量中,以便以后访问它。 WordPress 使用允许的查询变量的白名单,以防止人们通过 URL 修改帖子查询的每个参数。这个列表上的所有内容都被忽略。只需钩入 query_vars 钩子并添加额外的变量:

add_filter( 'query_vars', 'wpa5413_query_vars' );
function wpa5413_query_vars( $query_vars )
{
    $query_vars[] = 'designer_slug';
    return $query_vars;
}

正如你所看到的,这个答案基本上与 my previous answer 相同,但没有规则在代码中刷新 (所以你可以在主题的 functions.php 而不是插件中使用它),并且有一点更确定和解释,因为我学到了很多关于重写规则,因为 (并因为) 回答你的第一个问题。

聊天室讨论

我们清理了这个问题 in the chat room 的最终问题。最后,Steven 使用了 generate_rewrite_rules 钩子,因为 add_rewrite_rule()功能似乎不适合他。

参考文献

注:本文内容整合自 Google/Baidu/Bing 辅助翻译的英文资料结果。如果您对结果不满意,可以加入我们改善翻译效果:薇晓朵技术论坛。