自WordPress版本4.4起\'theme_page_templates\'
允许设置任意页面模板。
这意味着可以在页面编辑屏幕的“页面模板”菜单中显示任意值,选择后,该值将存储在页面的页面模板元中。
这意味着您可以“自动”为任何注册的CPT创建页面模板。
设置页面模板代码如下所示:
add_action( \'current_screen\', function( \\WP_Screen $screen ) {
if( \'page\' !== $screen->id || \'post\' !== $screen->base ) {
return;
}
// retrieve CPT objects with archive
$types = get_post_types( [\'has_archive\' => true], \'objects\' );
// store CPT slug and labels in an array
$menu = array();
foreach( $types as $cpt ) {
$menu[ $cpt->name ] = \'Archive: \' . $cpt->label;
}
// merge with page templates
$menu and add_filter(
\'theme_page_templates\',
function( array $templates ) use ( $menu ) {
$templates = array_merge( $templates, $menu );
return $templates;
}
);
} );
使用此代码,假设您注册了一个帖子类型
resources
具有
has_archive
设置为
true
, 创建或编辑页面时,您将在“页面模板”下拉列表中看到一个名为
Archive: Resources
.
您可以在创建页面时选择要用于显示resources
职位。
重定向直接页面访问
由于此页面是一个归档文件而不是一个页面,因此在访问页面时,可以使用一些代码将用户重定向到实际CPT的归档文件:
add_action( \'template_redirect\', function() {
if( is_page_template() ) {
// current page templates
$template = get_page_template_slug( get_queried_object_id() );
// array of CPT names, filtering the ones with archives
$types = get_post_types( array( \'has_archive\' => true ), \'names\' );
// if the current template is one of the CPT, redirect
if( in_array( $template, $types, true ) ) {
wp_safe_redirect( get_post_type_archive_link( $template ) );
exit();
}
}
} );
获取页面数据查看文章时,您可能希望使用该页面的内容和标题。
那么,让我们编写一个函数,用于获取特定帖子类型的页面。
function get_archive_page( $post_type = \'\' ) {
// if no CPT given, let\'s use the current main query to get it
if( ! $post_type ) {
global $wp_query;
$query_var = ( array ) $wp_query->get( \'post_type\' );
$post_type = reset($query_var);
}
// if we have a valid post type
if( post_type_exists( $post_type ) ) {
// let\'s query the first page that has a page template
// named after the the post type
$posts = get_posts( array(
\'post_type\' => \'page\',
\'post_status\' => \'publish\',
\'posts_per_page\' => 1,
\'orderby\' => \'menu_order\',
\'order\' => \'ASC\',
\'meta_query\' => array( array(
\'key\' => \'_wp_page_template\',
\'value\' => $post_type
) )
) );
// if we have results, return first (and only) post object
if( $posts ) {
return reset($posts);
}
}
}
您可以使用上面的函数编写两个附加函数来获取页面的标题和内容:
function get_archive_page_title( $post_type = \'\' ) {
$page = get_archive_page( $post_type );
return ( $page ) ? get_the_title( $page ) : \'\';
}
function get_archive_page_content( $post_type = \'\' ) {
$page = get_archive_page( $post_type );
$content = \'\';
if( $page ) {
setup_postdata( $page );
ob_start();
the_content();
$content = ob_get_clean();
wp_reset_postdata();
}
return $content;
}
function the_archive_page_title() {
echo get_archive_page_title();
}
function the_archive_page_content() {
echo get_archive_page_content();
}
函数名应该明确它们的作用。
您还可以编写如下函数get_archive_page_meta()
如果需要自定义字段。
现在,在存档模板中archive.php
(或在archive-resources.php
) 模板中,您可以使用上述功能显示存档页面的标题和内容。
它看起来像:
<h1><?php the_archive_page_title(); ?></h1>
<div><?php the_archive_page_content(); ?></div>
<?php
while( have_posts() ) : the_post();
// loop stuff here
endwhile;
?>
这样,您的CPT存档url将
example.com/resources/
您的单个CPT url将是
example.com/resources/post-name/
就像你想要的那样。
同时,您将能够为帖子类型编写特定的内容和标题(以及自定义字段,如果需要的话)。
此外,请考虑此方法对于您已经或将来可能使用的任何post类型都是可重用的。