web-dev-qa-db-fra.com

Comment récupérer le slug de la page en cours?

J'essaie de récupérer le slug de la page WordPress actuelle en dehors de la boucle. Le titre de la page revient avec wp_title (), mais comment puis-je obtenir le slug?

<li>
  <a href="/slug-of-current-page/">
    <?php wp_title('', true); ?>
  </a>
</li>
93
sarytash

Utilisez la variable globale $post :

<?php 
    global $post;
    $post_slug = $post->post_name;
?>
147
Arvind Pal

Comme pour d’autres réponses, le slug est stocké dans la propriété post_name. Bien qu’il puisse soit accessible directement, je préfère la fonction (sous-utilisée) get_post_field() pour accéder aux propriétés de publication qui n’ont pas d’API appropriée.

Il faut que le message soit fourni explicitement et qu'il ne corresponde pas au message actuel, il serait donc complet pour le message actuel:

$slug = get_post_field( 'post_name', get_post() );
64
Rarst

EDIT 5 AVRIL 2016

Après avoir cherché plus de fiabilité, je me suis retrouvé avec cette réponse au message suivant qui mène à cette modification: (veillez à bien vérifier)

La méthode la plus fiable à ce jour que je pourrais trouver est la suivante:

// Get the queried object and sanitize it
$current_page = sanitize_post( $GLOBALS['wp_the_query']->get_queried_object() );
// Get the page slug
$slug = $current_page->post_name;

De cette façon, vous êtes sûr à 99,9999% d’obtenir les bonnes données à chaque fois.

RÉPONSE ORIGINALE

Une autre alternative plus sûre à ce problème consiste à utiliser get_queried_object() qui contient l'objet interrogé actuel pour obtenir le slug de page qui est détenu par la propriété post_name. Ceci peut être utilisé n'importe où dans votre modèle.

$post peut être utilisé, mais il peut ne pas être fiable car toute requête personnalisée ou code personnalisé peut modifier la valeur de $post; il convient donc de l'éviter en dehors de la boucle.

L'utilisation de get_queried_object() pour obtenir l'objet de la page en cours est beaucoup plus fiable et moins susceptible d'être modifiée, à moins que vous n'utilisiez le query_posts malveillant qui casse l'objet de requête principal, mais tout dépend de vous.

Vous pouvez utiliser ce qui précède comme suit

if ( is_page() )
    $slug = get_queried_object()->post_name;
25
Pieter Goosen

Le moyen simple d'obtenir la limace est avec:

<?php echo basename(get_permalink()); ?>
11
tracey

Étant donné l'exemple de code, il semble que vous ayez vraiment besoin d'un lien. Dans ce cas, vous pouvez utiliser get_permalink () , qui peut être utilisé en dehors de la boucle. Cela devrait faire ce dont vous avez besoin de manière plus fiable que d'utiliser le post slug.

8
Matthew Boynes

C'est peut-être une vieille question, mais j'ai créé les fonctions get_the_slug () et the_slug () en fonction de vos réponses.

if ( !function_exists("get_the_slug") ) {
    /**
    * Returns the page or post slug.
    *
    * @param int|WP_Post|null $id (Optional) Post ID or post object. Defaults to global $post.
    * @return string
    */
    function get_the_slug( $id = null ){
        $post = get_post($id);
        if( !empty($post) ) return $post->post_name;
        return ''; // No global $post var or matching ID available.
    }
    /**
    * Display the page or post slug
    *
    * Uses get_the_slug() and applies 'the_slug' filter.
    *
    * @param int|WP_Post|null $id (Optional) Post ID or post object. Defaults to global $post.
    */
    function the_slug( $id=null ){
        echo apply_filters( 'the_slug', get_the_slug($id) );
    }
}
2
Earlee

Juste plus loin sur la réponse de @Matthew Boynes, si vous souhaitez également obtenir le slug parent (le cas échéant), alors j'ai trouvé cette fonction utile:

function mytheme_get_slugs() {
    if ( $link = get_permalink() ) {
        $link = str_replace( home_url( '/' ), '', $link );
        if ( ( $len = strlen( $link ) ) > 0 && $link[$len - 1] == '/' ) {
            $link = substr( $link, 0, -1 );
        }
        return explode( '/', $link );
    }
    return false;
}

Par exemple, ajouter la ou les limaces à la classe de corps:

function mytheme_body_class( $classes ) {
    if ( $slugs = mytheme_get_slugs() ) {
        $classes = array_merge( $classes, $slugs );
    }
    return $classes;
}
add_filter( 'body_class', 'mytheme_body_class' );
0
bonger

Honnêtement, je ne comprends pas pourquoi aucune des réponses ne le fait tout simplement:

global $wp;
$current_slug = $wp->request;

// Given the URL of https://example.com/foo-bar
if ($current_slug === 'foo-bar') {
  // the condition will match.
}

Cela fonctionne pour tous les articles, pages, itinéraires personnalisés.

0
leymannx

C'est la fonction à utiliser pour récupérer le slug en dehors de la boucle.

get_post_field( 'post_name');

Réponse trouvée ici: Comment récupérer le slug de la page actuelle dans WordPress?

0
Kash

Si vous voulez une réponse plus subtile, vous pouvez utiliser la requête SQL suivante pour extraire à tout moment tous les articles qui sont des articles, des pages ou des taxonomies personnalisées, même si aucun crochet n'a été utilisé.

SQL brut:


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`;

Cela fonctionne même sur la toute première ligne de votre fichier de fonctions, même avant les points d'ancrage mu_plugins_loaded ou init.

@Remarque

Cela suppose que vous avez un préfixe de base de données standard wp_posts. Si vous devez prendre en compte les préfixes de variable, vous pouvez obtenir assez facilement le tableau de publication correct via PHP en procédant comme suit:

<?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`;"

Exécutez ensuite avec $wpdb, mysqli ou une instance PDO. Etant donné qu'il n'y a aucune entrée d'utilisateur dans cette requête, il est prudent de l'exécuter sans une instruction préparée tant que vous n'y injectez aucune variable.

Je suggérerais de stocker ceci en tant que valeur statique privée d'une classe, de sorte qu'il soit possible d'y accéder sans avoir à relancer la requête plusieurs fois par page pour obtenir les meilleures performances, comme ceci:

class Post_Cache
{
    private static $post_cache;

    public function __construct()
    {
        //This way it skips the operation if it's already set.
        $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 ) )
        {
            //returns the specific column value for the id
            return self::$post_cache[$id][$type];
        }
        //returns the whole row
        return self::$post_cache[$id];
    }

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

            $query = "...";
            $result = some_query_method($query); //Do your query logic here.
            self::$post_cache = $result;
        {
    }
}

Utilisation

$cache = new \Post_Cache();

//Get the page slug
$slug = $cache->get( get_the_ID(), 'slug');

if ($cache->get( get_the_ID() ))
{
    //post exists
} else {
    //nope, 404 'em
}
if ( $cache->get( get_the_ID(), 'status') === 'publish' )
{
    //it's public
} else {
    //either check current_user_can('whatever_permission') or just 404 it,
    //depending whether you want it visible to the current user or not.
}
if ( $cache->get( get_the_ID(), 'type') === 'post' )
{
    //It's a post
}
if ( $cache->get( get_the_ID(), 'type') === 'page' )
{
    //It's a page
}

Vous obtenez le Gist. Si vous avez besoin de plus de détails, vous pouvez les récupérer comme d'habitude avec new \WP_Post( get_the_ID() );


Cela vous permettra de vérifier les publications à tout moment, même si la boucle wordpress n’a pas atteint un point où elle juge votre demande agréable. Ceci est une version légèrement plus optimisée de la même requête exécutée par le noyau Wordpress lui-même. Celui-ci filtre toutes les informations indésirables que vous ne voudriez pas obtenir, et vous donne simplement une liste bien organisée avec l'identifiant de l'auteur, le type de publication, le slug et la visibilité appropriés. Si vous avez besoin de plus de détails, vous pouvez les récupérer comme d'habitude avec new \WP_Post($id); ou utiliser l'une des autres fonctions Wordpress natives avec l'une des lignes de la table pertinentes, même en dehors de la boucle.

J'utilise une configuration similaire dans quelques-uns de mes propres thèmes et plugins personnalisés, et cela fonctionne très bien. Il est également sécurisé et ne laisse pas de données internes flotter dans la portée globale où elles peuvent être remplacées comme le font la plupart des éléments de Wordpress.

0
mopsyd