Jak mogę odzyskać informacje o bieżącej stronie?

99

Próbuję pobrać informacje o bieżącej stronie WordPress poza pętlą. Tytuł strony powraca z wp_title (), ale jak mogę dostać ślimaka?

<li>
  <a href="/slug-of-current-page/">
    <?php wp_title('', true); ?>
  </a>
</li>
sarytash
źródło

Odpowiedzi:

151

Użyj zmiennej globalnej $post:

<?php 
    global $post;
    $post_slug = $post->post_name;
?>
Arvind Pal
źródło
3
Dziękuję Ci. Twoje rozwiązanie działa świetnie. Wystarczy echo ślimaka:<?php global $post; $post_slug=$post->post_name; echo $post_slug; ?>
sarytash,
1
Jak powiedział sarytash, musisz to echozrobić. Byłoby to idealne:<?php global $post; echo $post->post_name; ?>
its_me
Co $WP_Post?
Peter Mortensen
68

Zgodnie z innymi odpowiedziami ślimak jest przechowywany we post_namewłaściwości. Chociaż można było uzyskać do niego bezpośredni dostęp, wolę funkcję (niedostatecznie wykorzystywaną) get_post_field()do uzyskiwania dostępu do właściwości postu, które nie mają dla nich odpowiedniego interfejsu API.

Wymaga posta podanego jawnie i nie jest domyślnie ustawiony na bieżący, więc w całości dla bieżącego postu będzie to:

$slug = get_post_field( 'post_name', get_post() );
Rarst
źródło
12
Warto zauważyć, że jeśli jesteś w pętli, możesz używać get_post_fieldbez drugiego argumentu ( docs )
jmarceli 16.06.16
26

EDYCJA 5 KWIECIEŃ 2016

Po kopaniu w celu uzyskania większej niezawodności skończyłem z odpowiedzią na następujący post, który prowadzi do tej edycji: ( koniecznie sprawdź to )

Najbardziej niezawodną metodą do tej pory, jaką mogłem wymyślić, jest:

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

W ten sposób masz 99,9999% pewności, że za każdym razem otrzymujesz poprawne dane.

ORYGINALNA ODPOWIEDŹ

Inną bezpieczniejszą alternatywą dla tego problemu jest użycie, get_queried_object()które utrzymuje bieżący obiekt, którego dotyczy zapytanie, w celu uzyskania informacji o stronie przechowywanej przez post_namewłaściwość. Można tego użyć w dowolnym miejscu w szablonie.

$postmoże być użyty, ale może być zawodny, ponieważ każde niestandardowe zapytanie lub niestandardowy kod może zmienić wartość $post, dlatego należy go unikać poza pętlą.

Użycie get_queried_object()do uzyskania bieżącego obiektu strony jest znacznie bardziej niezawodne i jest mniej prawdopodobne, że zostanie zmodyfikowane, chyba że użyjesz zła, query_postsktóre psuje główny obiekt zapytania, ale to wszystko zależy od ciebie.

Możesz użyć powyższego w następujący sposób

if ( is_page() )
    $slug = get_queried_object()->post_name;
Pieter Goosen
źródło
Muszę powiedzieć, że query_poststo nie jest złe, jeśli chcesz zmienić główne zapytanie , które jednak zwykle nie jest i jest często niewłaściwie wykorzystywane :)
jave.web
11

Prostym sposobem na zdobycie ślimaka jest:

<?php echo basename(get_permalink()); ?>
śladowe
źródło
2
zależy to od ustawień łącza bezpośredniego. Jeśli użyjesz „prostego” ustawienia, linki będą wyglądać http://domain/?p=123, pozostawiając cię z ?p=123.
Mene
8

Biorąc pod uwagę przykład kodu, wygląda na to, że tak naprawdę potrzebujesz łącza. W takim przypadku możesz użyć get_permalink () , którego można użyć poza pętlą. To powinno zrobić to, czego potrzebujesz bardziej niezawodnie niż przy użyciu ślimaka postowego.

Matthew Boynes
źródło
4
Jest to pełny adres URL, nie tylko ślimak.
Fred
2

To może być stare pytanie, ale stworzyłem funkcje get_the_slug () i the_slug () na podstawie twoich odpowiedzi.

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
źródło
0

W dalszej części odpowiedzi na @Matthew Boynes, jeśli jesteś zainteresowany otrzymaniem ślimaka nadrzędnego (jeśli istnieje), to uważam, że ta funkcja jest przydatna:

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

Np. Aby dodać ślimak (i) do klasy ciała:

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
źródło
0

Jeśli chcesz uzyskać bardziej ukrytą odpowiedź, możesz użyć następującego zapytania SQL, aby pobrać wszystkie posty, które są albo postami, stronami lub niestandardowymi taksonomiami w dowolnym momencie, nawet jeśli jak dotąd nie uruchomiono żadnych haków.

Surowy SQL:


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

Działa to nawet w pierwszym wierszu pliku funkcji, nawet przed przechwyceniem mu_plugins_loadedlub init.

@Uwaga

Zakłada się, że masz standardowy prefiks bazy danych wp_posts. Jeśli potrzebujesz uwzględnić zmienne prefiksy, możesz łatwo uzyskać poprawną tabelę postów przez PHP, wykonując następujące czynności:

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

Następnie należy uruchomić z obu $wpdb, mysqlialbo PDOinstancji. Ponieważ w tym zapytaniu nie ma danych wejściowych od użytkownika, można bezpiecznie uruchomić bez przygotowanej instrukcji, pod warunkiem, że nie zostaną do niej wprowadzone żadne zmienne.

Sugerowałbym przechowywanie tego jako prywatnej wartości statycznej klasy, aby można było uzyskać do niego dostęp bez konieczności ponownego uruchamiania zapytania więcej niż raz na stronę w celu uzyskania najlepszej wydajności, coś takiego:

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;
        {
    }
}

Stosowanie

$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
}

Dostajesz sedno. Jeśli potrzebujesz dodatkowych informacji, możesz je pobrać jak zwykle za pomocąnew \WP_Post( get_the_ID() );


To pozwoli ci sprawdzić posty w dowolnym momencie, nawet jeśli pętla wordpress nie osiągnęła punktu, w którym uzna twoje żądanie za akceptowalne. Jest to nieco bardziej zoptymalizowana wersja tego samego zapytania uruchamianego przez sam rdzeń Wordpress. Ten odfiltrowuje wszystkie śmieci, których nie chciałbyś zwracać, i po prostu daje ci ładnie zorganizowaną listę z odpowiednim identyfikatorem autora, typem postu, ślimakiem i widocznością. Jeśli potrzebujesz dodatkowych informacji, możesz je pobrać normalnie za pomocą new \WP_Post($id);lub użyć dowolnej innej natywnej funkcji Wordpress z dowolnym odpowiednim wierszem tabeli, nawet poza pętlą.

Korzystam z podobnej konfiguracji w kilku własnych niestandardowych motywach i wtyczkach i działa całkiem nieźle. Jest również bezpieczny i nie pozostawia wewnętrznych danych w globalnym zasięgu, gdzie można je zastąpić, jak większość rzeczy w Wordpress.

mopsyd
źródło
0

Naprawdę nie rozumiem, dlaczego żadna z odpowiedzi po prostu nie:

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

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

Działa to dla wszystkich postów, stron, tras niestandardowych.

leymannx
źródło
-1

Dynamiczne wywołanie strony w WordPress.

<?php
    get_template_part('foldername/'.basename(get_permalink()),'name');
    ?>
Sujoy Bhowmick
źródło