WordPress Logo WordPress スラッグ(slug)を取得

更新日:2019年03月24日

作成日:2019年03月15日

スラッグの取得

スラッグ(slug)は、投稿や固定ページなどのページの固有の識別子として登録される値で、ページの識別子として URL の一部(最後の部分)に使われます。また、パーマリンクの設定によってその値は変わってきます。

ループの中でスラッグを取得

テンプレートで現在表示されている投稿や固定ページのスラッグを取得するには、以下のような方法があります。

スラッグは投稿オブジェクト(global $post)の post_name プロパティから取得できます。

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

ループの中では投稿オブジェクトは既に the_post() により宣言されているので、以下のように単に $post の post_name プロパティとして取得できます。

<?php if(have_posts()) : ?>
  <?php while(have_posts()) : the_post(); ?>
      ・・・
   <?php $slug = $post->post_name; ?><!-- スラッグを $slug に代入 -->
      ・・・
  <?php endwhile; ?>
<?php endif; ?>

get_post() に投稿の ID を渡して取得した投稿オブジェクトから取得することもできます。

以下は get_post() に get_the_ID() を使って現在の投稿の ID を渡してスラッグを取得しています。

<?php 
  $slug = get_post( get_the_ID() )->post_name;
?>

以下は get_post_field() の投稿のフィールド名に post_name を指定してスラッグを取得しています。

<?php 
  $slug = get_post_field( 'post_name', get_post() ); 
  //または
  $slug = get_post_field( 'post_name', get_the_ID() );
?>

以下は PHP の basename() を使って get_permalink() で取得した URL からスラッグを取得しています。※パーマリンクの設定に依存します。

<?php 
$slug = basename( get_permalink() );
?>
get_the_ID()

上記で使用している get_the_ID() は現在の投稿の ID を取得を取得する関数です。

日本語Codex には「このタグは、ループの中でのみ使用することができます。」と記載されていますが、ループの外でも ID を取得できる場合が多いです。

但し、ループの外だと記述する場所によっては $post が書き換えられている場合など、意図通りの動作をしない可能性があるようです。

get_the_ID() のソースは以下のようになっています。

function get_the_ID() {
  $post = get_post();
  return ! empty( $post ) ? $post->ID : false;
}
ループの外で ID を取得

ループの外で現在の投稿の ID をより確実に取得するには、以下のように $wp_query から get_queried_object_id() を使って取得すると良いかと思います。

<?php
  global $wp_query;
  $my_post_id = $wp_query->get_queried_object_id();
?>
カテゴリーのスラッグの取得

カテゴリーのスラッグは、カテゴリーオブジェクトの category_nicename プロパティから取得することができます。

カテゴリーは複数設定されている可能性があるので、get_the_category() により取得されるのは、カテゴリーオブジェクトの配列になっています。

属するカテゴリーが1つだけの場合は、単純に最初の配列の要素の category_nicename プロパティから取得すことができます。

<?php     
  $category = get_the_category();
  $slug = $category[0]->category_nicename;  
?>

ループの中では以下のようにしてその投稿に設定してある最初(一番小さいカテゴリ ID)のカテゴリーのスラッグを取得できます。

get_the_category() の引数「投稿ID」を省略した場合は現在の投稿データの投稿IDが適用されます。

<?php if(have_posts()) : ?>
  <?php while(have_posts()) : the_post(); ?>
    ・・・
    <?php     
      $category = get_the_category();
      $slug = $category[0]->category_nicename;  
    ?>
   ・・・
  <?php endwhile; ?>
<?php endif; ?>

属するカテゴリーを全て取得するには、foreach() を使います。

<?php     
  global $post;
  $slugs = [];  //スラッグを入れるの配列の初期化
  foreach ( ( get_the_category( $post->ID ) ) as $category ) {
    array_push($slugs, $category->category_nicename);
  }
?>
タグのスラッグの取得

タグのスラッグは、タグオブジェクトの slug プロパティから取得することができます。

タグは複数設定されている可能性があるので、get_the_tags() により取得されるのは、タグオブジェクトの配列になっています。

属するタグが1つだけの場合は、単純に最初の配列の要素の slug プロパティから取得すことができます。

但し、カテゴリーは必ず投稿に設定されていますが、タグは設定されていない場合もあるので、タグオブジェクトが存在する場合のみスラッグを取得しています。

<?php 
  $posttags = get_the_tags(); 
  if($posttags[0]) {
    $slug = $posttags[0]->slug; 
  }
?>

付けられているタグを全て取得するには、foreach() を使います。

但し、タグは設定されていない場合もあるので、タグオブジェクトが存在する場合のみスラッグを取得しています。

<?php     
  global $post;
  $tags = [];  //タグを入れるの配列の初期化
  if( get_the_tags( $post->ID ) ) {
    foreach ( ( get_the_tags( $post->ID ) ) as $tag ) {
      array_push($tags, $tag->slug);
    }
  }
?>

ループの外でスラッグを取得

前述の方法でもループの外で問題なくスラッグを取得できることもありますが、何らかの理由で($post が書き換えられている場合など)期待どおりに値を取得できない場合があるかも知れません。

ループの外でスラッグをより確実に取得するには、$wp_query から get_queried_object() を使ってページやカテゴリーのオブジェクトを取得して、そのオブジェクトからスラッグを取得します

get_queried_object() は以下のような現在クエリされているオブジェクトを取得します。

  • 単一投稿ページを表示中なら、投稿オブジェクト。
  • 固定ページを表示中なら、固定ページのオブジェクト。
  • カテゴリーアーカイブを表示中なら、カテゴリーオブジェクト。
  • 投稿者アーカイブを表示中なら、投稿者オブジェクト。

以下は get_queried_object() で現在表示しているページのオブジェクトを取得して post_name や category_nicename プロパティからスラッグを取得する例です。

<?php 
  global $wp_query;
  $post_obj = $wp_query->get_queried_object();
  $slug = $post_obj->post_name;  //投稿や固定ページのスラッグ
  $cat_slug = $post_obj->category_nicename;  //カテゴリーアーカイブページのスラッグ
  $tag_slug = $post_obj->slug;  //タグアーカイブページスラッグ
?>

以下は wordpress.stackexchange.com に掲載されていた方法です。

$GLOBALS['wp_the_query'] は global $wp_query のオリジナルの(変更されていない)コピーです。($GLOBALS['wp_the_query'] vs global $wp_query

<?php 
  // 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;
  $cat_slug = $current_page->category_nicename; 
  $tag_slug = $current_page->slug;
?>

スラッグを id や class として出力

WordPress には body 要素のページ種類に応じた class 属性を出力する便利な body_class() と言う関数がありますが、ページ種類に応じた id 属性を出力する関数はありません。

以下は個別ページ(投稿、カスタム投稿、固定ページ、添付ファイル)やカテゴリーとタグアーカイブページの場合に、スラッグを id として出力する独自の関数を作成する例です。

スラッグは念のため $wp_query のバックアップが入っている $GLOBALS['wp_the_query'] から get_queried_object() を使ってページやカテゴリーのオブジェクトを取得してから取得しています。

但し、全てのページの種類に対応していないのでサイトに合わせて条件分岐タグを使ってページの種類により取得及び出力する id を追加したり、不要な条件を削除するなどの必要があるかと思います。

スラッグを id として出力

フロントページの場合は、「設定」→「表示設定」の「ホームページの表示」で「固定ページ」を選択して「ホームページ」を設定してある場合はその固定ページのスラッグを id の値とし、そうでない場合は id の値は「top」にしています。

また、検索ページの場合で該当ページがある場合の id の値は「search-results」に、該当ページがない場合の id の値は「search-no-results」に、404ページの場合は id の値は「error404」にしています。

以下の関数は、スラッグ($slug)を取得してその値を esc_attr() でエスケープ処理し、その値が問題なく取得できていれば id="スラッグ名"として出力しています。値が空の場合は、何も出力しません。

以下は functions.php に記述します。

function my_body_id() {
  $post_obj =  $GLOBALS['wp_the_query']->get_queried_object();
  $slug = '';
  if(is_front_page()) {
    $slug = 'top';
    if(is_page() && get_post( get_the_ID() )->post_name) {
      $slug = $post_obj->post_name;
    }
  } elseif (is_category()) {
    $slug = $post_obj->category_nicename;
  }  elseif (is_tag()) {
    $slug = $post_obj->slug;
  } elseif ( is_singular() ) {
    $slug = $post_obj->post_name;
  } elseif (is_search()) {
    $slug  = $GLOBALS['wp_the_query']->posts ? 'search-results' : 'search-no-results';
  } elseif ( is_404() ) {
    $slug = 'error404';
  } 
  $body_id = esc_attr($slug);
  echo ( $body_id ) ? 'id="' . $body_id . '"' : '' ;
}

使い方は body_class() と同じように、テンプレートに以下のように記述します。出力される値の前後にスペースはないので適宜スペースを入れる必要があります。

<!-- スラッグを id として出力  -->
<body <?php my_body_id(); ?>>

<!-- WordPress の body_class() と併用する例  -->
<body <?php my_body_id(); ?> <?php body_class(); ?>>

ページが条件分岐に該当しない場合など、id が出力されない場合もあるので、出力する値の前後にスペースを付けた方が使いやすいかもしれません。

スラッグを class として出力

以下は、スラッグを class として出力する例です。

前述の id として出力する例とほぼ同じですが、カテゴリーアーカイブページの場合は cat と言うクラスを、タグアーカイブページの場合は tag と言うクラスを追加し、個別ページの場合は post(投稿の場合)や page(固定ページの場合)など投稿タイプのクラスを追加して出力しています。

こちらも id の出力の場合と同様に、サイトに合わせて出力する class を追加したり削除する必要があるかと思います。

以下は functions.php に記述します。

function add_my_class() {
  $post_obj =  $GLOBALS['wp_the_query']->get_queried_object();
  $slug = '';
  if(is_front_page()) {
    $slug = 'top';
    if(is_page() && get_post( get_the_ID() )->post_name) {
      $slug = $post_obj->post_name;
    }
  } elseif (is_category()) {
    $slug = 'cat ' . $post_obj->category_nicename;
  } elseif (is_tag()) {
    $slug = 'tag ' . $post_obj->slug;
  } elseif ( is_singular() ) {
    $slug = $post_obj->post_type . ' ' . $post_obj->post_name;
  } elseif (is_search()) {
    $slug  = $GLOBALS['wp_the_query']->posts ? 'search-results' : 'search-no-results';
  } elseif ( is_404() ) {
    $slug = 'error404';
  } 
  $my_classes = esc_attr($slug);
  //出力する値の前にスペースを入れてある
  echo ( $my_classes ) ? ' class="' . $my_classes . '"' : '' ;
}

使い方は、テンプレートに以下のように記述します。出力される値の前にスペースが入っています。

<div id="side"<?php add_my_class(); ?>>
          
<!-- スラッグが music のカテゴリーのアーカイブページの場合の出力例 -->                 
<div id="side" class="cat music">

以下は投稿の個別ページの場合は、属する全てのカテゴリーのスラッグを追加する場合の例です。

function add_my_class() {
  $post_obj =  $GLOBALS['wp_the_query']->get_queried_object();
  $slug = '';
  if(is_front_page()) {
    $slug = 'top';
    if(is_page() && get_post( get_the_ID() )->post_name) {
      $slug = $post_obj->post_name;
    }
  } elseif (is_category()) {
    $slug = 'cat ' . $post_obj->category_nicename;
  } elseif (is_tag()) {
    $slug = 'tag ' . $post_obj->slug;
  } elseif ( is_singular() ) {
    $slug = $post_obj->post_type . ' ' . $post_obj->post_name;
    if(is_single()) {  //投稿の個別ページの場合(追加部分)
      global $post;
      foreach ( ( get_the_category( $post->ID ) ) as $category ) {
        $slug .= " ". $category->category_nicename;
      }
    }
  } elseif (is_search()) {
    $slug  = $GLOBALS['wp_the_query']->posts ? 'search-results' : 'search-no-results';
  } elseif ( is_404() ) {
    $slug = 'error404';
  } 
  $my_classes = esc_attr($slug);
  echo ( $my_classes ) ? ' class="' . $my_classes . '"' : '' ;
}