ฉันจะดึงกระสุนของหน้าปัจจุบันได้อย่างไร


99

ฉันพยายามดึงกระสุนของหน้า WordPress ปัจจุบันนอกลูป หัวเรื่องของหน้าจะส่งคืนด้วยwp_title ()แต่ฉันจะรับกระสุนได้อย่างไร

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

คำตอบ:


151

ใช้ตัวแปรโกลบอล$post:

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

3
ขอขอบคุณ. โซลูชันของคุณใช้งานได้ดีมาก เพียงแค่ต้องสะท้อนทาก:<?php global $post; $post_slug=$post->post_name; echo $post_slug; ?>
sarytash

1
เช่นเดียวกับ sarytash พูดว่าคุณต้องการechoมัน ดังนั้นนี่จึงเป็นอุดมคติ:<?php global $post; echo $post->post_name; ?>
its_me

เกี่ยวกับ$WP_Postอะไร
Peter Mortensen

68

ตามคำตอบอื่น ๆ กระสุนจะถูกเก็บไว้ในpost_nameสถานที่ให้บริการ ในขณะที่สามารถเข้าถึงได้โดยตรงฉันชอบget_post_field()ฟังก์ชั่น(underused) สำหรับการเข้าถึงคุณสมบัติโพสต์ที่ไม่มี API ที่เหมาะสมสำหรับพวกเขา

ต้องมีการโพสต์ไว้อย่างชัดเจนและไม่ได้กำหนดค่าเริ่มต้นให้กับโพสต์ปัจจุบันดังนั้นเต็มสำหรับโพสต์ปัจจุบันมันจะเป็น:

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

12
มันเป็นที่น่าสังเกตว่าถ้าคุณอยู่ในวงที่คุณสามารถใช้get_post_fieldโดยไม่ต้องอาร์กิวเมนต์ที่สอง ( เอกสาร )
jmarceli

26

แก้ไข 5 เมษายน 2559

หลังจากขุดเพื่อความน่าเชื่อถือมากขึ้นฉันลงเอยด้วยการทำคำตอบนี้ไปยังโพสต์ต่อไปนี้ซึ่งนำไปสู่การแก้ไขนี้: ( อย่าลืมตรวจสอบ )

วิธีการที่เชื่อถือได้มากที่สุดจนถึงวันที่ฉันจะมาด้วยคือต่อไปนี้:

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

ด้วยวิธีนี้คุณมั่นใจได้ 99.9999% ว่าคุณได้รับข้อมูลที่ถูกต้องทุกครั้ง

คำตอบเดิม

ทางเลือกที่ปลอดภัยกว่าอีกทางหนึ่งสำหรับปัญหานี้คือการใช้get_queried_object()ซึ่งเก็บออบเจ็กต์การสอบถามปัจจุบันเพื่อรับบุ้งเพจที่จัดขึ้นโดยpost_nameพร็อพเพอร์ตี้ สามารถใช้ที่ใดก็ได้ในเทมเพลตของคุณ

$postสามารถใช้งานได้ แต่อาจไม่น่าเชื่อถือเนื่องจากแบบสอบถามแบบกำหนดเองใด ๆ หรือรหัสที่กำหนดเองสามารถเปลี่ยนค่าได้$postดังนั้นจึงควรหลีกเลี่ยงนอกลูป

การใช้get_queried_object()เพื่อให้วัตถุหน้าปัจจุบันมีความน่าเชื่อถือมากขึ้นและมีโอกาสน้อยที่จะได้รับการแก้ไขเว้นแต่ว่าคุณกำลังใช้สิ่งชั่วร้ายquery_postsซึ่งจะทำลายวัตถุแบบสอบถามหลัก แต่นั่นก็ขึ้นอยู่กับคุณแล้ว

คุณสามารถใช้ข้างต้นดังต่อไปนี้

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

ฉันต้องบอกว่าquery_postsไม่เลวเมื่อคุณต้องการเปลี่ยนการสืบค้นหลักซึ่งอย่างไรก็ตามคุณมักจะไม่ทำผิดและมักถูกนำไปใช้ผิด ๆ :)
jave.web

11

วิธีง่ายๆในการรับกระสุนคือ:

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

2
ขึ้นอยู่กับการตั้งค่าความคิดเห็น หากคุณใช้การตั้งค่า "ง่าย" การเชื่อมโยงจะมีลักษณะเช่นออกจากคุณกับhttp://domain/?p=123 ?p=123
Mene

8

จากตัวอย่างโค้ดดูเหมือนว่าสิ่งที่คุณต้องการจริงๆคือลิงค์ ในกรณีนั้นคุณสามารถใช้get_permalink ()ซึ่งสามารถใช้นอกลูปได้ นั่นควรทำสิ่งที่คุณต้องการได้อย่างน่าเชื่อถือมากกว่าการใช้ตัวบุ้งโพสต์


4
นี่เป็น URL แบบเต็มไม่ใช่แค่ตัวบุ้ง
เฟรด

2

อาจเป็นคำถามเก่า แต่ฉันสร้างฟังก์ชัน get_the_slug () และ the_slug () ตามคำตอบของคุณ

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

1

นี่คือฟังก์ชั่นที่ใช้เมื่อต้องการดึงกระสุนออกจากห่วง

get_post_field( 'post_name');

พบคำตอบได้ที่นี่: วิธีดึงตัวบุ้งของหน้าปัจจุบันใน WordPress?


แน่นอน แต่คุณต้องผ่านการ $ post หรือ ID ของการโพสต์เป็นอาร์กิวเมนต์ที่สอง
trainoasis

0

ต่อไปที่ @Matthew Boynes คำตอบหากคุณสนใจที่จะรับ slug แม่ (ถ้ามี) แล้วฉันก็พบว่าฟังก์ชั่นนี้มีประโยชน์:

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

เช่นเพื่อเพิ่มกระสุน (s) ไปยังระดับร่างกาย:

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

หากคุณต้องการคำตอบที่ไม่คาดคิดมากขึ้นคุณสามารถใช้แบบสอบถาม SQL ต่อไปนี้เพื่อดึงข้อมูลโพสต์ทั้งหมดที่เป็นโพสต์เพจหรือ taxonomies แบบกำหนดเองได้ตลอดเวลาแม้ว่าจะยังไม่มีฮุคใด ๆ ก็ตาม

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

สิ่งนี้จะทำงานได้แม้ในบรรทัดแรกของไฟล์ฟังก์ชั่นของคุณแม้ก่อนหน้าmu_plugins_loadedหรือinitตะขอ

@บันทึก

wp_postsนี้จะสมมติว่าคุณมีคำนำหน้าฐานข้อมูลมาตรฐาน หากคุณต้องการบัญชีคำนำหน้าตัวแปรคุณสามารถรับตารางการโพสต์ที่ถูกต้องผ่าน PHP ได้อย่างง่ายดายโดยทำดังต่อไปนี้:

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

จากนั้นทำงานกับอย่างใดอย่างหนึ่ง$wpdb, mysqliหรือPDOอินสแตนซ์ เนื่องจากไม่มีการป้อนข้อมูลของผู้ใช้ในแบบสอบถามนี้จึงปลอดภัยที่จะรันโดยไม่มีคำสั่งที่เตรียมไว้ตราบใดที่คุณไม่ต้องแทรกตัวแปรใด ๆ

ฉันขอแนะนำให้เก็บค่านี้เป็นค่าคงที่แบบส่วนตัวของคลาสดังนั้นจึงสามารถเข้าถึงได้โดยไม่ต้องเริ่มต้นคิวรีอีกครั้งมากกว่าหนึ่งครั้งต่อหน้าเพื่อประสิทธิภาพที่ดีที่สุดดังนี้:

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

การใช้

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

คุณได้รับส่วนสำคัญ หากคุณต้องการรายละเอียดเพิ่มเติมคุณสามารถดึงข้อมูลได้ตามปกติด้วยnew \WP_Post( get_the_ID() );


วิธีนี้จะช่วยให้คุณตรวจสอบการโพสต์ได้ตลอดเวลาแม้ว่า wordpress loop ยังไม่ถึงจุดที่พบคำขอของคุณ นี่เป็นรุ่นที่ได้รับการปรับให้เหมาะสมยิ่งขึ้นของการสืบค้นเดียวกันโดย Core Wordpress เอง อันนี้กรองขยะทั้งหมดที่คุณไม่ต้องการให้กลับมาและให้รายชื่อที่จัดเรียงอย่างดีกับ id ผู้เขียนที่เกี่ยวข้องประเภทโพสต์กระสุนและการมองเห็น หากคุณต้องการรายละเอียดเพิ่มเติมคุณสามารถดึงข้อมูลได้ตามปกติด้วยnew \WP_Post($id);หรือใช้ฟังก์ชัน Wordpress ดั้งเดิมอื่น ๆ กับแถวของตารางที่เกี่ยวข้องแม้อยู่นอกวง

ฉันใช้การตั้งค่าที่คล้ายกันในธีมและปลั๊กอินที่กำหนดเองของฉันและมันใช้งานได้ดีมาก นอกจากนี้ยังมีความปลอดภัยและไม่ปล่อยให้ข้อมูลภายในที่ลอยอยู่ในขอบเขตทั่วโลกที่สามารถถูกแทนที่ได้เหมือนสิ่งที่ส่วนใหญ่ใน Wordpress ทำ


0

ฉันไม่เข้าใจจริง ๆ ว่าทำไมไม่มีคำตอบง่ายๆ:

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

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

ใช้ได้กับโพสต์เพจเส้นทางที่กำหนดเองทั้งหมด


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.