Practical WordPress Development

How To Get a Page’s Permalink By Slug

If you’re used to working with The Loop, then you’re all too familiar with the_permalink. Simply put, it’s how to get the link to the post currently being rendered in the browser.

But if you’re working on anything more advanced than using the typical Loop, then you may be looking to get the permalink for a post by other means – perhaps by a page slug or by a page’s title.

I’ve had to do this in some recent work, as well, so here’s what I do when I need to get permalink by slug:

Get Permalink By Slug

If you’re looking to get the permalink by the slug, then you need to know two things:

  • A page’s slug is usually the post name unless you’ve done something else programmatically. Review this Codex article for more information.
  • The get_permalink function can accept an ID or an actual object. I’m a fan of passing the ID. I think it makes for cleaner code when comparing it to the Codex documentation.

So with that said, let’s assume that there’s a page that has the slug: “Register For This Site.” Since the slug is often the page’s title, we can write the following function:

function theme_get_permalink_by_title( $title ) {

    // Initialize the permalink value
    $permalink = null;

    // Try to get the page by the incoming title
    $page = get_page_by_title( strtolower( $title ) );

    // If the page exists, then let's get its permalink
    if( null != $page ) {
        $permalink = get_permalink( $page->ID );
    } // end if

    return $permalink;

} // end theme_get_permalink_by_title
You can then interact with this function by doing the following. Remember “Register For This Site” is the name of the page:
if( null == theme_get_permalink_by_title( 'Register For This Site' ) ) {
  // The permalink doesn't exist, so handle this however you best see fit.
} else {
  // The page exists, so do what you need to do.
} // end if/else

Although we’re technically getting the page’s permalink by its slug, the slug is often synoymous with the page’s title so I tend to prefer to write my functions so they are a bit more readable – title seems to be a bit clearer than slug.

Notice also that I’m performing a strtolower within the theme_get_permalink_by_title function. WordPress will handle the case when it’s lowercase and I always find it a best practice to normalize whatever input the user has provided given the function.


  1. Maor Chasen

    Nice trick, Tom!

    Although I suspect there might be a problem with that in some scenarios. For instance, I have clients who run WordPress installations in Hebrew. When you save a post in Hebrew, usually the slug will also be in Hebrew unless you specify it manually.

    And that works the same in many other languages, I’ve also seen that happen with Korean (notice the slug).

    Since not all languages have lower case and upper case letters (Hebrew doesn’t for example), strtolower doesn’t play a role in these cases. I have researched this a little more and it seems that sanitize_title_with_dashes() does some UTF-8 checks using a WordPress core function named seems_utf8(), and changes the slug. Seems to me that using sanitize_title_with_dasheswill do the job just fine for all languages, so using that function, you might be on the safe side.

    I should also note that when looking into sanitize_title()‘s code, I have noticed it is using a function called remove_accents() that seems to also check fot UTF-8 strings and turn them into readable slugs. So basically those two functions should be pretty similar by the output they produce.

    P.S. — seems like there’s a typo in your function. Looks like theme_get_permalink_by_title accepts a variable named $title, then suddenly it becomes $slug.

    • Tom McFarlin

      Perfect – thanks for this comment. Beyond simply localizing themes and plugins, I’ve not really dealt with international languages so this is great to know.

      Definitely gonna make sure to note this.

      Also .. typo resolved. Nice catch ;).

Leave a Reply

© 2020 Tom McFarlin

Theme by Anders NorenUp ↑