自定义帖子类型的动态page.php模板

时间:2014-04-05 06:43:31

标签: wordpress custom-post-type

我注册了几个自定义帖子类型。我想在自己的页面上显示每个自定义帖子类型的所有“帖子”,这些页面必须在导航菜单中可见。

对每个自定义帖子类型的页面模板只有一个page-custom.php模板会很棒。是否有可能创造这样的东西。

1 个答案:

答案 0 :(得分:0)

如果查看template hierarchy,自定义帖子类型通常会显示在存档模板上。普通模板层次结构不会默认使用page.php类型模板来显示自定义帖子类型。

存档模板的问题在于它们不会自动添加到默认导航菜单中,创建自定义菜单来创建链接并不总是最方便的方式。

此处的方法是使用WP_Query为循环创建自定义查询以包含自定义帖子类型。 WP_Query有一个post_type类型参数,用于调用post types

因此,需要修改以下内容才能使其正常工作:

首先,创建自定义page.php模板

要创建自定义page.php,您需要复制主题page.php并将其重命名为page-cpt.php。现在打开它并改变循环。为了这个答案,我使用了默认的二十四个主题。删除模板中的所有内容并将其替换为此代码

<?php
/**
 * Template Name: Custom Post Type Page
 */
get_header(); ?>

<?php
//See if we have any values
$post_meta=array();
$post_meta = get_post_meta( $post->ID,false );
$posttype = isset( $post_meta['_cpt_post_type'] ) ? $post_meta['_cpt_post_type'][0] : 1;
$orderby = isset( $post_meta['_cpt_order_by'] ) ? $post_meta['_cpt_order_by'][0] : 'date';
$asc = isset( $post_meta['_cpt_asc'] ) ? $post_meta['_cpt_asc'][0] : 'DESC';
$post_count = isset( $post_meta['_cpt_post_count'] ) ? $post_meta['_cpt_post_count'][0] : get_option('posts_per_page');
if(!$post_count || !is_numeric( $post_count )) $post_count = get_option('posts_per_page');
?>  
<div id="main-content" class="main-content">

    <div id="primary" class="content-area">
        <div id="content" class="site-content" role="main">

        <?php the_post(); ?>
        <div class="entry-content">
            <article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>

            <?php if( $post->post_content ) : ?>

                    <header class="entry-header">
                        <h1 class="entry-title"><?php echo the_title(); ?></h1>
                    </header><!-- .entry-header -->

                <div class="entry-content">
                    <?php the_content(); ?>
                    <?php wp_link_pages( array( 'before' => '<div class="page-link"><span>' . __( 'Pages:', 'pietergoosen' ) . '</span>', 'after' => '</div>' ) ); ?>
                </div><!-- .entry-content -->
                <footer class="entry-meta">

                </footer><!-- .entry-meta -->
            <?php endif; ?>
            </article><!-- #post-<?php the_ID(); ?> -->
        </div>  

            <?php 
            /* Do we have any Custom Post Type */
                global $post;

                // Save posts for later use
                $tmp_post = $post;

                $args = array( 
                    'post_type' => $posttype,
                    'posts_per_page' => $post_count,
                    'paged' => $paged,
                    'order' => $asc,
                    'ignore_sticky_posts' => 1,
                );

                    $wp_query= null;
                    $wp_query = new WP_Query();
                    $wp_query->query( $args );

                // Output
        if ( $wp_query->have_posts() ) :

                // Start the Loop.
                while ( have_posts() ) : the_post();


            get_template_part( 'content', get_post_format() );

            endwhile;

                pietergoosen_pagination();  

                else : 

                    get_template_part( 'content', 'none' );

                endif; ?>

                <?php 
                    // Reset the post to the page post
                    $post = $tmp_post; 
                ?>

            <?php if ( comments_open() || get_comments_number() ) {
                        comments_template();
                    } ?>

    </div><!-- #content -->
    </div><!-- #primary -->

    <?php get_sidebar( 'content' ); ?>

</div><!-- #main-content -->

<?php
get_footer();

第一段代码用于从db调用设置。在页面编辑器屏幕中创建新页面时,将通过后端的元变量设置此项。这里重要的代码是WP_Query的参数。

$args = array( 
 'post_type' => $posttype,
 'posts_per_page' => $post_count,
 'paged' => $paged,
 'order' => $asc,
 'ignore_sticky_posts' => 1,

这将决定将显示哪些自定义帖子类型,每页帖子和帖子顺序。所有这些设置都是从​​db调用的,并在后端的自定义元框中设置

其次,创建一个custom meta box

当创建新页面并在“页面属性”元框中选择“自定义帖子类型页面”时,此元数据框将显示在“页面”屏幕中。

functions.php或自定义函数文件

中添加以下内容
add_action('admin_init', 'pietergoosen_add_cpt_meta_box');

function pietergoosen_add_cpt_meta_box(){   
    $post_id = isset( $_GET['post'] ) ? $_GET['post'] : 0 ;
    if($post_id) { 
        $template_file = get_post_meta($post_id,'_wp_page_template',TRUE);
        if ($template_file == 'page-cpt.php') { 
            add_meta_box('cpt_meta_box', __( 'Page of Posts with the same name', 'pietergoosen' ), 'pietergoosen_cpt_meta_options', 'page', 'side', 'core');
        } else {
            $meta = get_post_meta($post_id, '_cpt_post_type', true);
            if( $meta ) {
                pietergoosen_cpt_update_post_meta($post_id, '_cpt_post_type', '');
                pietergoosen_cpt_update_post_meta($post_id, '_cpt_order_by', '');
                pietergoosen_cpt_update_post_meta($post_id, '_cpt_asc', '');
                pietergoosen_cpt_update_post_meta($post_id, '_cpt_post_count', '');
                remove_meta_box( 'cpt_meta_box', 'page', 'side');
            }
        }
    }
    add_action('save_post', 'pietergoosen_cpt_update_post_meta_box');
}

function pietergoosen_cpt_meta_options(){

    $post_id =  !empty($_GET['post']) ? $_GET['post'] : 0;
    if( !$post_id ) return;

    $template_file = get_post_meta($post_id,'_wp_page_template',TRUE);
    if ($template_file != 'page-cpt.php') return;

    global $order_list,$post_styles,$sort;
    $categories = get_categories();

    //Check if we have values
    $post_meta=array();
    $post_meta = get_post_meta( $post_id,false );

    $posttype = isset( $post_meta['_cpt_post_type'] ) ? $post_meta['_cpt_post_type'][0] : 1;
    $order_by = isset( $post_meta['_cpt_order_by'] ) ? $post_meta['_cpt_order_by'][0] : 'date';
    $asc = isset( $post_meta['_cpt_asc'] ) ? $post_meta['_cpt_asc'][0] : 'DESC';
    $post_count = isset( $post_meta['_cpt_post_count'] ) ? $post_meta['_cpt_post_count'][0] : get_option('posts_per_page');
    if(!$post_count || !is_numeric( $post_count )) $post_count = get_option('posts_per_page');
    ?>

    <!-- Start the meta boxes -->
    <div class="inside">
    <p><label><strong><?php _e( 'Custom Post Type', 'pietergoosen' ); ?></strong></label></p>
    <select id="_cpt_post_type" name="_cpt_post_type">
<?php 
    //Custom Post Type List
    $args = array(
    'public'   => true,
    '_builtin' => false
    );

    $output = 'names'; // names or objects, note names is the default
    $operator = 'and'; // 'and' or 'or'

    $post_types = get_post_types( $args, $output, $operator ); 

    foreach ( $post_types  as $post_type ) :
        $selected = ( $post_type == $posttype ) ? ' selected = "selected" ' : '';
        $option = '<option '.$selected .'value="'. $post_type;
        $option = $option .'">';
        $option = $option .$post_type;
        $option = $option .'</option>';
        echo $option;
    endforeach;

?>
    </select>

    <p><label><strong><?php _e( 'Order')?><strong></label></p>
    <select id="_cpt_asc" name="_cpt_asc">
<?php 

    $sort = array(
        'DESC' => array( 'value' => 'DESC','label' => 'Descending' ),
        'ASC' => array( 'value' => 'ASC','label' => 'Ascending' ),
    ); 

    foreach ($sort as $output) :
        $selected = ( $output['value'] == $asc ) ? ' selected = "selected" ' : '';
        $option = '<option '.$selected .'value="' . $output['value'];
        $option = $option .'">';
        $option = $option .$output['label'];
        $option = $option .'</option>';
        echo $option;
    endforeach;
?>
    </select>

    <p><strong><label><?php _e( 'Posts per Page', 'pageofposts' ); ?><strong></label></p>
    <input id="_cpt_post_count" name="_cpt_post_count" type="text" value="<?php echo $post_count; ?>" size="3" />

    </div>
    <!-- End page of posts meta box -->
    <?php
}
function pietergoosen_cpt_update_post_meta_box( $post_id ){

    if ( empty( $_POST ) ) {
        return;
    } else {
        $template_file = get_post_meta($post_id,'_wp_page_template',TRUE);
        if ($template_file != 'page-cpt.php') return;

        if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) {
            return $post_id;
        } else {
            if ( $_POST['post_type'] == 'page' ) {
                if ( !current_user_can( 'edit_page', $post_id ) )
                  return $post_id;
            } else {
                if ( !current_user_can( 'edit_post', $post_id ) )
                  return $post_id;
            }
            $meta = isset( $_POST['_cpt_post_type'] ) ? $_POST['_cpt_post_type'] : 1;           
            pietergoosen_cpt_update_post_meta($post_id, '_cpt_post_type', $meta);
            $meta = isset( $_POST['_cpt_order_by'] ) ? $_POST['_cpt_order_by'] : 'date';            
            pietergoosen_cpt_update_post_meta($post_id, '_cpt_order_by', $meta);
            $meta = isset( $_POST['_cpt_asc'] ) ? $_POST['_cpt_asc'] : 'DESC';
            pietergoosen_cpt_update_post_meta($post_id, '_cpt_asc', $meta);
            $meta = isset( $_POST['_cpt_post_count'] ) ? $_POST['_cpt_post_count'] : get_option('posts_per_page');
            pietergoosen_cpt_update_post_meta($post_id, '_cpt_post_count', $meta);
            return;
        }
    }
}

function pietergoosen_cpt_update_post_meta($post_id, $key, $data) {
    $post_meta = get_post_meta($post_id, $key, true);
    if( $data != '' && $post_meta != $data) {
        update_post_meta($post_id, $key, $data);
    } elseif ( $post_meta != '' && $data == '' ) {
        delete_post_meta($post_id, $key);
    }
}

此代码的作用是注册和显示元框,将选项添加到元框并将选项存储到数据库以供page-cpt.php模板使用。

您现在可以创建新页面,并随意调用页面。在“页面属性”中,选择“自定义帖子类型页面”和“发布”您的页面。现在,自定义帖子类型选项的元数据框将显示在“发布”元数据框上方,并将显示所有当前可用的自定义帖子类型。选择并设置需要显示的选项,然后单击“更新”。您的页面现在将显示您选择的自定义帖子类型中的帖子,并且您的页面将显示在导航栏中。

您可以为此添加更多功能,或更改代码以相同方式显示类别或分类。希望这个帮助