150

Is it possible to get a page's permalink from the slug alone? I'm aware that you can get the page's permalink from the ID using get_page_link():

<a href="<?php echo get_page_link(40); ?>">Map</a> 

I'm curious if there is any way to do the same with the slug of a page - like this:

<a href="<?php echo get_page_link('map'); ?>">Map</a> 
2
  • You can also use: site_url('page-slug') Commented Jan 13, 2021 at 7:19
  • Please note that many of the answers are confusing a post's slug (the post_name column in the wp_posts database table) for a post's title, which is different. It's also different from a post's path (especially noticeable when using hierarchical paths or when two posts of different post types share the same slug). Commented Jul 14, 2022 at 11:41

7 Answers 7

238

Is this what you are looking for:

  • get_permalink( get_page_by_path( 'map' ) )
  • get_permalink( get_page_by_title( 'Map' ) )
  • home_url( '/map/' )

References:

11
  • 5
    Did you mean get_permalink(get_page_by_path('contact')->ID));? Commented Dec 7, 2010 at 22:22
  • 3
    get_page_by_path() returns an array of all page information. get_permalink() takes a page ID as the first argument. I thought I'd have to explicitly pass the ID value. Commented Dec 8, 2010 at 4:47
  • 13
    @Jonathan: It's not always documented, but many WP functions accept both numeric ID's and full post objects as the argument. Commented Dec 8, 2010 at 7:18
  • 2
    It seems that get_page_by_path() can be quite complicated to use when dealing with child pages... Commented Nov 14, 2011 at 14:57
  • 4
    wrong answer, downvote to nirvana please. The path is not the same like the slug. Example: a page has a parent page called abc the page itself has a slug of 123. The path now is abc/123 the slug is 123. Please remove this wrong answer. get_page_by_path( '123' ) wont work. Commented Sep 1, 2017 at 22:03
11

I think this could be better:

function get_page_by_slug($page_slug, $output = OBJECT, $post_type = 'page' ) { global $wpdb; $page = $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_name = %s AND post_type= %s", $page_slug, $post_type ) ); if ( $page ) return get_page($page, $output); return null; } 

following the pattern of "original" get_page_by_title of wordpress. (line 3173)

rgds

5
  • 11
    Why would that be better? Can you explain? Commented Apr 11, 2012 at 13:11
  • Last comment - I think that sql needs to have one more condition: function get_page_by_slug($page_slug, $output = OBJECT, $post_type = 'page' ) { global $wpdb; $page = $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_name = %s AND post_type= %s AND post_status = 'publish'", $page_slug, $post_type ) ); if ( $page ) return get_page($page, $output); return null; } Commented Jan 9, 2013 at 14:27
  • Why? It doesn't generate a complete post object just to get the ID. Commented Jan 9, 2013 at 14:53
  • @webcitron I think just because is following original pattern of Wordpress getting post by 'title', just changing for 'slug'. (check the link) Commented May 13, 2013 at 11:08
  • This is a good answer. This bypasses the possiblity of a rogue plugin masking your page or incorrectly filtering it. If you return the id from the post table, then you can create an instance of \WP_Post from it, and that resolves directly in all of the wordpress functions that check for other values. \WP_Post also provides methods directly to find most related data about the post. Commented Mar 23, 2018 at 3:53
8

This is a method published by Tom McFarlin on his blog:

/** * Returns the permalink for a page based on the incoming slug. * * @param string $slug The slug of the page to which we're going to link. * @return string The permalink of the page * @since 1.0 */ function wpse_4999_get_permalink_by_slug( $slug, $post_type = '' ) { // Initialize the permalink value $permalink = null; // Build the arguments for WP_Query $args = array( 'name' => $slug, 'max_num_posts' => 1 ); // If the optional argument is set, add it to the arguments array if( '' != $post_type ) { $args = array_merge( $args, array( 'post_type' => $post_type ) ); } // Run the query (and reset it) $query = new WP_Query( $args ); if( $query->have_posts() ) { $query->the_post(); $permalink = get_permalink( get_the_ID() ); wp_reset_postdata(); } return $permalink; } 

It works with custom post types and built-in post types (such as post and page).

1
  • In Wordpress 6.4.2, I needed to use post_name instead of name in the query $args Commented Jan 12, 2024 at 17:56
4

the accepted answer is wrong because hierarchical pages don't work like that. Simply put, the slug is not always the path of the page or post. E.g. your page has a child etc. the path will be parent-slug/child-slug and get_page_by_path will fail to find child-slug this way. The proper solution is this:

function mycoolprefix_post_by_slug($the_slug, $post_type = "page"){ $args = array( 'name' => $the_slug, 'post_type' => $post_type, 'post_status' => 'publish', 'numberposts' => 1 ); $my_page = get_posts($args)[0]; return $my_page; } <a href="<?php echo mycoolprefix_post_by_slug('map'); ?>">Map</a> 
4

Try This:

<a href="<?php echo get_page_link( get_page_by_path( 'map' ) ); ?>">Map</a> 

get_page_by_path( 'path' ) returns page/post object which can be then used by get_page_link() as it accepts post/page object and returns permalink.

2
  • 2
    Please edit your answer, and add an explanation: why could that solve the problem? Commented Feb 26, 2018 at 13:27
  • 1
    Note that the path is not the same as the slug, necessarily. Commented Jul 14, 2022 at 11:39
-1
 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 

Use this function by

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 
1
  • The title is not the same as the slug. Commented Jul 14, 2022 at 11:39
-1

A little late, but kind of...

You can do this:
<?php $map = get_page_by_title( 'map' ); ?>
<a href="<?php echo get_page_link('$map->ID'); ?>">Map</a>

That's how I do it :-)

Thanks,
Josh

1
  • The title is not the same as the slug. Commented Jul 14, 2022 at 11:39

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.