110

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>
176

You're talking about Pages right? Not Posts.

Is this what you looking for:

  1. get_permalink( get_page_by_path( 'map' ) )
  2. get_permalink( get_page_by_title( 'Map' ) )
  3. home_url( '/map/' )
  • 4
    Did you mean get_permalink(get_page_by_path('contact')->ID));? – Sampson Dec 7 '10 at 22:22
  • 1
    hmmm nope? What's with the ID? – zeo Dec 8 '10 at 1:52
  • 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. – Sampson Dec 8 '10 at 4:47
  • 10
    @Jonathan: It's not always documented, but many WP functions accept both numeric ID's and full post objects as the argument. – Jan Fabry Dec 8 '10 at 7:18
  • 1
    It seems that get_page_by_path() can be quite complicated to use when dealing with child pages... – Kaaviar Nov 14 '11 at 14:57
9

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

  • 11
    Why would that be better? Can you explain? – julien_c Apr 11 '12 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; } – user25790 Jan 9 '13 at 14:27
  • Why? It doesn't generate a complete post object just to get the ID. – s_ha_dum Jan 9 '13 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) – Matheus Eduardo May 13 '13 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. – mopsyd Mar 23 '18 at 3:53
6

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).

2

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>
1

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
    Please edit your answer, and add an explanation: why could that solve the problem? – fuxia Feb 26 '18 at 13:27
0
    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

protected by Community Feb 26 '18 at 12:00

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.