添加自定义post类型重写规则时,有两个攻击点需要解决:
重写规则在中生成重写规则时会发生这种情况wp-includes/rewrite.php
在里面WP_Rewrite::rewrite_rules()
. WordPress允许您过滤特定元素(如帖子、页面和各种类型的存档)的重写规则。你看到的地方posttype_rewrite_rules
这个posttype
part应该是自定义帖子类型的名称。或者,您可以使用post_rewrite_rules
过滤,只要不删除标准post规则即可。
接下来,我们需要函数来实际生成重写规则:
// 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;
}
如果你决定在这里玩游戏,最需要注意的是“漫游目录”布尔值。它为permastruct的每个段生成重写规则,并可能导致重写规则不匹配。当请求WordPress URL时,从上到下检查重写规则数组。一旦找到匹配项,它将加载它遇到的任何内容,例如,如果你的permastruct有一个贪婪的匹配项,例如
/%category%/%postname%/
和walk目录,它将为两者输出重写规则
/%category%/%postname%/
和
/%category%/
这将匹配任何东西。如果发生得太早,你就完蛋了
Permalinks是解析post类型Permalinks并将permastruct(例如“/%year%/%monthnum%/%postname%/”)转换为实际URL的函数。
下一部分是理想情况下的get_permalink()
在中找到函数wp-includes/link-template.php
. 自定义post permalinks由生成get_post_permalink()
这是一个非常淡化的版本get_permalink()
. get_post_permalink()
筛选依据post_type_link
所以我们用它来定制permastructure。
// 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;
}
如前所述,这是一个非常简单的生成自定义重写规则集和永久链接的案例,并不是特别灵活,但应该足以让您开始。
作弊我写了一个插件,可以让你为任何自定义帖子类型定义permastruct,但你可以使用%category%
在我的插件支持的帖子的permalink结构中%custom_taxonomy_name%
对于任何自定义分类法custom_taxonomy_name
是分类法的名称,例如。%club%
.
它将像您所期望的那样适用于层次/非层次分类法。
http://wordpress.org/extend/plugins/wp-permastructure/