添加自定义帖子类型重写规则时,有两个攻击要点:
改写规则
在wp-includes/rewrite.php
中生成重写规则时会发生这种情况WP_Rewrite::rewrite_rules()
。WordPress允许您过滤特定元素(例如帖子,页面和各种类型的存档)的重写规则。您看到posttype_rewrite_rules
的posttype
部分应该是您的自定义帖子类型的名称。另外,您也可以使用post_rewrite_rules
过滤器,只要您也不会删除标准发布规则。
接下来,我们需要该函数实际生成重写规则:
// add our new permastruct to the rewrite rules
add_filter( 'posttype_rewrite_rules', 'add_permastruct' );
function add_permastruct( $rules ) {
global $wp_rewrite;
// set your desired permalink structure here
$struct = '/%category%/%year%/%monthnum%/%postname%/';
// use the WP rewrite rule generating function
$rules = $wp_rewrite->generate_rewrite_rules(
$struct, // the permalink structure
EP_PERMALINK, // Endpoint mask: adds rewrite rules for single post endpoints like comments pages etc...
false, // Paged: add rewrite rules for paging eg. for archives (not needed here)
true, // Feed: add rewrite rules for feed endpoints
true, // For comments: whether the feed rules should be for post comments - on a singular page adds endpoints for comments feed
false, // Walk directories: whether to generate rules for each segment of the permastruct delimited by '/'. Always set to false otherwise custom rewrite rules will be too greedy, they appear at the top of the rules
true // Add custom endpoints
);
return $rules;
}
如果决定玩转,这里需要注意的主要是“ Walk directory”布尔值。它为永久结构的每个段生成重写规则,并且可能导致重写规则不匹配。当请求WordPress URL时,将从顶部到底部检查重写规则数组。一旦找到匹配项,它将加载遇到的所有内容,例如,如果您的永久对象有贪婪的匹配项,例如。for /%category%/%postname%/
和walk目录位于其上,将为两个/%category%/%postname%/
AND 输出/%category%/
匹配任何内容的重写规则。如果那太早发生了,那您就被搞砸了。
固定链接
该函数用于解析帖子类型的永久链接,并将永久结构(例如'/%year%/%monthnum%/%postname%/')转换为实际的URL。
下一部分是一个简单的示例,该示例理想地是在中get_permalink()
找到的函数的版本wp-includes/link-template.php
。生成自定义帖子永久链接,get_post_permalink()
这是的精简版本get_permalink()
。get_post_permalink()
被过滤,post_type_link
因此我们使用它来创建自定义的永久结构。
// parse the generated links
add_filter( 'post_type_link', 'custom_post_permalink', 10, 4 );
function custom_post_permalink( $permalink, $post, $leavename, $sample ) {
// only do our stuff if we're using pretty permalinks
// and if it's our target post type
if ( $post->post_type == 'posttype' && get_option( 'permalink_structure' ) ) {
// remember our desired permalink structure here
// we need to generate the equivalent with real data
// to match the rewrite rules set up from before
$struct = '/%category%/%year%/%monthnum%/%postname%/';
$rewritecodes = array(
'%category%',
'%year%',
'%monthnum%',
'%postname%'
);
// setup data
$terms = get_the_terms($post->ID, 'category');
$unixtime = strtotime( $post->post_date );
// this code is from get_permalink()
$category = '';
if ( strpos($permalink, '%category%') !== false ) {
$cats = get_the_category($post->ID);
if ( $cats ) {
usort($cats, '_usort_terms_by_ID'); // order by ID
$category = $cats[0]->slug;
if ( $parent = $cats[0]->parent )
$category = get_category_parents($parent, false, '/', true) . $category;
}
// show default category in permalinks, without
// having to assign it explicitly
if ( empty($category) ) {
$default_category = get_category( get_option( 'default_category' ) );
$category = is_wp_error( $default_category ) ? '' : $default_category->slug;
}
}
$replacements = array(
$category,
date( 'Y', $unixtime ),
date( 'm', $unixtime ),
$post->post_name
);
// finish off the permalink
$permalink = home_url( str_replace( $rewritecodes, $replacements, $struct ) );
$permalink = user_trailingslashit($permalink, 'single');
}
return $permalink;
}
如前所述,这是用于生成自定义重写规则集和永久链接的非常简化的情况,虽然不是特别灵活,但是足以让您入门。
作弊
我写了一个插件,可以让您为任何自定义帖子类型定义%category%
永久结构,但是就像您可以在永久链接结构中使用的那样,我的插件也支持%custom_taxonomy_name%
您拥有的任何自定义分类法的帖子custom_taxonomy_name
,例如,分类法名称在哪里。%club%
。
它将与分层/非分层分类法一样工作。
http://wordpress.org/extend/plugins/wp-permastructure/