web-dev-qa-db-ja.com

現在のページのスラッグを取得する方法

現在のWordPressページのスラッグをループの外に取り出そうとしています。ページのタイトルはwp_title ()で返されますが、どうすればスラッグを取得できますか?

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

グローバル変数 $post を使用します。

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

他の答えと同様に、slugはpost_nameプロパティに格納されています。に直接アクセスできますが、適切なAPIを持たない投稿プロパティにアクセスするには(未使用の)get_post_field()関数を使用します。

明示的に投稿を指定する必要があり、現在の投稿にデフォルト設定されていません。そのため、現在の投稿では次のようになります。

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

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%の確信を持っています。

もともとの答え

この問題に対するもう1つのより安全な代替方法は、現在照会されているオブジェクトを保持するget_queried_object()を使用して、post_nameプロパティーによって保持されるページスラッグを取得することです。これはあなたのテンプレートのどこでも使うことができます。

$postを使用することはできますが、カスタムクエリまたはカスタムコードが$postの値を変更する可能性があるため、信頼性が低くなる可能性があるため、ループ外では使用しないでください。

現在のページオブジェクトを取得するためにget_queried_object()を使用することは、メインのクエリオブジェクトを壊す邪悪なquery_postsを使用しているのでない限り、はるかに信頼性が高く、修正される可能性が低くなります。

あなたは以下のように上記を使用することができます

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

スラッグを取得する簡単な方法は、次のとおりです。

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

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

8
Matthew Boynes

古い質問かもしれませんが、私はあなたの答えに基づいて関数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) );
    }
}
2
Earlee

@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' );
0
bonger

私は正直に言って答えがどれも単純にしない理由を理解していない

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

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

これはすべての投稿、ページ、カスタムルートに有効です。

0
leymannx

これは、ループの外側でスラッグを取得したいときに使用する関数です。

get_post_field( 'post_name');

答えはここにあります: WordPressで現在のページのスラッグを取得する方法?

0
Kash

より詳細な回答が必要な場合は、次の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フックの前であっても、あなたのfunctionsファイルの一番最初の行でさえも働きます。

@注意

これは、標準のデータベースプレフィックス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のいずれかのインスタンスで実行します。このクエリにはユーザー入力がないため、変数を挿入しない限り、prepared statementを使用せずに実行するのが安全です。

これをクラスのプライベートな静的値として格納することをお勧めします。そのため、最高のパフォーマンスを得るためにページごとに2回以上クエリを起動することなくアクセスできます。

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のほとんどのものがそうするようにそれが上書きされることができるグローバルな範囲の中に浮遊する内部データを残しません。

0
mopsyd