Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I'm trying to build a debates-like system.

It will work like this:

A page will display the post with a countdown timer, so user will be able to submit comment till a specific period of time. (this will be the first page users will see)

All the comments submitted in that period of time will be displayed in a child page so there the users will be able to see all the comments.

And the other page will display some stats from the comments page like best comments(based on votes), poll results from a plugin shortcode.

All three pages will contain the same post ( the title, the content).

This is how I'm thinking to approach this: As long as the countdown plugin have the option to display other URL after the time is over I can replace the first page after the countdown is over with the page containing the poll results.

So by creating three pages in a parent-child relationship this can work.

Briefly, each of them will have different additional content ( first page will have a comments section where users will submit a comment, the other page will contain the comments submitted in the first one, and the third one will contain informations from the comments page like the poll results and best comments and also will replace the first page after the countdown is over.)

The first page will be the single-{myCPT}.php.

Second page which will be a child of the first page getting the comments from it. I will create this first from the dashboard assign it as a child to the first page and use a template for it something like page-{'slug'}.php Third page the same but of course with a different template.

I was thinking a lot and this seems the only solution.

Is this the way to go ? Or It can be done in a much easier way ? LATER EDIT: I've modified the cpt with my name and now I'm getting this:

Fatal error: Call to undefined function wpse121567_get_cpt_hierarchy() 

SNIPPET FROM MY single-cpt.php:

<div id="content" class="span9" role="main">




<?php if ( 'debate-parent' == wpse121567_get_cpt_hierarchy() ) {
    // Normal loop here
    if ( have_posts() ) : while ( have_posts() ) : the_post();

    get_template_part( 'inc/post-format/single', get_post_format() ); 
    endwhile; endif;
} 
// Child CPT
else if ( 'debate-child' == wpse121567_get_cpt_hierarchy() ) {
    // Globalize post object
    global $post;

    // Output Parent CPT title and content
    $parent = get_post( $post->post_parent );
    echo '<h1>' . $parent->post_title . '</h1>';
    echo '<div>' . apply_filters( 'the_content', $parent->post_content ) . '</div>';

    // Fetch parent CPT comments
    $parent_cpt_comments = get_comments( array(
        'post_id' => $post->post_parent,
        'status' => 'approve'
    ) );
    // Loop through parent CPT comments
    foreach ( $parent_cpt_comments as $comment ) {
        // Output comment list markup here
    }
}
// Grandchild CPT
else if ( 'debate-grandchild' == wpse121567_get_cpt_hierarchy() ) {
    // Comment Stats code goes here


?>

    <?php 


        $enable_rtl         = of_get_option('enable_rtl', false);



        if(!of_get_option('disable_pagination')){

            if($enable_rtl){

                $next_post = get_adjacent_post( false, '', true ); 

                $prev_post = get_adjacent_post( false, '', false ); 

            }else{

                $next_post = get_adjacent_post( false, '', false ); 

                $prev_post = get_adjacent_post( false, '', true ); 

            }

            ?>

            <?php

        }



    // show related posts by tag

    if(!of_get_option('disable_related_posts')){ 

        get_template_part( 'inc/related-posts' );

    }





    // If comments are open or we have at least one comment, load up the default comment template provided by Wordpress

    if ( comments_open()  )

        comments_template( '', true );



 }else{ // Well, if there are no posts to display and loop through, let's apologize to the reader (also your 404 error) ?>



<article class="post error">

    <h1 class="404"><?php _e('Page not found', 'outbox'); ?></h1>

</article>



<?php } // OK, I think that takes care of both scenarios (having a post or not having a post to show) ?>

</div><!-- #content .site-content -->
share|improve this question
    
Yes, it's possible. What have you tried? Also: is there any particular reason that you're set on using a custom page template, rather than single-{cpt}.php in this case? –  Chip Bennett Nov 7 '13 at 14:47
    
If the point of the child pages is simply a placeholder for parent page comments display, I think an endpoint would be more appropriate. –  Milo Nov 7 '13 at 15:04
    
@ChipBennett, I'm thinking that this is the only solution, otherwise how can I get the comments from the parent page? Or it will get them automatically ? I'm confused... –  Alecs Nov 7 '13 at 15:16
    
Why limit yourself to one potential implementation? Why not ask your question such that you consider any potential implementations for your ultimate objective? –  Chip Bennett Nov 7 '13 at 15:22
    
I've edited my question, Now I've presented the whole objective and the way I'm thinking to resolve it. Please take a look and tell me what do you think –  Alecs Nov 7 '13 at 16:53
add comment

2 Answers

up vote 1 down vote accepted

I would take advantage of post-type hierarchy, and the single-{cpt}.php template file, to accomplish everything you're after.

You can use $post->post_parent (recursively) to determine if the current CPT is a parent, child, or grandchild, and also to query content from parent and grand-parent CPTs for output.

CPT Hierarchy

You can create a custom function to determine the hierarchy of the current CPT; e.g.:

function wpse121567_get_cpt_hierarchy() {
    // Make sure it's the right CPT
    if ( 'cpt-slug' != get_post_type() ) {
        return false;
    }
    // Globalize the post object
    global $post;
    // Parent CPT
    if ( 0 == $post->post_parent ) {
        return 'cpt-parent';
    }
    // Not a parent CPT, so fetch current post parent
    $parent = get_post( $post->post_parent );
    // Child CPT
    if ( 0 == $parent->post_parent ) {
        return 'cpt-child';
    } else {
        return 'cpt-grandchild';
    }
}

Parent CPT

The "parent" CPT can simply use the normal loop to display the debate title, content, etc.:

if ( 'cpt-parent' == wpse121567_get_cpt_hierarchy() ) {
    // Normal loop here
    if ( have_posts() ) : while ( have_posts() ) : the_post();
        // Normal loop markup
    endwhile; endif;
}

Child CPT

The "child" CPT can fetch the parent CPT's comments using get_comments() and display them:

if ( 'cpt-child' == wpse121567_get_cpt_hierarchy() ) {
    // Globalize post object
    global $post;

    // Output Parent CPT title and content
    $parent = get_post( $post->post_parent );
    echo '<h1>' . $parent->post_title . '</h1>';
    echo '<div>' . apply_filters( 'the_content', $parent->post_content ) . '</div>';

    // Fetch parent CPT comments
    $parent_cpt_comments = get_comments( array(
        'post_id' => $post->post_parent,
        'status' => 'approve'
    ) );
    // Loop through parent CPT comments
    foreach ( $parent_cpt_comments as $comment ) {
        // Output comment list markup here
    }
}

Grandchild CPT

The "grandchild" CPT can fetch the Parent CPT's statistics (using whatever method you choose):

if ( 'cpt-grandchild' == wpse121567_get_cpt_hierarchy() ) {
    // Comment Stats code goes here
}

All in one template file single-{cpt}.php

Putting it all together:

get_header();

// Parent CPT
if ( 'cpt-parent' == wpse121567_get_cpt_hierarchy() ) {
    // Normal loop here
    if ( have_posts() ) : while ( have_posts() ) : the_post();
        // Normal loop markup
    endwhile; endif;
} 
// Child CPT
else if ( 'cpt-child' == wpse121567_get_cpt_hierarchy() ) {
    // Globalize post object
    global $post;

    // Output Parent CPT title and content
    $parent = get_post( $post->post_parent );
    echo '<h1>' . $parent->post_title . '</h1>';
    echo '<div>' . apply_filters( 'the_content', $parent->post_content ) . '</div>';

    // Fetch parent CPT comments
    $parent_cpt_comments = get_comments( array(
        'post_id' => $post->post_parent,
        'status' => 'approve'
    ) );
    // Loop through parent CPT comments
    foreach ( $parent_cpt_comments as $comment ) {
        // Output comment list markup here
    }
}
// Grandchild CPT
else if ( 'cpt-grandchild' == wpse121567_get_cpt_hierarchy() ) {
    // Comment Stats code goes here
}

get_footer();
share|improve this answer
    
Let me see if I got it, I create 3 posts inside my cpt from the dashboard, first one is the default post, the second one will be named comments and I will assign it as a child to the first one, and the third one named stats will be a child of the first one or the second one? –  Alecs Nov 7 '13 at 18:29
    
Third would be a child of the second. –  Chip Bennett Nov 7 '13 at 18:36
    
Thanks, but the child posts will have the same title,post content as the parent but with the option to add more stuff if it's needed?I'm asking this because I don't want to copy and paste the same post text, thumbnail image for each one ? Or this is the only way ? –  Alecs Nov 7 '13 at 18:48
1  
You have access to the $post object for Parent, Child, and/or Grandchild CPTs, so you can output the parent CPT title/content/etc. I'll edit the question to show an example with the child CPT. –  Chip Bennett Nov 7 '13 at 18:52
1  
You need to clean up your HTML/PHP interspersion. You've dumped PHP code into the template, without an opening <?php tag, and you've got PHP tags inside of PHP code. –  Chip Bennett Nov 7 '13 at 21:07
show 6 more comments

As I mentioned in my comment, I would use some rewrite endpoints for this. That way each custom post is just a single entry on the admin side where you can centrally mange all the content for that single custom post. Use add_meta_box and/or Custom Fields to add extra data to each post.

First, add the endpoints:

function wpa121567_rewrite_endpoints(){
    add_rewrite_endpoint( 'comments', EP_PERMALINK );
    add_rewrite_endpoint( 'stats', EP_PERMALINK );
}
add_action( 'init', 'wpa121567_rewrite_endpoints' );

After rewrite rules are flushed, each of your custom posts will be able to use two additional permalinks:

site.com/your-custom-type-slug/single-custom-post-name/
site.com/your-custom-type-slug/single-custom-post-name/comments/
site.com/your-custom-type-slug/single-custom-post-name/stats/

Then in your single-{cpt}.php template, you can check if the request is for the comments or stats pages, and include or output the desired data:

if( array_key_exists( 'comments', $wp_query->query_vars ) ){
    // the request is for the comments page
} elseif( array_key_exists( 'stats', $wp_query->query_vars ) ) {
    // the request is for the stats page
} else {
    // the request is for the main post
}

EDIT

Additionally, you could use the single_template filter to include separate templates based on the view:

function wpa_post_type_template( $single_template ){
    global $post;
    if ( 'your-cpt-slug' == $post->post_type ) {
        if( array_key_exists( 'comments', $wp_query->query_vars ) ){
            $single_template = locate_template( 'cpt-comments.php', false );
        } elseif( array_key_exists( 'stats', $wp_query->query_vars ) ) {
            $single_template = locate_template( 'cpt-stats.php', false );
        }
    }
    return $single_template;
}
add_filter( 'single_template', 'wpa_post_type_template' );
share|improve this answer
    
I like this approach, but how do I put extra content for each page from the dashboard ? –  Alecs Nov 8 '13 at 13:32
    
and in this approach it may be a problem for me because I will need to use also some shortcodes, and as far as I know the custom fields / meta boxes don't accept them –  Alecs Nov 8 '13 at 14:13
1  
as I mentioned, you can use a meta box to add additional content areas, or you can use a plugin like Advanced Custom Fields, which will do all the work for you. shortcodes can be used anywhere, you just need to run content through do_shortcode, or apply_filters to apply the_content filters. I believe ACF will do those for you as well if you use a wysiwyg field. –  Milo Nov 8 '13 at 15:06
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.