Cum pot obține slug-ul paginii curente?
Folosește variabila globală $post
:
<?php
global $post;
$post_slug = $post->post_name;
?>

Mulțumesc. Soluția ta funcționează excelent. Trebuie doar să afișezi slug-ul: <?php
global $post;
$post_slug=$post->post_name; echo $post_slug;
?>

Așa cum a spus sarytash, trebuie să folosești echo
. Deci, aceasta ar fi varianta ideală: <?php global $post; echo $post->post_name; ?>

Ce zici de $WP_Post
?

Nu va funcționa dacă sunteți, să zicem, pe yourpage.com/search dacă aceasta nu este o pagină existentă ci o rescriere de la ?s=

nu este post_name titlul lizibil de către om (inclusiv spațiile goale) în loc de slug?

Conform altor răspunsuri, slug-ul este stocat în proprietatea post_name
. Deși ar putea fi accesat direct, prefer funcția (puțin utilizată) get_post_field()
pentru accesarea proprietăților articolelor care nu au un API specific pentru ele.
Aceasta necesită ca articolul să fie furnizat în mod explicit și nu folosește implicit articolul curent, așadar pentru articolul curent ar arăta complet astfel:
$slug = get_post_field( 'post_name', get_post() );

Merită menționat că dacă te afli în loop poți folosi get_post_field
fără al doilea argument (documentație)

Notă scurtă: Am folosit această metodă pe aproximativ 8 site-uri web diferite cu plugin-ul meu, dar nu a reușit să preia slug-ul corect al paginii pe cel mai recent site web pe care am instalat plugin-ul. Probabil că temele sau alte plugin-uri au încurcat referința corectă către obiectul $post, rezultând în slug-ul greșit al postării. Oricum, răspunsul lui @Pieter Goosen a rezolvat această problemă pentru mine: https://wordpress.stackexchange.com/a/188945/150100

Este probabil evident, dar vreau să adaug că al 2-lea argument poate fi de asemenea un ID de articol.

da, acest răspuns sau răspunsul lui Pieter de mai jos ar trebui să fie răspunsul acceptat! de ce? ... dacă globalizezi $post într-o funcție și apoi din greșeală îi atribui o valoare... tocmai ai suprascris variabila globală $post care ar putea strica codul ulterior... este mai bine să folosești acest exemplu sau get_queried_object()->post_name

EDITARE 5 APRILIE 2016
După ce am săpat mai mult pentru fiabilitate, am ajuns să ofer acest răspuns la următoarea postare care duce la această editare: (Asigură-te că o verifici)
Cea mai fiabilă metodă până în prezent pe care am putut să o concep este următoarea:
// Obține obiectul interogat și igienizează-l
$current_page = sanitize_post( $GLOBALS['wp_the_query']->get_queried_object() );
// Obține slug-ul paginii
$slug = $current_page->post_name;
În acest fel, ești 99.9999% sigur că vei obține datele corecte de fiecare dată.
RĂSPUNSUL ORIGINAL
O altă alternativă mai sigură la această problemă este utilizarea get_queried_object()
care conține obiectul curent interogat pentru a obține slug-ul paginii care este stocat în proprietatea post_name
. Aceasta poate fi utilizată oriunde în șablonul tău.
$post
poate fi utilizat, dar poate fi nesigur deoarece orice interogare personalizată sau cod personalizat poate modifica valoarea lui $post
, așa că ar trebui evitat în afara buclei.
Utilizarea get_queried_object()
pentru a obține obiectul paginii curente este mult mai fiabilă și este mai puțin probabil să fie modificată, cu excepția cazului în care utilizezi maleficul query_posts
care strică obiectul interogării principale, dar asta depinde doar de tine.
Poți utiliza cele de mai sus astfel
if ( is_page() )
$slug = get_queried_object()->post_name;

acest lucru depinde de setările permalink. Dacă folosești setarea "simple", link-urile vor arăta ca http://domain/?p=123
, lăsându-te cu ?p=123
.

@Mene adevărat, dar întrebarea este cum să obții slug-ul care, de obicei, înseamnă că există unul în URL (argumentul GET p
nu este un slug).

Având în vedere exemplul de cod, se pare că ceea ce ai nevoie de fapt este un link. În acest caz, poți folosi get_permalink(), care poate fi utilizat și în afara buclei. Această funcție ar trebui să facă ceea ce ai nevoie într-un mod mai fiabil decât utilizarea slug-ului postării.

Ar putea fi o întrebare mai veche, dar am creat funcțiile get_the_slug() și the_slug() bazate pe răspunsurile voastre.
if ( !function_exists("get_the_slug") ) {
/**
* Returnează slug-ul paginii sau al articolului.
*
* @param int|WP_Post|null $id (Opțional) ID-ul articolului sau obiectul post. Implicit folosește variabila globală $post.
* @return string
*/
function get_the_slug( $id = null ){
$post = get_post($id);
if( !empty($post) ) return $post->post_name;
return ''; // Nu există variabila globală $post sau ID-ul corespunzător nu este disponibil.
}
/**
* Afișează slug-ul paginii sau al articolului
*
* Folosește get_the_slug() și aplică filtrul 'the_slug'.
*
* @param int|WP_Post|null $id (Opțional) ID-ul articolului sau obiectul post. Implicit folosește variabila globală $post.
*/
function the_slug( $id=null ){
echo apply_filters( 'the_slug', get_the_slug($id) );
}
}

Poți pur și simplu să separi slug-ul din request folosind funcția explode.
global $wp;
// Deoarece slug-urile în sine nu pot conține slash-uri,
// să folosim explode pe slash-uri și să luăm ultima porțiune.
$request_args = explode('/', $wp->request);
$current_slug = end($request_args);
// Pentru URL-ul https://example.com/foo/bar/foo-bar
if ($current_slug === 'foo-bar') {
// condiția va fi îndeplinită.
}
Aceasta funcționează pentru toate articolele, paginile și rutele personalizate.

Aceasta este funcția care trebuie folosită când doriți să obțineți slug-ul în afara buclei.
get_post_field( 'post_name');
Răspuns găsit aici: Cum să obții Slug-ul Paginii Curente în WordPress?

Dacă dorești un răspuns mai detaliat, poți utiliza următoarea interogare SQL pentru a extrage toate postările care sunt fie articole, pagini sau taxonomii personalizate în orice moment, chiar dacă nu s-a declanșat niciun hook până în acel moment.
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`;
Aceasta funcționează chiar și pe prima linie din fișierul functions.php, chiar înainte de hook-urile mu_plugins_loaded
sau init
.
@notă
Acest exemplu presupune că ai un prefix standard pentru baza de date wp_posts
. Dacă trebuie să ții cont de prefixe variabile, poți obține tabelul corect pentru postări prin PHP destul de ușor făcând următoarele:
<?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`;"
Apoi rulează cu fie $wpdb
, mysqli
, sau o instanță PDO
. Deoarece nu există input de la utilizator în această interogare, este sigur să o rulezi fără o declarație pregătită atâta timp cât nu injectezi nicio variabilă în ea.
Sugerez stocarea acesteia ca o valoare statică privată într-o clasă, astfel încât să poată fi accesată fără a trebui să executăm interogarea de mai multe ori pe pagină pentru performanță optimă, ceva de genul:
class Post_Cache
{
private static $post_cache;
public function __construct()
{
//În acest fel sare peste operațiune dacă este deja setată
$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 ) )
{
//returnează valoarea coloanei specifice pentru id
return self::$post_cache[$id][$type];
}
//returnează întregul rând
return self::$post_cache[$id];
}
private function initCache()
{
if ( is_null(self::$post_cache) )
{
$query = "...";
$result = some_query_method($query); //Adaugă aici logica interogării
self::$post_cache = $result;
{
}
}
Utilizare
$cache = new \Post_Cache();
//Obține slug-ul paginii
$slug = $cache->get( get_the_ID(), 'slug');
if ($cache->get( get_the_ID() ))
{
//postarea există
} else {
//nu există, arată 404
}
if ( $cache->get( get_the_ID(), 'status') === 'publish' )
{
//este publică
} else {
//fie verifică current_user_can('whatever_permission') sau arată 404,
//în funcție dacă vrei să fie vizibilă pentru utilizatorul curent sau nu
}
if ( $cache->get( get_the_ID(), 'type') === 'post' )
{
//Este o postare
}
if ( $cache->get( get_the_ID(), 'type') === 'page' )
{
//Este o pagină
}
Înțelegi ideea. Dacă ai nevoie de mai multe detalii, le poți obține în mod normal cu new \WP_Post( get_the_ID() );
Aceasta îți va permite să verifici postările în orice moment, chiar dacă bucla WordPress nu a ajuns într-un punct în care să găsească cererea ta acceptabilă. Aceasta este o versiune ușor optimizată a aceleiași interogări rulată de nucleul WordPress. Aceasta filtrează toate elementele nedorite pe care nu ai vrea să le returneze și îți oferă o listă organizată frumos cu id-ul autorului relevant, tipul postării, slug-ul și vizibilitatea. Dacă ai nevoie de mai multe detalii, le poți obține în mod normal cu new \WP_Post($id);
, sau poți utiliza oricare dintre funcțiile native WordPress cu oricare dintre rândurile tabelului relevant, chiar și în afara buclei.
Folosesc o configurație similară în câteva dintre temele și plugin-urile mele personalizate și funcționează foarte bine. De asemenea, este sigură și nu lasă date interne plutind în scopul global unde pot fi suprascrise ca majoritatea lucrurilor din WordPress.

Dacă te afli în loop atunci celelalte răspunsuri te vor ajuta.
Dacă nu (de exemplu, dacă te conectezi la init
sau plugins_loaded
) poți recurge la o funcție primitivă PHP precum parse_url()
.
Iată o funcție care funcționează în ambele cazuri:
function get_the_slug() {
// Declarăm variabila globală post
global $post;
// Încercăm să obținem slug-ul din obiectul post
$slug = $post->post_name ?? '';
// Dacă nu avem slug, îl extragem din URL
if ( ! $slug ) {
$slug = basename( parse_url( $_SERVER['REQUEST_URI'] ?? '', PHP_URL_PATH ) );
}
return $slug;
}
Te rugăm să reții că această abordare funcționează doar pentru articole/pagini la nivel rădăcină, datorită modului în care funcționează basename()
.

În completarea răspunsului lui @Matthew Boynes, dacă sunteți interesat să obțineți și slug-ul părintelui (dacă există), am găsit această funcție utilă:
function mytheme_get_slugs() {
if ( $link = get_permalink() ) {
// Înlocuiește URL-ul de bază cu un string gol
$link = str_replace( home_url( '/' ), '', $link );
// Elimină slash-ul final dacă există
if ( ( $len = strlen( $link ) ) > 0 && $link[$len - 1] == '/' ) {
$link = substr( $link, 0, -1 );
}
// Împarte link-ul în segmente folosind slash-ul ca separator
return explode( '/', $link );
}
return false;
}
De exemplu, pentru a adăuga slug-urile la clasa body:
function mytheme_body_class( $classes ) {
// Verifică dacă există slug-uri
if ( $slugs = mytheme_get_slugs() ) {
// Combină array-ul de clase existent cu slug-urile
$classes = array_merge( $classes, $slugs );
}
return $classes;
}
add_filter( 'body_class', 'mytheme_body_class' );
