現在のページのスラッグを取得するにはどうすればよいですか?


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
サリタッシュが言ったように、あなたはechoそれをする必要があります。したがって、これは理想的です<?php global $post; echo $post->post_name; ?>
。– its_me


68

他の回答によると、スラッグはpost_nameプロパティに保存されます。直接アクセスすることはできますget_post_field()が、適切なAPIを持たない投稿プロパティにアクセスするための(未使用の)関数を好みます。

明示的に提供された投稿が必要であり、デフォルトは現在の投稿ではないため、現在の投稿の全文は次のようになります。

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

12
それはあなたがループ内にある場合に使用できることは注目に値するget_post_field第二引数なし(ドキュメント
jmarceli

26

2016年4月5日編集

信頼性を高めるために掘り下げた後、私はこの編集につながる次の投稿にこの回答をすることになりました:(必ずチェックしてください

私が思い付く日までの最も信頼できる方法は次のとおりです。

// 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
メネ

8

コード例を考えると、本当に必要なのはリンクです。その場合は、ループの外側で使用できるget_permalink()を使用できます。ポストスラッグを使用するよりも、必要なことをより確実に行う必要があります。


4
ただし、これはスラッグだけでなく、完全なURLです。
フレッド14年

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


0

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

たとえば、slug(s)をbodyクラスに追加するには:

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クエリを使用して、まだフックが起動されていない場合でも、投稿、ページ、またはカスタム分類であるすべての投稿をいつでも取得できます。

生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で実行します。このクエリにはユーザー入力がないので、変数を注入しない限り、準備されたステートメントなしで実行しても安全です。mysqliPDO

これをクラスのプライベートな静的値として保存することをお勧めします。これにより、最高のパフォーマンスを得るためにページごとに複数回クエリを実行する必要なくアクセスできます。

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コア自体によって実行される同じクエリのわずかに最適化されたバージョンです。これは、返されたくないすべてのジャンクを除外し、関連する著者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.