Thursday, October 5, 2017

How to Use the WordPress Loop to Style Your First Post Differently

Being able to edit the WordPress Loop gives you lots of control over the design and content of your WordPress site.

I often create custom loops, sometimes by editing the standard loop and sometimes using WP_Query to create completely new loops.

But in some cases I want to take things further. I want to display the first post in my loop differently from subsequent posts. This could be by adding custom styling or it could be because I want to display different content.

For example I might want to display the post content for the first post but just the excerpt for subsequent posts. Or I might want to use a different sized featured image, or apply difference CSS classes to the first post.

Doing this can highlight your most recent post, drawing attention to it and encouraging visitors to read it or click on it. It can also enhance the layout of your site, breaking things up and creating a more varied design.

In this post, I'm going to show you how to use the WP_Query class to do it. I'll show you how to set up a custom query for all your posts using WP_Query and then I'll show you how to create a second query which just applies to the first post.

In the worked example I'll show you how to do this on a custom page template, using WP_Query to run two separate queries. And then I'll show you how to apply this technique to the standard loop, editing a standard archive template and using pre_get_posts to alter the standard loop.

Note: If you're not familiar with WP_Query and its awesome power, then check out our In-Depth Guide to Conquering WP_Query.

What You'll Need

To follow along with this post, you'll need a few things:

  • A development installation of WordPress – don't try this on your live site until you've got it working!
  • A code editor
  • Getting Started: Creating the Query

    My personal site has a custom page template in it for my 'books' page. This page displays the content I've added to the 'books' page and then runs a loop to output all of my books. This is done using a custom post type.

    Your loop might be very different – you could be using normal posts, it could be in an archive template file, a template file for a custom post type or anything you want not to work on. So you don't have to be working with a custom page template to use this technique. If you just focus on the loop itself, that shows you how the technique works and you can apply it to your own site.

    Here's my page with one loop outputting all of my books in a 2x 2 grid:

    I've used some object oriented CSS which is in my theme to create a 2×2 grid displaying each of my books. Within the loop I have the title, the excerpt and the featured image.

    Here's the loop that's running for all my posts:

    You'll see that my loop has just one argument: the post type. So it's displaying all posts of that post type, most recent first.

    But what we want to do is display the first post differently. Let's do that.

    Creating a Separate Loop for the First Post

    To display the first post differently, we need to create a separate loop that just runs that post.

    To do that, you need two arguments: one for the post type and one for the number of posts, which is the posts_per_page argument. Set that to 1.

    Start by duplicating your original loop so you have two loops in your template file, both using WP_Query. Now edit the arguments for the first one so they read as follows:

    This will fetch just the most recent post. But there's not much point in doing this unless you want to change something in that first loop.

    I want to output the excerpt and the content. I also want to add some styling for layout, so that the featured image and excerpt appear above the content.

    Here's the new version of the part of the loop that outputs the post itself, just for the first post:

    You'll see that there's extra code in there for the content, and that I've added some extra enclosing div elements to style the layout – again this uses styling that's already present in my theme.

    Here's the first post in my page:

    It looks good. You may have spotted that I've also removed the link to explore the book (as the entire content is here on the main books page) and instead there's a button to buy the book, which is taken form the content of the post.

    Amending the Loop for Subsequent Posts

    But there's a problem.

    Here's a screenshot showing you the first post and the posts after it:

    The first post is currently being duplicated. It's being fetched by the loop that was there originally, and it's also being fetched by the new loop for just the first post.

    This is fixed by adding an extra argument to the second loop – the offset argument. This tells WordPress to skip a set number of posts before fetching posts to output. As we've displayed one post in tour first loop, we need to offset by one.

    Note: If you're ever using this technique, the posts_per_page argument for your first loop and the offset argument for your second loop should be the same, They might not always be 1.

    In your second loop, amend the arguments so they look like this:

    Now when you refresh your page you'll find that the first post isn't duplicated:

    That's better! Now you're done. You've created a custom page with two loops, one of which displays extra content for the most recent post.

    Applying This Technique to the Standard Loop

    But what if your page is running the standard loop? If this is the case, you can edit the template file that's running that page, adding just one extra query using WP_Query. You don't have to write two new queries.

    There are two steps to this technique:

  • Add an extra query to your template file, using WP_Query.
  • In your theme's functions file, use pre_get_posts to amend the standard loop in this archive type to skip the first post.
  • Adding the Extra Query

    First, open the template file that you want to edit. It will be any archive template file. In my case if I was using a standard template file to output my custom post type, the file would be called archive-rmcc_book.php.

    Before the main loop, add an extra loop using WP_Query. You'll do this in a similar way to the above method, copying and editing the contents of the main loop, but putting it inside a query that's powered by WP_Query. Don't forget that you still need the post_type argument despite the fact that you're in the archive template for this post type.

    Save your template file and your first post will show up twice, just like it did in my worked example.

    Skipping the First Post in the Main Query

    You can't directly edit the arguments for the main query in your archive file. Instead you need to use the pre_get_posts hook to do this. Open your functions.php file (or create one if you don't have one already) and add something like this:

    You'll see here that there are three conditional tags being used: one to check we're not in the admin screens, another to check that it's the main query running and a third to check if we're on an archive page for this post type. The conditional tag you use for your post type (or category, or whatever) can be found in the WordPress Codex.

    Save your functions file and you'll find that your first post is output using your custom loop and then subsequent posts are output via the standard loop.

    Note: This method can sometimes break pagination. If this happens to you, follow these guidelines.

    WP_Query Lets You Highlight Your Most Recent Post

    By using this technique, you can use the WP_Query class to display extra content for your most recent post, or to style it differently. As you'll see from my example, I've used it to make my most recent book stand out from the others.

    You can apply this to a loop you've created using the WP_Query class to to the standard loop in your theme template file – whichever you're using. Once you've done it, your most recent post will stand out and attract your readers' attention.


    Source: How to Use the WordPress Loop to Style Your First Post Differently

    No comments:

    Post a Comment