我试图在循环外检索当前WordPress页面的信息。页面标题返回wp_title (),但是如何获取该标签?

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


#1 楼

使用全局变量$post

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


评论


谢谢。您的解决方案效果很好。只需要回声一下:<?php global $ post; $ post_slug = $ post-> post_name; echo $ post_slug; ?>

–sarytash
2012年2月13日在12:13

就像sarytash所说的,您需要回显它。因此,这将是理想的:<?php global $ post; echo $ post-> post_name; ?>

–its_me
13-10-11在15:59

$ WP_Post呢?

– Peter Mortensen
19年4月24日在13:00

如果您说这不是现有页面,而是从?s =重写,则无法在yourpage.com/search上运行

–火车头病
10月14日12:55



#2 楼

根据其他答案,段塞存储在post_name属性中。尽管可以直接访问它,但我更喜欢使用(未充分利用的)get_post_field()函数来访问没有适当API的帖子属性。

它需要显式提供帖子,并且默认不使用当前帖子,因此,对于当前帖子而言,完整信息为:

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


评论


值得注意的是,如果您处于循环中,则可以使用没有第二个参数的get_post_field(docs)

– jmarceli
16年6月16日在6:42

小提示:我在大约8个不同的网站上都使用了此方法,但我的插件确实无法在最新的网站上检索到正确的页面信息。主题或其他插件本身可能弄乱了对$ post对象的正确引用,从而导致错误的发布结果。无论如何,@ Pieter Goosen的回答确实为我解决了这个问题:wordpress.stackexchange.com/a/188945/150100

–瓦斯科
10月19日10:07

#3 楼

编辑2016年4月5日

为了获得更高的可靠性,我最终对导致此编辑的以下帖子进行了回答:(请务必将其检出)


$ GLOBALS ['wp_the_query']与全局$ wp_query

到目前为止,我能想到的最可靠的方法是:

// 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
18 Mar 3 '18 at 21:12

#4 楼

获取子弹的简单方法是:

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


评论


这取决于永久链接设置。如果使用“简单”设置,则链接将看起来像http:// domain /?p = 123,而使您剩下?p = 123。

–Mene
16-10-14在10:36

@Mene是正确的,但是问题是如何获取段符,通常这意味着url中有一个(获取段p不是段符)。

–jave.web
2月17日在11:43



这是如此整洁的一线:D

– Sean Doherty
3月13日15:46

很好,很好:)

–Chaoley
10月21日3:46

#5 楼

给定代码示例,看起来您真正需要的是链接。在这种情况下,您可以使用get_permalink(),可以在循环外部使用它。这比使用子弹头更可靠地完成了您需要的操作。

评论


不过,这是完整的URL,而不仅仅是段。

–弗雷德
2014年11月21日15:09

#6 楼

可能是个老问题,但是我根据您的回答创建了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) );
    }
}


#7 楼

老实说,我不明白为什么没有一个答案会简单地做到:

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

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


这适用于所有帖子,页面,自定义路线。

评论


“老实说,我不明白为什么没有一个答案能做到:...”可能是因为$ wp-> request包含URL的完整路径部分,包括子文件夹。此代码仅适用于根级别的帖子/页面。

– FluffyKitten
5月8日,0:38



这是对这个问题的最好答案-在我尝试之前没有任何作用。

–克里斯
8月14日21:20

#8 楼

如果您希望获得更深入的了解,则可以使用以下SQL查询随时提取所有帖子,无论是帖子,页面还是自定义分类法,即使到目前为止还没有激发任何钩子。

原始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_loadedinit钩子之前。

@note

这是假定您具有标准数据库前缀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`;"


然后使用$wpdbmysqli或或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循环未达到要求的水平,也可以随时检查该信息。认为您的要求可以接受。这是由Wordpress核心本身运行的同一查询的稍微优化的版本。这个过滤器过滤掉了您不希望返回的所有垃圾,并为您提供了一个井井有条的列表,其中列出了相关的作者ID,帖子类型,子词和可见性。如果需要更多详细信息,则可以按常规使用new \WP_Post($id);来获取它们,或者将其他任何本机Wordpress函数与任何相关的表行一起使用,甚至在循环之外也可以。

我在几个自己的自定义主题和插件中使用了类似的设置,并且效果很好。它也很安全,不会在内部范围内浮动内部数据,就像在Wordpress中大多数内容一样可以覆盖内部数据。

#9 楼



get_post_field( 'post_name');


在这里找到答案:如何在WordPress中检索当前页面的子对象? br />

评论


确实,但是您需要传递$ post或帖子的ID作为第二个参数。

–火车头病
19-10-17在11:29

#10 楼

就@Matthew Boynes答案而言,如果您还有兴趣获得父子弹(如果有),那么我发现此功能很有用:

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


例如将子弹添加到主体类中:

function mytheme_body_class( $classes ) {
    if ( $slugs = mytheme_get_slugs() ) {
        $classes = array_merge( $classes, $slugs );
    }
    return $classes;
}
add_filter( 'body_class', 'mytheme_body_class' );


#11 楼

WordPress中的动态页面调用。

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