WordPress Rewrite Rules是控制wordpress路由的,说简单点就是控制访问链接的。
一、可使用函数
1、add_rewrite_rule() 允许我们为 WordPress 添加自定义重写规则,通常和下面的add_rewrite_tag()配合使用。
add_rewrite_rule($regex, $redirect, $after);
$regex (string) (必需) 一个匹配请求 URL 的正则表达式,可是使用一个或多个正则表达式组。默认:None
$redirect (string) (必需):真正需要获取的 URL, ($regex 匹配时).。我们可以使用 $matches[] 数组在这里插入捕获获的匹配组。默认: None
$after (string) (可选):这可以是 ‘top’ 或 ‘bottom’.。’top’ 将在 WordPress 现有的规则之前优先处理, ‘bottom’ 将在其他规则之后处理。默认: “bottom”
2、add_rewrite_tag() 允许我们添加 WordPress 可以识别的自定义查询参数。
add_rewrite_tag($tag, $regex, $query);
$tag (string) (必需) 重定向标签的名称,开始和结尾需要用 % 包括起来。默认: None
$regex (string) (必需) 指定标签的正则表达式默认: None
$query (string) (可选) 附加查询到查询属性数组默认: None
二、使用例子
1、add_rewrite_rule()
访问链接:http://example.com/leaf/95
如同访问链接:http://example.com/index.php?page_id=95
add_action('init', function ()
{
add_rewrite_rule('^leaf/([0-9]+)/?', 'index.php?page_id=$matches[1]', 'top');
});
2、add_rewrite_rule()和add_rewrite_tag()配合使用
页面:
query_vars['food'];
echo '
';
echo 'Variety : ' . $wp_query->query_vars['variety'];
// ... more ...
get_footer();
?>
add_rewrite_tag() (使用 add_rewrite_tag() 让 WordPress 可以识别自定义查询变量 「food」 和 「variety」):
add_action('init', function ()
{
add_rewrite_tag('%food%', '([^&]+)');
add_rewrite_tag('%variety%', '([^&]+)');
}, 10, 0);
add_rewrite_rule() (改变路由):
add_action('init', function ()
{
add_rewrite_rule('^nutrition/([^/]*)/([^/]*)/?', 'index.php?page_id=12&food=$matches[1]&variety=$matches[2]', 'top');
}, 10, 0);
此时访问:http://example.com/nutrition/milkshakes/strawberry/
如同访问:http://example.com/index.php?page_id=12&food=milkshake&variety=strawberry
3、add rewrite tag 单独使用示例
下面的代码将注册一个名称为 ‘film_title’ 的查询标签:
<?php
function custom_rewrite_tag() {
add_rewrite_tag('%film_title%', '([^&]+)');
}
add_action('init', 'custom_rewrite_tag', 10, 0);
?>
获取重定向后的查询的参数值(这也就是2中为什么要和add rewrite tag一起使用):
$wp_query->query_vars['film_title']
国外网站的代码:
<?php
add_action( 'init', 'rewrite_tag_example_init' );
add_action( 'template_redirect', 'rewrite_tag_example_template_redirect' );
/**
* Add rewrite rule and tag to WP
*/
function rewrite_tag_example_init(){
// rewrite tag adds the matches found in the pattern to the global $wp_query
add_rewrite_tag( '%affiliate%', '(.*)' );
}
/**
* Modify the query based on our rewrite tag
*/
function rewrite_tag_example_template_redirect(){
// get the value of our rewrite tag
$affiliate = get_query_var( 'affiliate' );
// check if our rewrite tag has value
if ( !empty( $affiliate ) ){
// track where this visitor came from
setcookie( 'affiliate', $affiliate, 0, '/' );
}
}
三、高级用法,使用hook新增、修改、删除路由
这里的话有两种类型的hook
1、这里和上面一样
function iteblog_rewrite_rule() {
add_rewrite_rule('wechat$', 'index.php?iteblog_hadoop'', 'top');
}
add_action('init', 'iteblog_rewrite_rule');
2、高级用法,很多地方看到这类用法,适合用在复杂场景,hook的是rewrite_rules_array。
新增路由:
function add_rewrite_rules($aRules){
$aNewRules = array(
'wechat$' => 'index.php?iteblog_hadoop'
);
$aRules = $aNewRules + $aRules;
return $aRules;
}
add_filter('rewrite_rules_array', 'add_rewrite_rules');
删除路由:
add_filter('rewrite_rules_array', 'kill_feed_rewrites');
function kill_feed_rewrites($rules){
foreach ($rules as $rule => $rewrite) {
if ( preg_match('/^foo.*(feed)/',$rule) ) {
unset($rules[$rule]);
}
}
return $rules;
}
修改路由可以参照删除路由改改,也可以先删除再新增。
更多hook:
<?php
add_action( 'init', 'rewrite_tag_permalink_init' );
add_action( 'pre_get_posts', 'rewrite_tag_permalink_pre_get_posts' );
// normal posts
add_filter( 'post_link', 'rewrite_tag_permalink_post_link', 10, 2 );
// custom post types
add_filter( 'post_type_link', 'rewrite_tag_permalink_post_link', 10, 2 );
/**
* Add our rewrite rule and rewrite tag
*/
function rewrite_tag_permalink_init(){
// rewrite rule looks for custom_folder
add_rewrite_rule( '^([^/]+)/(.*)/?', 'index.php?custom_folder=$matches[1]&name=$matches[2]', 'bottom' );
// rewrite tag puts custom_folder value into the query vars
add_rewrite_tag( '%custom_folder%', '(.*)' );
}
/**
* Alter permalinks to reflect the new custom_folder rewrite tag
*
* @param $permalink
* @param $post
*
* @return mixed
*/
function rewrite_tag_permalink_post_link( $permalink, $post ) {
$rewrite_tag = '%custom_folder%';
// return early if tag not found
if ( strpos( $permalink, $rewrite_tag ) === FALSE ) {
return $permalink;
}
// look for custom permalink meta data
$custom_folder = get_post_meta( $post->ID, 'custom_folder', true );
// if a custom permalink exists as meta data, use it
if ( !empty( $custom_folder ) ){
$permalink = str_replace( $rewrite_tag, $custom_folder, $permalink );
}
// fallback by completely removing our tag from the permalink
else {
$permalink = str_replace( $rewrite_tag . '/', '', $permalink );
}
return $permalink;
}
/**
* Use pre_get_posts to make the custom_folder meta data value optional
*
* @param $query
*/
function rewrite_tag_permalink_pre_get_posts( $query ){
if ( $query->is_main_query() ){
// if only the first argument is presented, use it as the post name
if ( get_query_var( 'custom_folder' ) &&
!get_query_var( 'name' ) )
{
// what we thought was the custom_folder is actually the post_name
$query->set( 'name', get_query_var( 'custom_folder' ) );
$query->is_home = false;
$query->is_singular = true;
$query->is_single = true;
}
}
}
四、特别说明
对于上面的一系列路由操作,在我们操作后,发现并不生效,有两种做法:
1、后台》设置》固定链接,(不要选择朴素类型,选个其他的),然后保存一下,就会刷新路由。
2、代码方式,其实做上面的操作是因为,操作一次就执行了这个代码:
flush_rewrite_rules();
或者下面的代码:
global $wp_rewrite;
$wp_rewrite->flush_rules();