Post Thumbnail Dialog

Exclude A Category From Turn Off Comments Automatically

Thanks to our post New Ideas For 2010? Now It’s Your Turn! we got an email form one of our loyal sponsors Chris Coyier.

Hey WP Engineer folks!

I have a little issue I'm trying to resolve on CSS-Tricks, regarding comments. In my discussion settings, I have it set to automatically turn off comments on everything after one-month. However, on certain things, specifically the snippets pages which all share a common page template, I want the comments to be left on forever.
This seems like the job for some fancy functions.php work that you guys are the masters at πŸ™‚

Ok Chris, here is our solution (copy the code in your functions.php and change the $cat values):

/**
 * Close comments on an old post.  Hooked to comments_open and pings_open.
 * small modifications on the default functions of WordPress
 *
 * @param bool $open Comments open or closed
 * @param int $post_id Post ID
 * @param int $cat Category ID (cat_ID), set '' or empty for all categories
 * @param int $days_old Days to close comments, set '' for use value from settings
 * @return bool $open
 */
function wpe_close_comments_for_old_post( $open, $post_id, $cat = array(1, 4), $days_old = '' ) {
	if ( !$open )
		return $open;
	
	if ( in_category($cat) )
		return $open;
	
	if ( '' === $days_old )
		$days_old = (int) get_option('close_comments_days_old');

	if ( !$days_old )
		return $open;
	
	$post = get_post($post_id);
	
	if ( time() - strtotime( $post->post_date_gmt ) > ( $days_old * 24 * 60 * 60 ) )
		return false;
	
	return $open;
}
add_filter( 'comments_open', 'wpe_close_comments_for_old_post', 10, 2 );
add_filter( 'pings_open',    'wpe_close_comments_for_old_post', 10, 2 );

Thanks Chris for your idea and please send us an email if you also have a nice idea how we could make WordPress even better.

Comments are closed.

17 comments

  1. Chris Coyier

    Nice! You guys rock =)

    I was just slightly unclear though. In my particular situation, it's a *page template* that I'd like to leave comments on eternally for, not a category. Could I change this:

    if ( in_category($cat) )

    to this?

    if ( is_page_template($cat) )

    and then pass in the file name for the page template as a param?

  2. Michael

    Hey Chis, change it to


    function wpe_close_comments_for_old_post( $open, $post_id, $pageid = 45, $days_old = '' ) // where 45 is the ID of snippets-page

    and than replace the category line with

    if ( is_page($pageid )
    return $open;

    That should work.

  3. Alphawolf

    @Chris Coyier: If you'd like to use is_page_template() passing a page template ID won't work. Instead, pass the page template filename as a parameter, like so:

    if ( is_page_template('your-page-template.php') )

    where your-page-template.php is located in your active theme's folder. πŸ™‚

  4. Chris Coyier

    This was my attempt at alteration:

    function wpe_close_comments_for_old_post( $open, $post_id, $template = 'page-snippet.php', $days_old = '' ) {
    if ( !$open )
    return $open;

    if ( is_page_template($template) )
    return $open;

    ... rest the same

    but no dice.

  5. Alphawolf

    @Chris Coyier: Try

    if ( basename( get_page_template() ) == $template )

    instead.

    *keeps his fingers cross* πŸ™‚

  6. Chris Coyier

    Thanks for the update, but unfortunately no, still nothing.

    My test:

    function wpe_close_comments_for_old_post( $open, $post_id, $template = 'page-snippet.php', $days_old = '' ) {
    if ( !$open )
    return $open;
    if ( basename( get_page_template() ) == $template )
    return $open;
    if ( '' === $days_old )
    $days_old = (int) get_option('close_comments_days_old');
    if ( !$days_old )
    return $open;
    $post = get_post($post_id);
    if ( time() - strtotime( $post->post_date_gmt ) > ( $days_old * 24 * 60 * 60 ) )
    return false;
    return $open;
    }
    add_filter( 'comments_open', 'wpe_close_comments_for_old_post', 10, 2 );
    add_filter( 'pings_open', 'wpe_close_comments_for_old_post', 10, 2 );

    Example of page I'm trying to leave comments open on:
    http://css-tricks.com/snippets/css/quality-abbreviations/

  7. Michael

    Chris, css is a subpage of snippets and quality-abbreviations a subpage of css, right?

  8. Michael

    Chris: Alphawolf and me working hard :p

    if ( get_post_meta($post_id, '_wp_page_template', true) == $template ) return open;

  9. Chris Coyier

    I gave it a shot but it's a no-go. Thanks for all the work on this though guys. I'm sure it works great for categories =) It probably isn't destined to be for me.

  10. Chris Coyier

    As a test, I made the function just "return true;", and indeed that did activate comments on all older content, so at least we can be sure the functions.php file is working and the filter is being applied properly. My theory is that the is_page_template and get_post_meta functions dont run properly in this context?

  11. Michael

    Here is the final working code for Chris Coyier's solution:

    function wpe_close_comments_for_old_post( $open, $post_id, $template = 'page-snippet.php', $days_old = '' ) {
    global $wp_query;

    if( !$post_id )
    $post_id = $wp_query->post->ID;

    if ( get_post_meta($post_id, '_wp_page_template', true) == $template && get_option('close_comments_for_old_posts') ) {
    return !$open;
    }

    if ( !$open )
    return $open;

    if ( '' === $days_old )
    $days_old = (int) get_option('close_comments_days_old');

    if ( !$days_old )
    return $open;

    $post = get_post($post_id);

    if ( (time() - strtotime( $post->post_date_gmt )) > ( $days_old * 24 * 60 * 60 ) )
    return false;

    return $open;
    }
    add_filter( 'comments_open', 'wpe_close_comments_for_old_post', 10, 2 );
    add_filter( 'pings_open', 'wpe_close_comments_for_old_post', 10, 2 );

    Thanks to Alphawolf for the final idea!

  12. Chris Coyier

    Yep that did the trick. I think it was pulling in that

    global $wp_query;

    that got the get_post_meta working.

    Excellent work guys, thanks!

  13. ahmad

    Hi,

    I loved the post very much.
    I have a small blog and what I want is to allow comments Meta Tag on some categories and totally make the comments link or the comments box invisible in some categories.

    Say I have 4 categories Google, Microsoft , yahoo, and Amazon. what I want is to remove comments box and link fully for category google & keep it visible for yahoo and others.

    Looking for your help

    Kind Regards,
    Ahmad

  14. phocean

    Hi,

    I copied the code above in functions.php of my them, created a new template and affected it to the page where I want the comment to stay open.
    Of course I updated the template name inside the function call.

    But it does not work. Any suggestion please ? Is there any change that my theme ignore functions.php ?

  15. Ralph

    I'm trying to get this to work for allowing comments permanently on two categories, and not having success. I'm confused on where you sub the $cat value - is it in the array definition or down in the add_filter function? Either way, comments stay off. How can I best troubleshoot this?

  16. Dan

    Hey, this looks great and should do exactly what I need it to. One question though, whenever I place it in my 'functions.php' I get a parse error...?

    Is there somewhere in particular where I should be placing it?

One pingback

  1. 11 Awesome Wordpress Development Blogs