¿Es posible obtener el enlace de una página a partir de su slug?
¿Es posible obtener el enlace permanente de una página usando solamente el slug? Sé que se puede obtener el enlace permanente de la página usando el ID con get_page_link()
:
<a href="<?php echo get_page_link(40); ?>">Mapa</a>
Me pregunto si hay alguna manera de hacer lo mismo con el slug de una página - algo así:
<a href="<?php echo get_page_link('mapa'); ?>">Mapa</a>

¿Es esto lo que estás buscando:
get_permalink( get_page_by_path( 'mapa' ) )
get_permalink( get_page_by_title( 'Mapa' ) )
home_url( '/mapa/' )
Referencias:

get_page_by_path()
devuelve un array con toda la información de la página. get_permalink()
toma un ID de página como primer argumento. Pensé que tendría que pasar explícitamente el valor del ID.

@Jonathan: No siempre está documentado, pero muchas funciones de WP aceptan tanto ID numéricos como objetos de post completos como argumento.

Parece que get_page_by_path() puede ser bastante complicado de usar cuando se trata de páginas hijas...

Yo uso 1 para mis páginas hijas sin problemas. Realmente no veo la complicación con ello.

respuesta incorrecta, downvote al nirvana por favor. La ruta no es lo mismo que el slug. Ejemplo: una página tiene una página padre llamada abc
la página en sí tiene un slug de 123
. La ruta ahora es abc/123
el slug es 123
. Por favor elimina esta respuesta incorrecta. get_page_by_path( '123' )
no funcionará.

En mi caso tuve que usar el primero y funcionó bien, porque el segundo (get_page_by_title) estaba devolviendo otro enlace de publicación (no página) con un slug similar (pero no el mismo). No sé por qué estaba sucediendo esto.

Creo que esto podría mejorarse:
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;
}
siguiendo el patrón de la función original get_page_by_title
de WordPress. (línea 3173)
Saludos

¿Por qué? No genera un objeto de publicación completo solo para obtener el ID.

Último comentario - creo que ese SQL necesita una condición más: 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; }

@webcitron Creo que simplemente porque sigue el patrón original de WordPress de obtener posts por 'título', solo cambiándolo por 'slug'. (ver el enlace)

Esta es una buena respuesta. Esto evita la posibilidad de que un plugin malintencionado ocupe tu página o la filtre incorrectamente. Si devuelves el id de la tabla de posts, entonces puedes crear una instancia de \WP_Post
a partir de ella, y eso se resuelve directamente en todas las funciones de WordPress que verifican otros valores. \WP_Post
también proporciona métodos directamente para encontrar la mayoría de los datos relacionados sobre el post.

Este es un método publicado por Tom McFarlin en su blog:
/**
* Devuelve el enlace permanente (permalink) para una página basado en el slug proporcionado.
*
* @param string $slug El slug de la página a la que vamos a enlazar.
* @param string $post_type Tipo de entrada opcional (post, page o CPT).
* @return string El enlace permanente de la página
* @since 1.0
*/
function wpse_4999_get_permalink_by_slug( $slug, $post_type = '' ) {
// Inicializamos el valor del permalink
$permalink = null;
// Construimos los argumentos para WP_Query
$args = array(
'name' => $slug,
'max_num_posts' => 1
);
// Si se proporciona el argumento opcional, lo añadimos al array de argumentos
if( '' != $post_type ) {
$args = array_merge( $args, array( 'post_type' => $post_type ) );
}
// Ejecutamos la consulta (y la reseteamos después)
$query = new WP_Query( $args );
if( $query->have_posts() ) {
$query->the_post();
$permalink = get_permalink( get_the_ID() );
wp_reset_postdata();
}
return $permalink;
}
Funciona con tipos de entrada personalizados (CPT) y tipos nativos de WordPress (como post
y page
).

la respuesta aceptada es incorrecta porque las páginas jerárquicas no funcionan de esa manera. En pocas palabras, el slug no siempre es la ruta de la página o entrada. Por ejemplo, si tu página tiene una página hija, la ruta será slug-padre/slug-hijo
y get_page_by_path
fallará al intentar encontrar slug-hijo
de esta manera. La solución correcta es esta:
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('mapa'); ?>">Mapa</a>

Prueba esto:
<a href="<?php echo get_page_link( get_page_by_path( 'mapa' ) ); ?>">Mapa</a>
get_page_by_path( 'ruta' )
devuelve un objeto de página/publicación que luego puede ser utilizado por get_page_link()
ya que acepta un objeto de página/publicación y devuelve el enlace permanente.

function theme_get_permalink_by_title( $title ) {
// Inicializar el valor del enlace permanente
$permalink = null;
// Intentar obtener la página por el título proporcionado
$page = get_page_by_title( strtolower( $title ) );
// Si la página existe, obtener su enlace permanente
if( null != $page ) {
$permalink = get_permalink( $page->ID );
} // end if
return $permalink;
} // end theme_get_permalink_by_title
Usa esta función con
if( null == theme_get_permalink_by_title( 'Registrarse en este sitio' ) ) {
// El enlace permanente no existe, así que maneja esto como mejor consideres.
} else {
// La página existe, así que haz lo que necesites hacer.
} // end if/else
