我使用Update 3并使其正常运行。我误解了,因为我相信重写规则会将
designers/?designer=some-designer&bid=9
更改为/designers/some-designer
。但这当然是另一回事。我一直在做一些研究,但是我不太了解如何使用add_rewrite_rule()。
这篇文章与我需要的内容非常接近,但是我真的需要那么多代码吗?
我当前的链接是:http://www.norwegianfashion.no/designers/?designer = Batlak-og-Selvig&bid = 9
我想要的是这个http://www.norwegianfashion.no/designers/Batlak-og-Selvig/
我如何使用
add_rewrite_rule()
? 我需要传递设计者ID(出价)。
更新1
使用re.write规则而没有在URL中显示该怎么办?我发现这更具解释性。但这不起作用:
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)在另一个线程中建议使用。我将其放在我的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=&bid= [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
我也在这里找到了一些示例。但这也不起作用:(
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;
}
我如果有人能够帮助我解决此问题,我们将不胜感激。
#1 楼
重写规则的一些背景知识WP Rewrite系统看起来很复杂,但实际上并不难理解它的工作原理。它用于解析漂亮的URL(
/designers/
),就好像它们不是漂亮的(/index.php?pagename=designers
)。基本思想是,您有一个重写规则列表,可以与传入URL匹配的正则表达式,并将它们重写为其他URL,大多数形式为带有某些查询变量的index.php
。这些变量设置为正则表达式中与URL匹配的部分。这些规则从上到下进行评估,因此,如果两个规则可能匹配,则第一个“获胜”。这些重写规则通过调用
flush_rewrite_rules()
存储在数据库中,但是因为生成和编写这些规则是一个昂贵的操作,您不应该在每个init
上都执行。相反,您只能在更改规则时执行此操作:可能是在插件激活时(使用register_activation_hook()
),或者是通过访问“永久链接”设置页面手动进行的(因为很难在主题激活时自动执行此操作)。如果不刷新规则,则调用add_rewrite_rule()
无效。即使在刷新规则后,也可以在每个add_rewrite_rule()
上调用init
。添加重写规则的方法有很多,如果只想添加一个规则,则可以执行此操作与
add_rewrite_rule()
。因为帖子,页面,分类法等的规则会导致多个规则,所以它们是由诸如add_rewrite_tag()
,add_permastruct()
之类的高级功能创建的,但是对于这里的简单情况而言,则不需要这些。还有一些过滤器,因此您也可以使用
generate_rewrite_rules
或generate_rewrite_rules_array
挂钩添加规则。这些使您可以对完整规则进行非常详细的控制,但是如果您只想添加一个规则,那么add_rewrite_rule()
就足够了。我创建了一个小插件,可以让您分析当前的重写规则,并且(当然)我建议您在尝试更改任何内容时使用它。
从URL获取更多信息
让我们以您给出的示例为基础。您拥有设计师品牌
Batlak og Selvig
和编号ID(bid
)9
。您不需要URL中的此ID,而只需要名称。我们将名称的URL友好版本(不带空格或特殊字符)称为slug:Batlak-og-Selvig
。通常,URL应包含所有信息以标识要在页面上显示的内容。您可以使用Cookie或POST请求来存储要显示的实际设计者ID,但是如果有人共享该链接(通过邮件,Facebook,Twitter或通过电话将其大声读出),则该链接将失效。如果您不想在URL中使用数字ID,则应确保该块是唯一的:然后您首先根据该块查找ID,然后像以前一样继续操作。
因此,我们现在了解到的是,我们想为模式“
/designers/
加上后一个到下一个/
”添加一个重写规则,并将该“任何内容”保存在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;
}
如您所见,该答案与我以前的答案基本相同,但是没有规则刷新在代码中(因此您可以在主题的
functions.php
中使用它,而不是在插件中使用),并且具有更多的确定性和解释,因为自从(由于(因为))回答了第一个问题以来,我学到了很多有关重写规则的知识。 讨论室
我们在聊天室中解决了该问题的最终问题。最后,史蒂文使用了
generate_rewrite_rules
钩子,因为add_rewrite_rule()
函数似乎对他不起作用。评论
@Steven:pagename是您要显示(记录在数据库中)的WordPress页面的信息。然后,该页面可以指示它要使用WP admin区域中的designer.php模板文件。因此,您指向的是页面信息,而不是模板名称,因为同一模板可以用于多个页面:在这种情况下,WordPress不知道您要做什么。
– Jan Fabry
2010-12-16 10:35
@Steven:我认为您过于复杂地设置了挂钩。删除add_rewrite_rules()函数并直接调用add_filter()/ add_action()。如果这在主题文件中,请删除flush_rewrite_rules()并仅访问永久链接设置页面以刷新规则(或将其添加到wpse5413_init()中,并在以后删除它们)。我的插件显示了当前的重写规则。请记住,这仅会更改传入URL的处理方式,而不会更改代码在HTML中写入URL的方式。
– Jan Fabry
2010-12-16 10:52
@Steven:我认为您甚至不必点击“保存”按钮,只需打开永久链接页面也可以刷新它。同样,这只会增加WordPress接受/ designers / designer-slug / URL的功能,您需要更改自己在HTML中编写这些URL的位置。通过自己进入/ designers / Batlak-og-Selvig /进行测试(如果可行),找到所有生成这些URL的位置并将其更改为使用新结构。
– Jan Fabry
2010-12-16 11:05
啊,现在我想开始了解了。我认为重写规则将改变URL在浏览器URL字段中的显示方式。但是,这就意味着我必须实际输出URL www.mysite.com/batlat-og-selvig/9,然后将其“翻译”为/?designer = Batlak-og-Selvig&bid = 9
–史蒂文
2010-12-16 11:23
@Steven:是的,的确如此:重写规则处理传入的链接,并且(仅在少数选定的情况下)不会影响代码中生成的链接。
– Jan Fabry
2010-12-16 11:32
评论
这看起来与您在此处提出的第一个问题非常相似,对此我给出了答案。从那以后情况发生了变化,所以我的答案不再有效了吗?如果您不想在URL中使用设计者ID,则需要自己将“子代码”转换为ID,WordPress无法为您完成此操作。设计师仍然是外部对象吗?@Jan Fabry是的,我发贴后发现(我忘记了)。现在我也更好地了解了您的建议。在这里查看我的更新代码。我的设计师仍然是自定义数据库中的条目。是否可以使用POST指示或GET传递出价?
如果我复制链接并将其发送给其他人,则无法使用POST请求。使条块唯一并从那里查找数据是否有问题?
@Jan Fabry:ug是什么意思? `使用出价而不是设计者,检索设计者数据要容易得多