Creating a custom comment list

What?

Comments. That is the topic. As some may know I’m in the middle of creating a WordPress theme to submit to the repository. I want this theme to not only pass but to pass with flying colors. I followed about as close to how the default themes are but have also integrated some from themes I have reviewed and added a bit of my own style, of course.

What started this?

What really initiated this was the default theme for WordPress 3.6: Twenty Thirteen. Previous default versions all passed a certain set of arguments and made a callback function in order to display the comments rather than have WordPress handle it. Wait? You mean to tell me that I can let WordPress do the coding for me? Yes. If you don’t like having control of how to structure your code. Twenty thirteen lets WordPress handle the coding of the comment list.

Callback?

Yes, a callback function. Simple and you have more control of how the code is structured and displayed. The function that handles this is:

wp_list_comments()

All that is needed now is some arguments:

$defaults = array(
    'walker'            => null,
    'max_depth'         => '',
    'style'             => 'ul',
    'callback'          => null,
    'end-callback'      => null,
    'type'              => 'all',
    'page'              => '',
    'per_page'          => '',
    'avatar_size'       => 32,
    'reverse_top_level' => null,
    'reverse_children'  => '',
    'format'            => 'xhtml', /* or html5 added in 3.6  */
    'short_ping'        => false, /* Added in 3.6 */
);
wp_list_comments ( $defaults );

Now, the thing that creates the comments is the callback. It tells WordPress to run the default code if no argument is passed. If there is one, then WordPress will look for that function and use that instead. In Twenty Twelve it was:

wp_list_comments( array(
    'callback' => 'twentytwelve_comment',
    'style' => 'ol'
     ) );

In the Twenty Thirteen theme it actually uses the default HTML5 markup by not setting a callback function and using the new argument:

'format' => 'html5'

This tells WordPress to use the HTML5 markup for the comment which is:

<article class="comment-body">
 <footer class="comment-meta">
 <div class="comment-author vcard"></div><!-- .comment-author -->
 
 <div class="comment-metadata">
 <a href="">
 <time></time>
 </a>
 <span class="edit-link">Edit</span>
 </div><!-- .comment-metadata -->

 <p class="comment-awaiting-moderation"></p>

 </footer><!-- .comment-meta -->

 <div class="comment-content"></div><!-- .comment-content -->

 <div class="reply"></div><!-- .reply -->

</article><!-- .comment-body -->

Keep in mind that is the very simplified version without any WordPress comment template tags. Just straight HTML5 markup. Some people don’t mind using that while others like to have more control and would like to style in a different way. In order to do that we have to pass an argument to the callback function argument.

Enter the callback

This is why you want to use a callback function to create and style the comment. In order to do this we pass the argument

'callback' => 'my_theme_comment'

in our array of arguments much like Twenty Twelve does. Next we have to create the actual function that will house our newly created and customized comment with custom markup. Where that function resides is entirely up to you.

Once we have created the function we can start with all the markup and comment template tags we so desire. I personally like to keep things fairly simple and just have the comment author, date and text. Often my code looks like:

function custom_comments( $comment, $args, $depth ) {
    $GLOBALS['comment'] = $comment;
    switch( $comment->comment_type ) :
        case 'pingback' :
        case 'trackback' : ?>
            <li <?php comment_class(); ?> id="comment<?php comment_ID(); ?>">
            <div class="back-link">< ?php comment_author_link(); ?></div>
        <?php break;
        default : ?>
            <li <?php comment_class(); ?> id="comment-<?php comment_ID(); ?>">
            <article <?php comment_class(); ?> class="comment">

            <div class="comment-body">
            <div class="author vcard">
            <?php echo get_avatar( $comment, 100 ); ?>
            <span class="author-name"><?php comment_author(); ?></span>
            <?php comment_text(); ?>
            </div><!-- .vcard -->
            </div><!-- comment-body -->

            <footer class="comment-footer">
            <time <?php comment_time( 'c' ); ?> class="comment-time">
            <span class="date">
            <?php comment_date(); ?>
            </span>
            <span class="time">
            <?php comment_time(); ?>
            </span>
            </time>
            <div class="reply"><?php 
            comment_reply_link( array_merge( $args, array( 
            'reply_text' => 'Reply',
            'after' => ' <span>&amp;amp;darr;</span>', 
            'depth' => $depth,
            'max_depth' => $args['max_depth'] 
            ) ) ); ?>
            </div><!-- .reply -->
            </footer><!-- .comment-footer -->

            </article><!-- #comment-<?php comment_ID(); ?> -->
        <?php // End the default styling of comment
        break;
    endswitch;
}

And there we have a custom comment that will be used instead of the default WordPress one.

I will always be a novice

I know it does sound funny to those that have known me for several years but that is how I view myself sometimes. I don’t mean that I am a beginner but I want to be one. I mean this in the most positive way I can think of.

A few years ago I was watching a documentary about the guitar. It opened my eyes to a slightly different way of thinking and looking at some things in my life. The person that really made me think most was Carlos Santana. Not too shocking since I fell in love with his guitar style of playing nearly a decade ago. He said that when plays the guitar he plays it like it’s his first time playing ( Or at least along those lines ).

This is often how I feel. The reason is because I think that there are several ways of doing one thing. Much like in PhotoShop there is more than one way of removing the background from an image. Yeah, each has their positive and negative but in the end they all get the same result. This is true when working with WordPress.

Recently I posted how to create a sticky post slider. I mentioned that another way of creating it would be to use get_posts rather than modifying the query. That is one way; another would be using query_posts and then of course there is what seems to be the more popular way of just getting a specific category or categories. There is nothing wrong with those methods. Each one has its own pitfalls and each one has their own feat. It is all a matter of preference.

What has brought this up is last week I was doing yet another WordPress theme review and saw a method that was new to me. It actually dealt with the WordPress theme customizer. It gave me an idea of how I could potentially use the customizer to include widgets or not. The other options was to display the copyright information on the footer.

Which then sparked an idea to create a plugin that has the ability to display the widgetized area on a single post or not, which actually could be attainable by using a simple conditional check for a theme option. And now I’m slowly trailing off.

The reason I say that I will always be a novice is because I want to be. It does sound a little odd to say but it is true. The reason is that I want to always be learning. The moment I feel like I have nothing left to learn that is when my brain wants to stop working and that is big no-no in my book. I want to always stimulate my brain and keep gathering information, methods and tons of new ideas.

The brain should always be focused and challenged on a daily basis.

Creating a sticky post slider

Brief background

Creating a slider is simple. For some. In WordPress there are a lot of ways to creating a post slider, image slider, category slider and just about any type of slider you could possibly imagine. The one I wanted to share is creating one with sticky posts. You know the ones that you have to pick from the slightly hidden options.

Make post sticky

Yeah. That little guy. The way WordPress handles sticky post is by putting them on the front page and keeping them on top regardless of when it was posted. A good example is the quick image I created to help illustrate.

The requirements

WordPress has plenty functions and plenty of ways of getting the required posts. One way of getting posts is using get_posts() but that isn’t the method I’ll be using. I’ll be using the WP_Query and alter it just a little bit. No, not with query_posts because that will just cause the world to implode. Okay, not really but there are several other reasons not to use that function.

The steps

In order to have a good functional featured post slider we first need to layout the steps needed. What I did initially was make a quick list of the steps.

  1. Get the posts
  2. Check if there are any ‘sticky’ posts
  3. If there are then run our code
  4. Ignore sticky posts in regular feed
  5. Drink up

The code

Now that we have our logic we can get started.

The first thing we have to do is get all the posts that are set to be sticky. We create and array to hold these.

$stickies = get_option( 'sticky_posts' );

We need to count how many posts there are and we’ll store that as a variable so we can use it later on.

$count = count( $stickies );

Now that we have an array and the total we can start a new query for only those posts. The way we do this is by creating a new WP_Query and passing some arguments. So we’ll create these arguments and name our newly created object of posts $featured. It can be whatever you want it to be. If you are submitting to the WordPress repo then prefix it with your theme or equivalent.

$args = array(
	'post__in'       => $stickies,
	'posts_per_page' => 3,
	'post_type'      => 'post',
	'nopaging'       => true
	);
$featured = new WP_Query( $args );

Now that we have our new object filled with posts we can run our code with the newly created query. But wait! When WordPress is first installed there are no sticky posts so then how do we check for that? Simple. Remember that we stored the value into a variable called $count? We’ll use that. We’ll use an if statement to run our code. If there are no posts then we’ll begin the newly created WordPress loop.

if ( $count > 0 ) {
  // run WordPress loop using $featured
}

Sounds simple now that we have it all together, right? Now we can create the loop and fill it with all the goodies and information we want using template tags. Don’t forget to use wp_reset_postdata() to reset our post data. There is one last thing we must do to get it all working right and that is hooking to pre_get_posts.

What?!

One more thing?

Yes, one last thing. I know a bit of a curveball but this is what will prevent the doubling of sticky posts. What we have to do is add just a few lines of code to our functions file of our theme.

add_action( 'pre_get_posts', 'my_awesome_theme_pre_posts' );
function my_awesome_theme_pre_posts( $query ){
    if ( is_home() ){
        $query->set( 'post__not_in', get_option( 'sticky_posts' ) );
    }

    return $query;
}

Now that we have that done we have our final code snippet:

// Create array of all the sticky_posts
$stickies = get_option( 'sticky_posts' );

// Count how many there are, if any
$count = count( $stickies );

// Create a set of arguments to pass
$args = array(
	'post__in'       => $stickies,
	'posts_per_page' => 3,
	'post_type'      => 'post',
	'nopaging'       => true
	);

$featured = new WP_Query( $args );

// If there is one or more sticky post we create our new slider
if ( $count > 0 ) : ?>
<section class="featured" id="featured-slider">
    <?php while( $featured->have_posts() ) : $featured->the_post(); ?>
    <article <?php post_class( 'featured' ); ?> id="post-< ?php the_ID(); ?>">
        <h1 class="featured-title"><?php the_title(); ?></h1>
        <div class="content"><?php the_content(); ?></div>
        <div class="content"><?php wp_link_pages(); ?></div>
        <footer class="meta">Posted: <?php the_time( get_option( 'date_format' ) ); ?></footer>
    </article>
    <?php endwhile; wp_reset_postdata(); ?>
</section><!-- end of our featured article slider -->
<?php endif; // end the featured posts ?>

Enjoy

And done! For the most part since we need to add interaction but I’ll let you pick out what to use since there are plenty of jQuery slider plugins to help with that.

Issues with my_query

Recently I was in the middle of creating a theme that had support for a front page and blog with featured posts that displayed in a certain manner. I read up on how to create a new WP_Query and felt pretty confident I would be able to get the desired results. Yeah, I was a little wrong. I got results but what ended up happening was that some of the posts were being place in the wrong sequence.

I got frustrated and had to take some time away from it. I turned to my source of inspiration and motivation: theme reviews. One of the themes that I reviewed used a method that I wanted. I looked at how they coded it and as it turns out it was the way I thought. New WP_Query object and

wp_reset_query

used.

I tried using the code and wondered what would happen if there were no sticky posts. I thought about this only because by default WordPress only creates one post and there are no sticky posts. What did it return? It for some reason returned all posts. The code was fairly simple:

$args = array(
        'posts_per_page' => 10,
        'post_status' => 'publish',
        'post__in' => get_option('sticky_posts')
        );
$fPosts = new WP_Query( $args );
$countPosts = $fPosts->found_posts;

if ( $countPosts > 1 ) { // run code for slider }

The downside to this is that

$countPosts

is not the amount of sticky posts. It kept driving my crazy when I had no sticky posts because it would return all posts. I was about ready to punch a wall. Such a simple thing and I couldn’t figure it out.

I read the WordPress docs about the WP_Query and noticed that the function

get_option( 'sticky_posts' )

creates an array of posts. That’s when the light bulb turned on and I altered the code.