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

100

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 la limace?

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

Réponses:

152

Utilisez la variable globale $post:

<?php 
    global $post;
    $post_slug = $post->post_name;
?>
Arvind Pal
la source
3
Je vous remercie. Votre solution fonctionne très bien. Juste besoin de faire écho à la limace:<?php global $post; $post_slug=$post->post_name; echo $post_slug; ?>
sarytash
1
Comme dit sarytash, vous en avez besoin echo. Donc, ce serait idéal:<?php global $post; echo $post->post_name; ?>
its_me
Qu'en est- il $WP_Post?
Peter Mortensen le
68

Comme d’autres réponses, la limace est stockée dans la post_namepropriété. Bien qu'il soit possible d' y accéder directement, je préfère la fonction (sous-utilisée) get_post_field()pour accéder aux propriétés de publication qui ne possèdent 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() );
Rarst
la source
12
Il est à noter que si vous êtes dans la boucle, vous pouvez utiliser get_post_fieldsans second argument ( docs )
jmarceli
26

EDIT 5 AVRIL 2016

Après avoir creusé pour plus de fiabilité, j'ai fini par faire cette réponse au message suivant qui mène à cette modification: ( Assurez-vous de 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é en cours pour obtenir le slug de page détenu par la post_namepropriété. Ceci peut être utilisé n'importe où dans votre modèle.

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

Utiliser get_queried_object()pour obtenir l'objet de la page en cours est beaucoup plus fiable et moins susceptible d'être modifié, à moins que vous n'utilisiez le mal, query_postsqui 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;
Pieter Goosen
la source
Je dois dire que ce query_postsn'est pas mauvais quand vous voulez modifier la requête principale , ce qui n'est pas le cas et qui est souvent mal utilisé :)
jave.web
11

Le moyen simple d'obtenir la limace est avec:

<?php echo basename(get_permalink()); ?>
trace
la source
2
cela dépend des paramètres de permalien. Si vous utilisez le paramètre "simple", les liens ressembleront http://domain/?p=123, vous laissant avec ?p=123.
Mene
8

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

Matthew Boynes
la source
4
Ceci est l'URL complète cependant, pas seulement la limace.
Fred
2

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) );
    }
}
Earlee
la source
0

Juste plus loin sur la réponse de @Matthew Boynes, si vous êtes intéressé à 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' );
bonger
la source
0

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é à ce jour.

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 première ligne de votre fichier de fonctions, avant même le mu_plugins_loadedou les initcrochets.

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

Ensuite , exécutez soit $wpdb, mysqliou une PDOinstance. 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;
        {
    }
}

Usage

$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 avez l'essentiel. Si vous avez besoin de plus amples détails, vous pouvez les récupérer comme d'habitude avecnew \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 retrouver, et vous donne simplement une liste bien organisée avec l'identifiant de l'auteur, le type de publication, le mot de passe 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 flottantes dans la portée globale où elles peuvent être remplacées, comme le font la plupart des éléments de Wordpress.

mopsyd
la source
0

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.

leymannx
la source
-1

Appel de page dynamique dans WordPress.

<?php
    get_template_part('foldername/'.basename(get_permalink()),'name');
    ?>
Sujoy Bhowmick
la source