When building out a custom “Blog” section for your WordPress site, sometimes it’s easiest to create a custom page template that you can customize that allows you to set the page location (such as https://upthemes.com/blog), as well as your very own title and description that are displayed at the top of the blog section.
Step 1. Copy index.php to tpl_blog.php
To start, copy your index.php file from your current theme and rename the copied file tpl_blog.php. The reason for this is to get an exact copy of the theme functions and HTML structure from your current theme and to create a page template that will eventually be selectable from the ‘Page Template’ dropdown.
Step 2. Create Page Template ID
In your new file tpl_blog.php, you need to add a special comment to the top of the file that WordPress will recognize as a custom template.
/*
Template Name: Blog Posts
*/
Simply add that to the very top of your page and now WordPress will recognize it in the Edit Page screen sidebar.
3. Use Custom Query for Posts
Place this below the get_header() template tag:
<?php query_posts('post_type=post&post_status=publish&posts_per_page=10&paged='. get_query_var('paged')); ?>
This will override the current page query with a custom query for 10 paginated blog posts. Since we’re using query_posts()
, we don’t need to generate a new custom WP_Query
to store the custom query.
4. Add Navigational Links for Pagination
Below your post loop, add some links for pagination like so:
<div class="navigation">
<span class="newer"><?php previous_posts_link(__('« Newer','example')) ?></span> <span class="older"><?php next_posts_link(__('Older »','example')) ?></span>
</div><!-- /.navigation -->
This should be between the endwhile;
and endif;
sections of code in your theme.
5. Reset the Query
Once you’ve output all your posts and navigation, you can use wp_reset_query()
to reset the query_posts()
results that you created earlier. In lamens terms, you’ve now reset the query to what it was before you called query_posts()
.
6. Putting it all together
Here’s a completed page template that utilizes everything described above with additional markup and includes the loop:
<?php get_header(); ?>
<div id="content">
<?php query_posts('post_type=post&post_status=publish&posts_per_page=10&paged='. get_query_var('paged')); ?>
<?php if( have_posts() ): ?>
<?php while( have_posts() ): the_post(); ?>
<div id="post-<?php get_the_ID(); ?>" <?php post_class(); ?>>
<a href="<?php the_permalink(); ?>"><?php the_post_thumbnail( array(200,220) ); ?></a>
<h2><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>
<span class="meta"><?php author_profile_avatar_link(48); ?> <strong><?php the_time('F jS, Y'); ?></strong> / <strong><?php the_author_link(); ?></strong> / <span class="comments"><?php comments_popup_link(__('0 comments','example'),__('1 comment','example'),__('% comments','example')); ?></span></span>
<?php the_excerpt(__('Continue reading »','example')); ?>
</div><!-- /#post-<?php get_the_ID(); ?> -->
<?php endwhile; ?>
<div class="navigation">
<span class="newer"><?php previous_posts_link(__('« Newer','example')) ?></span> <span class="older"><?php next_posts_link(__('Older »','example')) ?></span>
</div><!-- /.navigation -->
<?php else: ?>
<div id="post-404" class="noposts">
<p><?php _e('None found.','example'); ?></p>
</div><!-- /#post-404 -->
<?php endif; wp_reset_query(); ?>
</div><!-- /#content -->
<?php get_footer(); ?>
Ah, a no bs answer, where you bother to show your work rather than regurgitate. Got to love it. A+ man.
Thanks for the tutorial! This could be a really useful template to use in all my themes by default..
Thanks for a great post. I have a problem where “Older” points to blog/page/2 but when you click it, the site stays on blog/ . Any ideas?
Hey!
Thank-you! I’ve been customizing a wordpress website and I detest the blog page layout. I wasn’t sure how to make a template but this tutorial gave me some confidence that it’s possible. It worked but it needs to be edited to look a bit nicer. All the content shows up. It’s a good start though and I appreciate the tutorial.
THANK YOU
I just want to say : I LOVE YOU MAN! you just saved me lots and lots of time and it works brilliant! 😀
Chris, thanks a lot for such a lovely and helpful tutorial. You really saved my day.
Why don’t you remove author_profile_avatar_link(48); on line no 17, since it isn’t by default on all WordPress theme. I tried your code on my TwentyTweleve theme, it worked greatly but I’ve to remove the above mentioned code.
thanks man for info it was really helpful………
ThanKz For The Valuable Information!!
Nice article. Thanks!
Hello,
I did the same steps that you showed. And i changed the template of the page to the template i created, but it’s still showing the posts like the previous template.
Please advise.
Thank you
You’ve missed a question mark when calling the header. It should be
Ok, obviously i can’t post code in my reply!
It should be beging with < ? php
Thank you!
Will this work if I put it in my child theme folder?
Yes, you can put template files in child theme folders.
how to make one for posts not to index page
is it possiple
Thanx …. You are amazing. 🙂
This is great. Thanks! Can we do something similar with a portfolio items?
what would the query for the portafolio items be?
Thanks alot this has proved very useful!
Thank You
I’m so sorry to bother you so long after you posted this!
Worked like a dream for me. So happy! Only question – they are scrolling on the page brilliantly, but clicking the title or post doesn’t go into the individual posts (ie, to leave comments, etc). How can I do that OR get the ability for users to leave comments as they can in the single blog post pages? I’m sure I’m just missing something.
Sorry to be really over the top but the first line is missing the ‘?’
Just thought it might be worth mentioning in case people come just to copy & paste.
Great read, thanks very much for the tutorial!
Thanks for pointing that out. I’ve updated the code sample.