WordPress Get Latest Post URL Function

Recently I have been getting into the core workings of WordPress, both for my own ends with my recent plugin “WP-Blocks” and for the work I have been doing helping Mike out with the redesign of his site.

Developers never like repeating themselves (DRY is king, right?) and so when prompted with an interesting use case I decided to have a look at a few of the WordPress internals to see if they could help me out.

The Use Case

Mike’s new site includes a very simple blog. There are no tags and no categories, only posts and a simple archive page. When clicking on the main blog link in the navigation Mike wants the latest post to appear. Just for reference his portfolio page is the “home page” and the blog effectively an inner page of the site.

I had already coded up the single.php page and the custom archive page. After a chat with Mike I was reminded that he always wanted the blog tab to show just the latest post complete with the comments.

As the blog isn’t the main focus of the site I wanted to avoid having another custom page at, let’s say, /blog and then further pages for the archive and the actual post itself i.e.

This didn’t appear very DRY to me as it would entail having a virtually identical single.php (bear in mind I am not using the traditional WordPress index.php) with a slightly different query just to show the latest post.

My Solution

Being lazy I thought the simplest way would be to work with what I have and direct the /blog navigation tab to the latest post. I came up with a couple of ways of doing this:

  1. Create a custom page at /blog that works out the latest post and redirects
  2. Create a function that works out the latest post and plumbs in that URL to the /blog navigation tab

I decided that the second approach would be easier.

I knew that I was able to get the latest posts using the wp_get_archives function, the only snag here being that this is echo’d to the browser. Closer inspection of the function revealed a call to get_permalink (located in link-template.php) which returns the URL of a page or post for a given ID.

Therefore all I needed to do is get the latest published post ID from the database and pass it to get_permalink to retrieve the latest posts URL for use in the navigation.

The Function

I added the following to my themes functions.php file.

1
2
3
4
5
6
7
8
9
10
function get_laterst_post_url() {
  global $wpdb;
  $query = "SELECT ID FROM {$wpdb->prefix}posts WHERE post_type='post' AND post_status='publish' ORDER BY post_date DESC LIMIT 1;";
  $result = $wpdb->get_results($query);
  if(is_object($result[0])) {
    return get_permalink($result[0]->ID);
  } else {
    return '';
  };
}

It’s a simple enough function but it works. Here’s what’s happening:

  1. Declare the $wpdb (WordPress data access class) as global
  2. Create a SQL query to retrieve the latest published post and limit the result to one record
  3. Query the database using $wpdb->get_results($query); and assign it to the variable $result
  4. Next I wanted to check that I actually had a result before using get_permalink()
  5. get_results($query) will return an array of stdClass objects. Given that we only asked for one record to be returned we can do a quick check to see that the first array element (i.e. $result[0]) is an object. If the check returns TRUE then we can safely assume we have a record to use.
  6. We then pass the ID to get_permalink and return the value
  7. If it isn’t an object we return an empty string

This seems to do the trick although there maybe more efficient ways of achieving the same result.

The Navigation Template

Any function available placed in your themes function.php file is available in your templates. Here’s how I use it for Mike’s site:

1
2
3
4
5
6
7
8
9
10
11
12
<ul class="mainNav">
<li><a class="portfolio" href="/">Portfolio</a></li>
<?php 
$url = get_laterst_post_url();
if($url != ''): 
?>
<li><a class="blog" href="<?php echo $url; ?>">Blog</a></li>
<?php endif; ?>
<li><a class="photos" href="/photos/">Photos</a></li>
<li><a class="email" href="mailto:mike@mikekus.com">Email me</a></li>
<li><a class="twitter" href="http://twitter.com/mikekus">Twitter</a></li>
</ul>

This should be pretty straightforward, all I am doing is assigning the return value from get_laterst_post_url to a variable and checking to see if it is not an empty string. Only if I have a string do I show the /blog list item and echo out the $url variable for the anchor.

I could have used the ternary operator to return HTML in this instance but I prefer to keep the PHP logic and template code as separate as possible, although I do agree it is far from a perfect solution.

This now means that the latest post is always available via the /blog navigation tab. Yes it’s an extra query but it seems like a pragmatic approach to the problem. Using one of the many available cache plugins would help and is recommended.

Thoughts?

I would be interested to know if any of the WordPress hackers out there have a better/different way of achieving the same result.

9 Comments

This is awesome, and I’m looking for the solution to get the latest post url.

I don’t know what I should say to express my gratitude, but thanks!

Hi All,

First of all i am not really PHP expert.

I am working on a blog website.

On home page they are looking for recent post to show up.
on archive page it should be all the collection.

I was wondering is there any how i can make categories to get data from recent post (which is on the home page) also same content on the archive.

Please see:

http://postimage.org/image/bm7ugu9wj/

Here is how i am thinking of getting post from archive and showing it on home page.

Please give me any help will be appreciated.

Thank you.

YES! This worked like a charm and solved a big problem for me, thanks so much!

I tried to adapt the script to show the single.php of a spefic category, but i have failed. any idea?

Hey Franz – Which template are you using for this, category.php? There should be a way, let me know and I’ll have a think.

Hi,
Thanks for this great article! It all works fine, but how can I do if i want to put the link into a Menu ?
Thanks

A lot of business as people have hired them and they are
being paid down. But what if you have a lot of misconception about this plan and we hope to
dissolve and clear up any questions that those in extreme debt have.

Perfect, works like a charm. Thank you very much.