使用分类法的另一种方法是使用两种不同的岗位类型——孵化器和孵化器。我们可以通过在孩子的帖子元数据中保存家长的帖子ID,将孵化帖子与其家长孵化器关联起来。
步骤1-注册帖子类型
有关详细信息,请参阅代码注释。
// add parent and child post types
// set desired slugs using placeholder
add_action( \'init\', \'wpd_post_types\' );
function wpd_post_types() {
// add the parent slug placeholder rewrite tag
add_rewrite_tag( \'%wpd_parent_slug%\', \'([^&]+)\' );
// arguments for Incubators (parent)
// slug and archive are both just \'incubators\'
// feed and page rewrites disabled
$parent_args = array(
\'public\' => true,
\'label\' => \'Incubators\',
\'rewrite\' => array(
\'slug\' => \'incubators\',
\'with_front\' => false,
\'feeds\' => false,
\'pages\' => false
),
\'has_archive\' => \'incubators\'
);
register_post_type( \'incubators\', $parent_args );
// arguments for Incubated (child)
// slug contains parent slug placeholder
// no archive for Incubated, the parent posts serve as their archive
$child_args = array(
\'public\' => true,
\'label\' => \'Incubated Startups\',
\'rewrite\' => array(
\'slug\' => \'incubators/%wpd_parent_slug%\',
\'with_front\' => false,
\'feeds\' => false,
\'pages\' => false
),
\'has_archive\' => false
);
register_post_type( \'incubated\', $child_args );
}
第二步-哎呀,有些东西坏了为这些帖子类型生成的重写规则有问题-父附件规则步在子帖子规则上。有两种方法可以解决这个问题——一种方法是挂接查询解析,检查它是否匹配那些附件请求,如果这是它的目的,则将它们重置为子post请求。另一个更简单的方法是摆脱这些规则,因为也许你不需要它们。如果需要,可以插入备用规则以支持附件。
// filter the array of all rewrite rules
// remove any that contain the parent post type and attachment
add_filter( \'rewrite_rules_array\', \'wpd_remove_attachment_rewrites\' );
function wpd_remove_attachment_rewrites( $rules ){
foreach ( $rules as $rule => $rewrite ) {
if( strpos( $rewrite, \'attachment\' ) !== false
&& strpos( $rule, \'incubators\' ) !== false ) {
unset( $rules[$rule] );
}
}
return $rules;
}
第3步-过滤孵化(子)帖子的permalink输出每当API输出permalink时,子帖子需要在URL中包含其父帖子的slug,让我们来实现这一点。
// filter post_type_link for child posts
// swap real parent slug for parent slug placeholder
add_filter( \'post_type_link\', \'wpd_cpt_permalinks\', 1, 2 );
function wpd_cpt_permalinks( $post_link, $post ){
// if this is an Incubated post
if ( is_object( $post ) && $post->post_type == \'incubated\' ){
// get the parent ID saved in post meta
// and swap that post\'s slug for the placeholder tag
$parent_id = get_post_meta( $post->ID, \'_wpd_parent_id\', true );
$parent_slug = \'no-parent\';
if( \'\' != $parent_id ){
$parent_slug = basename( get_permalink( $parent_id ) );
}
$post_link = str_replace( \'%wpd_parent_slug%\' , $parent_slug , $post_link );
}
return $post_link;
}
警告此实现中没有任何内容在子post permalinks中强制执行有效的父slug值。实际上,我认为这不是一个问题。如果您认为是这样,那么可以通过挂接到查询解析/查询的某个阶段,并检查父slug是否有效以及是否是所查询帖子的父slug,然后强制执行404。
步骤4-在孵化(子)帖子中添加一个元框,用于选择父项
生成一个简单的选择列表,其中包含所有孵化器(父)帖子的名称和ID。将所选值保存在键下的孵化(子)post meta中
_wpd_parent_id
.
// Add the meta box
add_action( \'add_meta_boxes\', \'wpd_parent_metabox\' );
function wpd_parent_metabox(){
add_meta_box(
\'wpd_parent_metabox\',
\'Parent Incubator\',
\'wpd_parent_metabox_callback\',
\'incubated\',
\'side\'
);
}
// render the meta box
function wpd_parent_metabox_callback( $post, $metabox ) {
// load the parent ID if it already exists
$parent_id = get_post_meta( $post->ID, \'_wpd_parent_id\', true );
// add a nonce
echo \'<input type="hidden" name="wpd_parent_metabox_nonce" value="\' . wp_create_nonce( \'wpd_parent_metabox_nonce\' ) . \'" />\';
// get all the Incabator (parent) posts and make a list of IDs / names
// check previously saved value against each item\'s value
echo \'<select name="wpd_parent_id">\';
echo \'<option value="" \' . selected( $parent_id, \'\' ) . \'>None</option>\';
$parents = new WP_Query(
array(
\'post_type\' => \'incubators\',
\'posts_per_page\' => -1
)
);
if( $parents->have_posts() ){
foreach( $parents->posts as $parent ){
echo \'<option value="\' . $parent->ID . \'" \' . selected( $parent_id, $parent->ID ) . \'>\' . $parent->post_title . \'</option>\';
}
}
echo \'</select>\';
}
// save meta box data
add_action( \'save_post\', \'wpd_parent_metabox_save\', 1, 2 );
function wpd_parent_metabox_save( $post_id, $post ) {
// don\'t save if autosave, user doesn\'t have permission, or a revision
if ( defined( \'DOING_AUTOSAVE\' ) && DOING_AUTOSAVE ) return;
if ( !current_user_can( \'edit_post\', $post_id )) return;
if( \'revision\' == $post->post_type ) return;
// check nonce
if( isset( $_POST[\'wpd_parent_metabox_nonce\'] )
&& wp_verify_nonce( $_POST[\'wpd_parent_metabox_nonce\'], \'wpd_parent_metabox_nonce\' ) ){
// save value or remove if none was selected
if( isset( $_POST[\'wpd_parent_id\'] )
&& \'\' != $_POST[\'wpd_parent_id\'] ){
update_post_meta( $post_id, \'_wpd_parent_id\', $_POST[\'wpd_parent_id\'] );
} else {
delete_post_meta( $post_id, \'_wpd_parent_id\' );
}
}
}
好的,到目前为止,我们有我们的帖子类型和一种将孩子与父母联系起来的方法。我们可以创建每种类型的帖子和链接。
步骤5-过滤器the_content
并插入指向父级/子级的链接
这将显示如何查询子帖子或父帖子。家长将显示孩子的列表,孩子将显示指向家长的链接。
// add links to post content
add_filter( \'the_content\', \'wpd_child_post_links_in_parent_content\' );
function wpd_child_post_links_in_parent_content( $content ){
// if this is one of our two post types
if ( is_singular( array( \'incubators\', \'incubated\' ) ) ){
$args = array();
// set query args depending on what type this is
if( \'incubators\' == get_post_type() ){
// meta query for any incubated posts (children) with this incubator ID
$args = array(
\'post_type\' => \'incubated\',
\'posts_per_page\' => -1,
\'meta_query\' => array(
array(
\'key\' => \'_wpd_parent_id\',
\'value\' => get_the_ID()
)
)
);
// this is a child post, check if it has a parent
} elseif( $parent_id = get_post_meta( get_the_ID(), \'_wpd_parent_id\', true ) ){
// get the single parent from the ID stored in post meta
$args = array(
\'post_type\' => \'incubators\',
\'posts_per_page\' => 1,
\'p\' => $parent_id
);
}
if( !empty( $args ) ){
// query and output the list if any posts were returned
$related = new WP_Query( $args );
if( $related->have_posts() ){
$content .= \'<ul>\';
foreach( $related->posts as $related_post ){
$content .= \'<li><a href="\' . get_permalink( $related_post ) . \'">\' . $related_post->post_title . \'</a></li>\';
}
$content .= \'</ul>\';
}
}
}
return $content;
}