问题描述
解
我已经和 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/
- 如何使用
add_rewrite_rule()
? - 我需要通过设计师 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_rules
或 generate_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 版本的名称 (无空格或特殊字符)slug:Batlak-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 辅助翻译的英文资料结果。如果您对结果不满意,可以加入我们改善翻译效果:薇晓朵技术论坛。