Bagaimana cara mengambil siput halaman saat ini?

99

Saya mencoba untuk mengambil siput halaman WordPress saat ini di luar loop. Judul halaman kembali dengan wp_title (), tetapi bagaimana saya bisa mendapatkan siput?

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

Jawaban:

151

Gunakan variabel global $post:

<?php 
    global $post;
    $post_slug = $post->post_name;
?>
Arvind Pal
sumber
3
Terima kasih. Solusi Anda bekerja sangat baik. Hanya perlu mengulangi siput:<?php global $post; $post_slug=$post->post_name; echo $post_slug; ?>
sarytash
1
Seperti kata sarytash, Anda perlu echoitu. Jadi, ini ideal:<?php global $post; echo $post->post_name; ?>
its_me
Bagaimana dengan $WP_Post?
Peter Mortensen
68

Sebagai jawaban lain, siput disimpan di post_nameproperti. Walaupun dapat diakses secara langsung, saya lebih suka fungsi (kurang digunakan) get_post_field()untuk mengakses properti posting yang tidak memiliki API yang tepat untuk mereka.

Membutuhkan posting yang disediakan secara eksplisit dan tidak default ke yang sekarang, jadi secara penuh untuk posting saat ini adalah:

$slug = get_post_field( 'post_name', get_post() );
Jarang
sumber
12
Perlu dicatat bahwa jika Anda berada di loop Anda dapat menggunakan get_post_fieldtanpa argumen kedua ( docs )
jmarceli
26

EDIT 5 APRIL 2016

Setelah menggali untuk keandalan yang lebih, saya akhirnya melakukan jawaban ini untuk posting berikut yang mengarah ke pengeditan ini: ( Pastikan untuk memeriksanya )

Metode yang paling dapat diandalkan sampai saat ini yang bisa saya pikirkan adalah sebagai berikut:

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

Dengan cara ini, Anda 99,9999% yakin bahwa Anda mendapatkan data yang benar setiap waktu.

JAWABAN ASLI

Alternatif lain yang lebih aman untuk masalah ini adalah menggunakan get_queried_object()yang memegang objek tanya saat ini untuk mendapatkan halaman siput yang dimiliki oleh post_nameproperti. Ini dapat digunakan di mana saja di template Anda.

$postdapat digunakan, tetapi bisa tidak dapat diandalkan karena setiap kueri kustom atau kode khusus dapat mengubah nilai $post, jadi harus dihindari di luar loop.

Menggunakan get_queried_object()untuk mendapatkan objek halaman saat ini jauh lebih dapat diandalkan dan kecil kemungkinannya untuk dimodifikasi, kecuali jika Anda menggunakan iblis query_postsyang merusak objek permintaan utama, tapi itu semua terserah Anda.

Anda dapat menggunakan di atas sebagai berikut

if ( is_page() )
    $slug = get_queried_object()->post_name;
Pieter Goosen
sumber
Saya harus mengatakan bahwa query_postsitu tidak jahat ketika Anda ingin mengubah permintaan utama , yang bagaimanapun Anda biasanya tidak dan sering disalahgunakan :)
jave.web
11

Cara sederhana untuk mendapatkan siput adalah dengan:

<?php echo basename(get_permalink()); ?>
jejak
sumber
2
ini tergantung pada pengaturan permalink. Jika Anda menggunakan pengaturan "sederhana", tautan akan terlihat seperti http://domain/?p=123, meninggalkan Anda ?p=123.
Mene
8

Dengan contoh kode, sepertinya yang Anda butuhkan adalah tautan. Dalam hal ini, Anda bisa menggunakan get_permalink () , yang bisa digunakan di luar loop. Itu harus melakukan apa yang Anda butuhkan lebih andal daripada menggunakan post slug.

Matthew Boynes
sumber
4
Ini adalah URL lengkap, bukan hanya siput.
Fred
2

Mungkin menjadi pertanyaan lama, tetapi saya membuat fungsi get_the_slug () dan the_slug () berdasarkan jawaban Anda.

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
sumber
0

Lebih jauh lagi pada jawaban @Matthew Boynes, jika Anda tertarik untuk mendapatkan siput induk (jika ada) juga maka saya telah menemukan fungsi ini berguna:

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

Misalnya untuk menambahkan siput ke kelas tubuh:

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
sumber
0

Jika Anda menginginkan jawaban yang lebih tersembunyi, Anda dapat menggunakan kueri SQL berikut untuk mengambil semua pos yang merupakan pos, halaman, atau taksonomi ubahsuaian kapan saja, bahkan jika belum ada kait yang dipecat sama sekali.

SQL mentah:


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

Ini berfungsi bahkan pada baris pertama file fungsi Anda, bahkan sebelum mu_plugins_loadedatau initkait.

@catatan

Ini dengan asumsi Anda memiliki awalan basis data standar wp_posts. Jika Anda perlu memperhitungkan awalan variabel, Anda dapat memperoleh tabel posting yang benar melalui PHP dengan mudah dengan melakukan hal berikut:

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

Kemudian jalankan dengan baik $wpdb, mysqli, atau PDOcontoh. Karena tidak ada input pengguna dalam kueri ini, aman untuk dijalankan tanpa pernyataan yang disiapkan selama Anda tidak menyuntikkan variabel apa pun ke dalamnya.

Saya akan menyarankan menyimpan ini sebagai nilai statis privat dari sebuah kelas, sehingga dapat diakses tanpa harus memecat kueri lagi lebih dari sekali per halaman untuk kinerja terbaik, sesuatu seperti ini:

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

Pemakaian

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

Anda mendapatkan intinya. Jika Anda memerlukan detail lebih lanjut, Anda dapat mengambilnya seperti biasanew \WP_Post( get_the_ID() );


Ini akan memungkinkan Anda memeriksa posting kapan saja, bahkan jika loop wordpress belum mencapai titik di mana ia menemukan permintaan Anda menyenangkan. Ini adalah versi yang sedikit lebih dioptimalkan dari kueri yang sama yang dijalankan oleh inti Wordpress itu sendiri. Yang ini menyaring semua sampah yang tidak ingin Anda kembalikan, dan hanya memberi Anda daftar yang tertata rapi dengan id penulis yang relevan, jenis posting, siput, dan visibilitas. Jika Anda memerlukan perincian lebih lanjut, Anda dapat mengambilnya seperti biasa dengan new \WP_Post($id);, atau menggunakan salah satu fungsi Wordpress asli lainnya dengan salah satu baris tabel yang relevan, bahkan di luar loop.

Saya menggunakan pengaturan serupa di beberapa tema dan plugin kustom saya sendiri, dan itu bekerja sangat bagus. Ini juga aman dan tidak meninggalkan data internal melayang di lingkup global di mana ia dapat ditimpa seperti kebanyakan hal di Wordpress.

mopsyd
sumber
0

Sejujurnya saya tidak mengerti mengapa tidak ada jawaban yang cukup:

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

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

Ini berfungsi untuk semua posting, halaman, rute khusus.

leymannx
sumber
-1

Panggilan Halaman dinamis di WordPress.

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