> WordPress中文手册 > wordpress进阶教程(二十):认识重写规则之重写标签

本来这篇教程应该提前的,但是由于在教程十七写了个自定义注册页面的例子,那干脆把自定义登陆、自定义找回密码的实例都写出来,以便灵活掌握WordPress重写规则的运用。

但是我们发现,前面的例子都是翻译一个地址,而没有输出地址,比如我们前面的教程讲到了自定义文章类型,在wordpress创建了自定义文章类型后(比如一个book类型的文章),那么这类文章的url地址将会是:“dba.cn/book/文章名”      而在wordpress后台固定连接中也没有对于自定义文章类型的固定连接设置。看了前面的教程,我们可以将 dba.cn/book/123.HTML这类地址正确翻译到ID为123的book类型文章,但是我们在模板中使用the_permalink()函数输出的链接类型还是“dba.cn/book/文章名” 这种类型。这也就是我说的,只有翻译、没有输出。

研究过wordpress固定链接的人可能经常看到函数add_rewrite_tag(),这个函数 就是我们这篇教程要说的重点:重写标签。

在本站进阶教程二:wordpress进阶教程(二):注册一个自定义的文章类型中,注册了一个自定义文章类型-book:请参考前面的教程

wordpress进阶教程(二十):认识重写规则之重写标签

假设我们上图中的文章《测试文章》ID为123,那么我们要通过 dba.cn/book/123.html的链接格式来访问这篇文章怎么呢?

如果熟悉了前面的教程,那么很简单:

add_action('generate_rewrite_rules', 'ashu_rewrite_rules' );    function ashu_rewrite_rules( $wp_rewrite ){        $new_rules = array(            'book/([0-9]+)?.html$' => 'index.php?post_type=book&p=$matches[1]',            'top'        );        $wp_rewrite->rules = $new_rules + $wp_rewrite->rules;    }   add_filter('post_type_link', 'ashu_book_link', 1, 3); //过滤器post_type_link即输出链接的时候用    function ashu_book_link( $link, $post = 0 ){        if ( $post->post_type == 'book' ){ //判断如果是book类型的文章            return 'Http://www.dba.cn/book/'.$post->ID .'html'; //返回一个正确的链接        } else {            return $link;        }    }   add_action('init', 'ashu_book_rewrite');    function ashu_book_rewrite() {      global $wp_rewrite;      $queryarg = 'post_type=book&p=';      $wp_rewrite->add_rewrite_tag('%book_id%', '([^/]+)', $queryarg);      //这里的%book_id%就是重写标签,第二个参数为匹配这个标签的正则表达式,第三个参数这个标签匹配的翻译规则      $wp_rewrite->add_permastruct('book', '/book/%book_id%.html', false);       //add_permastruct是往数据库中保存一个固定链接格式,第一个参数为名称    }       add_filter('post_type_link', 'ashu_book_permalink', 1, 3);    function ashu_book_permalink($post_link, $post = 0) {      global $wp_rewrite;      if ( $post->post_type == 'book' ){ //判断文章类型          if ( is_wp_error( $post ) )            return $post;          $newlink = $wp_rewrite->get_extra_permastruct('book'); //获取前面保存的名为book的固定链接格式          $newlink = str_replace("%post_id%", $post->ID, $newlink); //将格式里面的重写标签替换为文章ID          $newlink = home_url(user_trailingslashit($newlink)); //完整的链接地址          return $newlink; //返回        } else {            return $post_link;        }    }   'book/([0-9]+)?.html$' => 'index.php?post_type=book&p=$matches[1]',  

上面的重写规则中正则表达式:[0-9]即匹配数字,在主题的functions.php中添加上面的代码即可,然后访问地址 dba.cn/book/123.html就会发现,居然到了正确的页面(如果错误、请更新重写规则,你懂的,没懂就参考前面的教程)

然而我们从通过模板输出的链接,或者通过后台点击查看文章,发现链接还是:“dba.cn/book/测试文章”,在主题中添加下面的代码:

add_action('generate_rewrite_rules', 'ashu_rewrite_rules' );    function ashu_rewrite_rules( $wp_rewrite ){        $new_rules = array(            'book/([0-9]+)?.html$' => 'index.php?post_type=book&p=$matches[1]',            'top'        );        $wp_rewrite->rules = $new_rules + $wp_rewrite->rules;    }   add_filter('post_type_link', 'ashu_book_link', 1, 3); //过滤器post_type_link即输出链接的时候用    function ashu_book_link( $link, $post = 0 ){        if ( $post->post_type == 'book' ){ //判断如果是book类型的文章            return '/book/'.$post->ID .'html'; //返回一个正确的链接        } else {            return $link;        }    }   add_action('init', 'ashu_book_rewrite');    function ashu_book_rewrite() {      global $wp_rewrite;      $queryarg = 'post_type=book&p=';      $wp_rewrite->add_rewrite_tag('%book_id%', '([^/]+)', $queryarg);      //这里的%book_id%就是重写标签,第二个参数为匹配这个标签的正则表达式,第三个参数这个标签匹配的翻译规则      $wp_rewrite->add_permastruct('book', '/book/%book_id%.html', false);       //add_permastruct是往数据库中保存一个固定链接格式,第一个参数为名称    }       add_filter('post_type_link', 'ashu_book_permalink', 1, 3);    function ashu_book_permalink($post_link, $post = 0) {      global $wp_rewrite;      if ( $post->post_type == 'book' ){ //判断文章类型          if ( is_wp_error( $post ) )            return $post;          $newlink = $wp_rewrite->get_extra_permastruct('book'); //获取前面保存的名为book的固定链接格式          $newlink = str_replace("%post_id%", $post->ID, $newlink); //将格式里面的重写标签替换为文章ID          $newlink = home_url(user_trailingslashit($newlink)); //完整的链接地址          return $newlink; //返回        } else {            return $post_link;        }    }   'book/([0-9]+)?.html$' => 'index.php?post_type=book&p=$matches[1]',  

即可输出正确的链接,然而教程到了这里,还没进入正题--重写标签。上面两个代码知识为了熟悉一下重写规则的使用。

重写标签在wordpress后台-设置-固定连接里面用到的 %post_id%  %post_name%之类的就是重写标签了,我们前面也说过,wordpress后台设置的“固定链接格式”是会保存到数据库中的_options表中,重写标签的主要作用也就是用来建立一个“固定链接格式”

上面添加的段代码,完全可以用下面的一段代码来代替:

add_action('generate_rewrite_rules', 'ashu_rewrite_rules' );    function ashu_rewrite_rules( $wp_rewrite ){        $new_rules = array(            'book/([0-9]+)?.html$' => 'index.php?post_type=book&p=$matches[1]',            'top'        );        $wp_rewrite->rules = $new_rules + $wp_rewrite->rules;    }   add_filter('post_type_link', 'ashu_book_link', 1, 3); //过滤器post_type_link即输出链接的时候用    function ashu_book_link( $link, $post = 0 ){        if ( $post->post_type == 'book' ){ //判断如果是book类型的文章            return '/book/'.$post->ID .'html'; //返回一个正确的链接        } else {            return $link;        }    }   add_action('init', 'ashu_book_rewrite');    function ashu_book_rewrite() {      global $wp_rewrite;      $queryarg = 'post_type=book&p=';      $wp_rewrite->add_rewrite_tag('%book_id%', '([^/]+)', $queryarg);      //这里的%book_id%就是重写标签,第二个参数为匹配这个标签的正则表达式,第三个参数这个标签匹配的翻译规则      $wp_rewrite->add_permastruct('book', '/book/%book_id%.html', false);       //add_permastruct是往数据库中保存一个固定链接格式,第一个参数为名称    }       add_filter('post_type_link', 'ashu_book_permalink', 1, 3);    function ashu_book_permalink($post_link, $post = 0) {      global $wp_rewrite;      if ( $post->post_type == 'book' ){ //判断文章类型          if ( is_wp_error( $post ) )            return $post;          $newlink = $wp_rewrite->get_extra_permastruct('book'); //获取前面保存的名为book的固定链接格式          $newlink = str_replace("%post_id%", $post->ID, $newlink); //将格式里面的重写标签替换为文章ID          $newlink = home_url(user_trailingslashit($newlink)); //完整的链接地址          return $newlink; //返回        } else {            return $post_link;        }    }   'book/([0-9]+)?.html$' => 'index.php?post_type=book&p=$matches[1]',  

上面的代码中,输出连接就不用解释了。翻译:当访客访问地址“www.dba.cn/book/123.html”,这个地址刚好匹配了名为“book”的固定连接格式,而这个格式里面的标签“%book_id%”是要翻译成“post_type=book&p=”的,所以翻译为“www.dba.cn/?post_type=book&p=123”这样就能正确翻译了。。。所以上面的add_rewrite_tag和add_permastruct两个函数组合的效果和使用函数添加重写的规则

add_action('generate_rewrite_rules', 'ashu_rewrite_rules' );    function ashu_rewrite_rules( $wp_rewrite ){        $new_rules = array(            'book/([0-9]+)?.html$' => 'index.php?post_type=book&p=$matches[1]',            'top'        );        $wp_rewrite->rules = $new_rules + $wp_rewrite->rules;    }   add_filter('post_type_link', 'ashu_book_link', 1, 3); //过滤器post_type_link即输出链接的时候用    function ashu_book_link( $link, $post = 0 ){        if ( $post->post_type == 'book' ){ //判断如果是book类型的文章            return '/book/'.$post->ID .'html'; //返回一个正确的链接        } else {            return $link;        }    }   add_action('init', 'ashu_book_rewrite');    function ashu_book_rewrite() {      global $wp_rewrite;      $queryarg = 'post_type=book&p=';      $wp_rewrite->add_rewrite_tag('%book_id%', '([^/]+)', $queryarg);      //这里的%book_id%就是重写标签,第二个参数为匹配这个标签的正则表达式,第三个参数这个标签匹配的翻译规则      $wp_rewrite->add_permastruct('book', '/book/%book_id%.html', false);       //add_permastruct是往数据库中保存一个固定链接格式,第一个参数为名称    }       add_filter('post_type_link', 'ashu_book_permalink', 1, 3);    function ashu_book_permalink($post_link, $post = 0) {      global $wp_rewrite;      if ( $post->post_type == 'book' ){ //判断文章类型          if ( is_wp_error( $post ) )            return $post;          $newlink = $wp_rewrite->get_extra_permastruct('book'); //获取前面保存的名为book的固定链接格式          $newlink = str_replace("%post_id%", $post->ID, $newlink); //将格式里面的重写标签替换为文章ID          $newlink = home_url(user_trailingslashit($newlink)); //完整的链接地址          return $newlink; //返回        } else {            return $post_link;        }    }   'book/([0-9]+)?.html$' => 'index.php?post_type=book&p=$matches[1]',  

是一样的。