¿Cómo obtengo el slug de la página actual?

13 feb 2012, 06:25:46
Vistas: 569K
Votos: 140

Estoy intentando obtener el slug de la página actual de WordPress fuera del loop. El título de la página se obtiene con wp_title(), pero ¿cómo puedo obtener el slug?

<li>
  <a href="/slug-de-pagina-actual/">
    <?php wp_title('', true); ?>
  </a>
</li>
0
Todas las respuestas a la pregunta 12
6
223

Utiliza la variable global $post:

<?php 
    global $post;
    $post_slug = $post->post_name;
?>
13 feb 2012 08:27:21
Comentarios

Gracias. Tu solución funciona muy bien. Solo necesitas hacer echo del slug: <?php global $post; $post_slug=$post->post_name; echo $post_slug; ?>

sarytash sarytash
13 feb 2012 14:13:52

Como dijo sarytash, necesitas usar echo. Entonces, esto sería lo ideal: <?php global $post; echo $post->post_name; ?>

its_me its_me
11 oct 2013 18:59:35

¿Qué hay de $WP_Post?

Peter Mortensen Peter Mortensen
24 abr 2019 16:00:07

No funcionará si estás, por ejemplo, en yourpage.com/search si esta no es una página existente sino una reescritura desde ?s=

trainoasis trainoasis
14 oct 2020 15:55:19

¿no es post_name el título legible por humanos (incluyendo espacios en blanco) en lugar del slug?

abinmorth abinmorth
7 jul 2021 20:01:57

@abinmorth no, ese es post_title.

Gavin Gavin
13 sept 2022 17:56:18
Mostrar los 1 comentarios restantes
6
113

Como se indica en otras respuestas, el slug se almacena en la propiedad post_name. Si bien se podría acceder directamente, prefiero la función (poco utilizada) get_post_field() para acceder a las propiedades de la entrada que no tienen una API específica para ellas.

Requiere que la entrada se proporcione explícitamente y no toma por defecto la entrada actual, así que para la entrada actual sería así:

$slug = get_post_field( 'post_name', get_post() );
21 may 2015 00:10:06
Comentarios

Vale la pena señalar que si estás dentro del loop puedes usar get_post_field sin el segundo argumento (documentación)

jmarceli jmarceli
16 jun 2016 09:42:13

Pequeña nota: He estado usando este método en aproximadamente 8 sitios web diferentes con mi plugin, pero falló al recuperar el slug de página correcto en el último sitio web donde instalé el plugin. Los temas u otros plugins probablemente alteraron la referencia correcta al objeto $post, resultando en el slug incorrecto del post. De todos modos, la respuesta de @Pieter Goosen solucionó este problema para mí: https://wordpress.stackexchange.com/a/188945/150100

Vasco Vasco
19 oct 2020 13:07:39

Esta debería ser la respuesta aceptada

Lovor Lovor
17 feb 2021 15:13:03

Es probablemente obvio, pero también quiero agregar que el segundo argumento puede ser un ID de entrada también.

Gavin Gavin
20 jun 2021 08:57:04

¡sí, esta o la respuesta de Pieter debajo debería ser la respuesta aceptada! ¿por qué? ... si globalizas $post en una función y luego inadvertidamente le asignas un valor... acabas de sobrescribir el $post global que podría romper el código subsiguiente... es mejor usar este ejemplo o get_queried_object()->post_name

aequalsb aequalsb
29 jul 2021 21:15:39

Esto no funciona en ciertos casos. Por ejemplo, creé una página de blog. Para esta página, $slug devolvió el enlace permanente de la primera entrada del blog en lugar de 'blog' que era lo que esperaba. Apoyo el uso de get_queried_object()->post_name.

Andrew Andrew
29 sept 2022 05:11:08
Mostrar los 1 comentarios restantes
1
40

EDICIÓN 5 ABRIL 2016

Después de investigar más sobre la fiabilidad, terminé haciendo esta respuesta a la siguiente publicación que lleva a esta edición: (Asegúrate de revisarla)

El método más fiable hasta la fecha que pude encontrar es el siguiente:

// Obtener el objeto consultado y limpiarlo
$current_page = sanitize_post( $GLOBALS['wp_the_query']->get_queried_object() );
// Obtener el slug de la página
$slug = $current_page->post_name;

De esta manera, tienes un 99.9999% de seguridad de obtener los datos correctos cada vez.

RESPUESTA ORIGINAL

Otra alternativa más segura para este problema es usar get_queried_object() que contiene el objeto consultado actual para obtener el slug de la página que está contenido en la propiedad post_name. Esto se puede usar en cualquier parte de tu plantilla.

Se puede usar $post, pero puede no ser fiable ya que cualquier consulta personalizada o código personalizado puede cambiar el valor de $post, por lo que debe evitarse fuera del loop.

Usar get_queried_object() para obtener el objeto de la página actual es mucho más fiable y es menos probable que se modifique, a menos que estés usando el malvado query_posts que rompe el objeto de consulta principal, pero eso ya depende de ti.

Puedes usar lo anterior de la siguiente manera

if ( is_page() )
    $slug = get_queried_object()->post_name;
21 may 2015 10:00:26
Comentarios

Debo decir que query_posts no es malvado cuando quieres alterar la consulta principal, que sin embargo usualmente no necesitas y es frecuentemente mal utilizado :)

jave.web jave.web
3 mar 2018 23:12:37
4
26

La forma simple de obtener el slug es con:

<?php 
// Obtener el slug de la URL actual
echo basename(get_permalink()); 
?>
25 sept 2015 02:26:22
Comentarios

esto depende de la configuración de los enlaces permanentes. Si usas la configuración "simple", los enlaces se verán como http://domain/?p=123, dejándote con ?p=123.

Mene Mene
14 oct 2016 13:36:28

@Mene es cierto, pero la pregunta es cómo obtener el slug que, usualmente, significa que hay uno en la url (el argumento GET p no es un slug).

jave.web jave.web
17 feb 2020 13:43:59

Esta es una línea de código tan elegante :D

Sean Doherty Sean Doherty
13 mar 2020 17:46:13

Bien, muy bien :)

Chaoley Chaoley
21 oct 2020 06:46:47
1

Dado el ejemplo de código, parece que lo que realmente necesitas es un enlace. En ese caso, puedes usar get_permalink(), que se puede utilizar fuera del bucle. Esto debería hacer lo que necesitas de manera más confiable que usar el slug del post.

13 feb 2012 06:55:40
Comentarios

Esta es la URL completa, no solo el slug.

Fred Fred
21 nov 2014 17:09:20
0

Puede que sea una pregunta antigua, pero creé las funciones get_the_slug() y the_slug() basadas en sus respuestas.

if ( !function_exists("get_the_slug") ) {
    /**
    * Devuelve el slug de la página o entrada.
    *
    * @param int|WP_Post|null $id (Opcional) ID de la entrada o objeto post. Por defecto usa la variable global $post.
    * @return string
    */
    function get_the_slug( $id = null ){
        $post = get_post($id);
        if( !empty($post) ) return $post->post_name;
        return ''; // No hay variable global $post o ID correspondiente disponible.
    }
    /**
    * Muestra el slug de la página o entrada
    *
    * Utiliza get_the_slug() y aplica el filtro 'the_slug'.
    *
    * @param int|WP_Post|null $id (Opcional) ID de la entrada o objeto post. Por defecto usa la variable global $post.
    */
    function the_slug( $id=null ){
        echo apply_filters( 'the_slug', get_the_slug($id) );
    }
}
29 ago 2017 12:09:01
1

Puedes simplemente separar el slug de la solicitud.

global $wp;
// Como los slugs por sí mismos no pueden contener barras diagonales,
// vamos a separar por barras y obtener solo la última parte.
$request_args = explode('/', $wp->request);
$current_slug = end($request_args);

// Dada la URL https://example.com/foo/bar/foo-bar
if ($current_slug === 'foo-bar') {
  // la condición coincidirá.
}

Esto funciona para todas las entradas, páginas y rutas personalizadas.

9 abr 2019 11:56:12
Comentarios

Esta es la mejor respuesta a esta pregunta - nada funcionó hasta que probé esto.

Chris Chris
15 ago 2020 00:20:31
1

Esta es la función a utilizar cuando se desea obtener el slug fuera del loop.

get_post_field( 'post_name');

Respuesta encontrada aquí: ¿Cómo obtener el slug de la página actual en WordPress?

24 nov 2018 18:03:12
Comentarios

Efectivamente, pero necesitas pasar $post o el ID de la entrada como segundo argumento.

trainoasis trainoasis
17 oct 2019 14:29:42
0

Si deseas una respuesta más detallada del funcionamiento interno, puedes usar la siguiente consulta SQL para obtener todas las entradas que son posts, páginas o taxonomías personalizadas en cualquier momento, incluso si no se han activado hooks hasta el momento.

SQL en bruto:


SELECT `id`, `post_type` AS `type`, `post_author` AS `author`, `post_name` AS 
`slug`, `post_status` AS `status`
FROM wp_posts 
WHERE `post_type` NOT IN ('attachment', 'nav_menu_item', 'revision')
AND `post_status` NOT IN ('draft', 'trash')
ORDER BY `id`;

Esto funciona incluso en la primera línea de tu archivo functions.php, incluso antes de los hooks mu_plugins_loaded o init.

@nota

Esto asume que tienes un prefijo de base de datos estándar wp_posts. Si necesitas tener en cuenta prefijos variables, puedes obtener la tabla de posts correcta a través de PHP fácilmente haciendo lo siguiente:

<?php
global $wpdb;
$table = $wpdb->posts;
$query = "SELECT `id`, `post_type` AS `type`, `post_author` AS `author`, `post_name` AS 
`slug`, `post_status` AS `status`
FROM " . $table . "
WHERE `post_type` NOT IN ('attachment', 'nav_menu_item', 'revision')
AND `post_status` NOT IN ('draft', 'trash')
ORDER BY `id`;"

Luego ejecuta con $wpdb, mysqli, o una instancia de PDO. Como no hay entrada de usuario en esta consulta, es seguro ejecutarla sin una declaración preparada siempre que no inyectes ninguna variable en ella.

Sugiero almacenar esto como un valor estático privado de una clase, para que se pueda acceder sin tener que ejecutar la consulta más de una vez por página para un mejor rendimiento, algo como esto:

class Post_Cache
{
    private static $post_cache;

    public function __construct()
    {
        //De esta manera se omite la operación si ya está establecida
        $this->initCache();
    }

    public function get($id, $type = null)
    {
        if ( !(is_int( $id ) && array_key_exists( $id, self::$post_cache ) ) )
            return false;
        }
        if ( !is_null( $type ) )
        {
            //devuelve el valor específico de la columna para el id
            return self::$post_cache[$id][$type];
        }
        //devuelve la fila completa
        return self::$post_cache[$id];
    }

    private function initCache()
    {
        if ( is_null(self::$post_cache) )
        {

            $query = "...";
            $result = some_query_method($query); //Realiza tu lógica de consulta aquí
            self::$post_cache = $result;
        {
    }
}

Uso

$cache = new \Post_Cache();

//Obtener el slug de la página
$slug = $cache->get( get_the_ID(), 'slug');

if ($cache->get( get_the_ID() ))
{
    //la entrada existe
} else {
    //no existe, mostrar 404
}
if ( $cache->get( get_the_ID(), 'status') === 'publish' )
{
    //es público
} else {
    //verificar current_user_can('whatever_permission') o simplemente mostrar 404,
    //dependiendo si quieres que sea visible para el usuario actual o no
}
if ( $cache->get( get_the_ID(), 'type') === 'post' )
{
    //Es una entrada
}
if ( $cache->get( get_the_ID(), 'type') === 'page' )
{
    //Es una página
}

Ya entiendes la idea. Si necesitas más detalles, puedes obtenerlos normalmente con new \WP_Post( get_the_ID() );


Esto te permitirá verificar las entradas en cualquier momento, incluso si el bucle de WordPress no ha llegado a un punto donde encuentre tu solicitud aceptable. Esta es una versión ligeramente más optimizada de la misma consulta ejecutada por el núcleo de WordPress. Esta filtra todo el contenido innecesario que no querrías que se devolviera, y te da una lista bien organizada con el ID del autor relevante, tipo de entrada, slug y visibilidad. Si necesitas más detalles, puedes obtenerlos normalmente con new \WP_Post($id);, o usar cualquiera de las otras funciones nativas de WordPress con cualquiera de las filas de tabla relevantes, incluso fuera del bucle.

Uso una configuración similar en algunos de mis propios temas y plugins personalizados, y funciona muy bien. También es seguro y no deja datos internos flotando en el ámbito global donde pueden ser sobrescritos como lo hace la mayoría de las cosas en WordPress.

23 mar 2018 03:43:49
0

Si estás dentro del bucle entonces las otras respuestas te ayudarán. Si no lo estás (por ejemplo, si estás usando los hooks init o plugins_loaded) puedes recurrir a una función primitiva de PHP como parse_url().

Aquí hay una función que funciona en ambos casos:

function get_the_slug() {
    global $post;
    // Intentamos obtener el slug del post actual
    $slug = $post->post_name ?? '';

    // Si no hay slug, lo extraemos de la URL
    if ( ! $slug ) {
        $slug = basename( parse_url( $_SERVER['REQUEST_URI'] ?? '', PHP_URL_PATH ) );
    }

    return $slug;
}

Ten en cuenta que este enfoque solo funciona en entradas/páginas en el nivel raíz, debido a cómo funciona basename().

10 nov 2021 12:53:48
0

Siguiendo la respuesta de @Matthew Boynes, si estás interesado en obtener también el slug del padre (si existe), he encontrado útil esta función:

// Función para obtener los slugs incluyendo el padre
function mytheme_get_slugs() {
    if ( $link = get_permalink() ) {
        // Remueve la URL base del sitio
        $link = str_replace( home_url( '/' ), '', $link );
        // Verifica si hay una barra al final y la elimina
        if ( ( $len = strlen( $link ) ) > 0 && $link[$len - 1] == '/' ) {
            $link = substr( $link, 0, -1 );
        }
        // Divide la URL en segmentos por las barras
        return explode( '/', $link );
    }
    return false;
}

Por ejemplo, para agregar el/los slug(s) a la clase del body:

// Función para añadir los slugs a las clases del body
function mytheme_body_class( $classes ) {
    if ( $slugs = mytheme_get_slugs() ) {
        // Combina las clases existentes con los slugs
        $classes = array_merge( $classes, $slugs );
    }
    return $classes;
}
add_filter( 'body_class', 'mytheme_body_class' );
12 feb 2015 18:33:31
0
-1

Llamada dinámica de páginas en WordPress.

<?php
    // Obtiene la parte de la plantilla basándose en el nombre base de la URL actual
    get_template_part('foldername/'.basename(get_permalink()),'name');
    ?>
14 feb 2017 06:05:44