WordPressのテンプレートタグ、the_*()とget_the_*()の違い

WordPressのテンプレートタグ、the_*()とget_the_*()の違い

ほんとうに今更なのですが、表示するthe_*()と、取得するget_the_*()というテンプレートタグの意味がようやくちゃんと理解できた気がするので、自分なりにまとめてみました!


初心者のつまづき

WordPressのカスタマイズ方法は、たくさんの方がコードを公開してくださっていて、phpを初めて触ったようなわたしでも、「こんなことしたいな」と思うことを検索して、更にそれをちょこっと自分好みに、ということならわりと簡単にやってこれました。

でも、どうせならちゃんと理解したい、いつかはコピペに頼らずに…!という想いでコードを眺めているなか、疑問のひとつだったのがthe_*()get_the_*()の違いでした。

表示と取得

Codexだと大抵、the_*()は「~を表示する」、get_the_*()は「~を取得する」と書いてあります。

この上なく明確な説明なのですが、phpに不慣れなわたしは、恥ずかしながら「表示」と「取得」の使いどころの違いが曖昧でして…。それが、ここ最近やっと「こういうことだったのか!」という思いに至ることができました。

後述しますが、すべてのテンプレートタグに当てはまるわけではないので、「だいたいこんな感じ」というニュアンスで捉えていただけると有難く思います。

「the」とは?

Codexには、theがつくテンプレートタグの説明には、大抵「ループの中で使う」と書いてあります。まずはgetの有無を一旦置いといて、theが一体どういうものなのか、一番基本のメインループと一緒におさらいしてみます。

メインループ

<?php if (have_posts()) : //該当記事の有無 ?>
	<?php while (have_posts()) : the_post(); //記事の該当回数、繰り返し ?>
		<?php the_title(); //タイトル ?>
		<?php the_post_thumbnail(); //サムネイル ?>
		<?php the_content(); //本文 ?>
	<?php endwhile; //繰り返し処理終了 ?>
<?php else : //該当記事がなかった場合 ?>
	<p>記事がありませんでした</p>
<?php endif; ?>

WordPressでは、このループで記事を出力しています。(実際にはレイアウト用のいろんな要素を含みますが、ここでは割愛しています。)

140306-1

例えばトップページなどでは、いくつ記事を表示するか、ダッシュボードのこの画面で指定していますよね?先ほどのループで、この回数を繰り返しているわけです。

140306-2

このブログのトップページで表すとこんな感じ。上記で示した3~5行目が、指定回数繰り返されています。

でも、ちょっと不思議だと思いませんか?the_title()the_post_thumbnail()the_content()という、(php上では)同じことしか書いていないのに、それぞれ違ったタイトルや本文が出力されています。

ループの中の現在地が「the」!

ここで言うtheは、「ループ内の○回目の」というような意味なんじゃないかなと思います。

140306-3

だから、毎回違った内容を出力してくれるんですねー!

そもそもtheって、「その」「あの」「例の」といったニュアンスですよね。Codexにはよく「現在の」という形で書いてありますね。なるほど、「ループの中で使う」というのはこういうことだったのかー。

1個しかなくてもループを使っている

それと、今ご覧頂いているこの単一記事や、固定ページなども上記のメインループで出力されています。ループって聞くと複数出てきそうな気がしちゃいますが、各記事はループの中で該当記事がひとつしかない、というイメージです。

だから、単一記事や固定記事でもthe_title()などが使えるんですね。

メインループとサブループ

さて、ここまで紹介してきたメインループは正直あんまり意識しなくても使っているし、知らなくてもブログは書けます。でも、もっとカスタマイズしたいという気持ちが芽生えてきますよね。例えば、記事の終わりに関連記事を何件か出してみたり、フッターやサイドバーに新着記事やランダムに記事を出してみたり。これらも、ループを使って出力します。

こういった目的のものはメインループに対してサブループと呼ばれ、get_posts()、またはWP_Query()という関数を使って出力するのが一般的です。

WP_Query()のほうが指定しなければならないパラメーターが多いみたいです。でも書き方はメインループと似ていて、なんとなく玄人好みな印象。

例:get_posts()で新着記事5件

php

<ul>
<?php
global $post;
$args = array( 'posts_per_page' => 5 );
$myposts = get_posts( $args );
foreach( $myposts as $post ) {
	setup_postdata($post);
	?>
	<li><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>
	<?php
}
wp_reset_postdata();
?>
</ul>

このように書いてみると、リスト形式で新着記事を5件表示してくれます。9行目が繰り返される部分です。書く場所は、サイドバーでもフッターでも、メインループの中でも外でも大丈夫です。

html

<ul>
	<li><a href="URL1">タイトル1</a></li>
	<li><a href="URL2">タイトル2</a></li>
	<li><a href="URL3">タイトル3</a></li>
	<li><a href="URL4">タイトル4</a></li>
	<li><a href="URL5">タイトル5</a></li>
</ul>

出力されたhtmlはこのようになります。ここでも、theはループ内の現在地の値を、その回数分だけ出力してくれていますよね。

the_*()とget_the_*()の違い

では、やっと本記事のタイトルに迫ってみます。

the_*()

php

この記事のタイトルは「<?php the_title(); ?>」です。

こちらのコードを任意のphpファイルのループ内に書いてみてください。

どこに書いたらいいの…!という方は、単一記事や固定ページのメインループ内あたりが分かりやすいかもです。

html

この記事のタイトルは「XXXXXXX」です。

出力されたhtmlには、このように該当記事のタイトルが書かれているはずです。

get_the_*()

php

この記事のタイトルは「<?php get_the_title(); ?>」です。

では、今度はgetをつけてみましょう。htmlを見てみると…?

html

この記事のタイトルは「」です。

記事タイトルが出てこなくなってしまいました。何故でしょうか?これは、getが(一般的に)「取得」するタグだからなんです。

表示と取得

WordPressはphpという言語で動いていて、様々な条件分岐によってその都度適した形のhtmlを出力してくれます。この条件分岐などの内部的な処理は、htmlに出力されない形で行います。(全部出力されちゃったら困りますよねw)

この内部的に使われる、出力されない形として保持するのが「取得」なんです!

  • the_*()… 表示 → htmlへ出力する形
  • get_the_*()… 取得 → 内部処理に使われる形

ざっくり言うと、こんな感じ。ちなみに、取得した値も出力してあげれば表示することができます。

php

この記事のタイトルは「<?php echo get_the_title(); ?>」です。

さっきのコードに「出力する」という意味のechoを加えてやると、

html

この記事のタイトルは「XXXXXXX」です。

このようにthe_*()と同じ結果が得られます。

140306-4

イメージ的にはこんな感じでしょうか。

追記:html上では同じ結果に見えても、場合によっては安易にgetをつけるのは危ないこともあるぞ、ということを後述してありますので、ぜひそちらもご参照ください。

表示と取得の使い分けの例

比較に使う

先日書いたこの記事のコードを例に見てみると、

<div id="publishing">公開日:<time datetime="<?php the_time('c'); ?>"><?php the_time('Y/m/d'); ?></time></div>
<?php if (get_the_time('Ymd') < get_the_modified_time('Ymd')): ?>
	<div id="update">更新日:<?php the_modified_time('Y/m/d'); ?></div>
<?php endif; ?>

2行目は、公開日と更新日を比較している部分です。条件を満たさなければ3行目は表示しないという、条件分岐になっています。内部処理なので、get_the_*()を使います。

1行目と3行目では、それぞれ公開日と更新日を「表示」するので、the_*()を使っています。

引数に使う

例えば、サムネイルを表示するこのテンプレートタグ。

<?php the_post_thumbnail(); ?>

このままでも表示はされますが、画像の大きさを指定したいなーとか、altに記事タイトルを入れたいなー、という場合。

<?php the_post_thumbnail( array(100, 100), array('alt' => get_the_title()) ); ?>

the_post_thumbnail()は「表示」の形ですが、カッコ内に入れる引数のget_the_title()は「内部処理される形」でないといけません。

ちなみに、get_the_*()を使うべき内部処理の場所に、出力のthe_*()を書いてしまうと、処理がうまく走らない上に、html上の変なところにthe_*()の内容が出力されたりします。(よくやりますw)

重要な追記

大変重要なことを教えて頂けました!こちらの記事にあるとおり、

  • WordPressでget_*()を使うときは念のためソースを確認して適切に処理すべし! | firegoby
the_*()の値とget_*()の値は必ずしも同じじゃないことに注意しよう!

先ほどの例のように、htmlの出力だけだと同じように見えることも、内部では同じ動きをしていないこともある、ということです!

the_*()get_*()の値は必ずしも同じとは限らない上に、セキュリティ上重要な処理が抜け落ちたりしますので、get_*()関数を使いたくなったら、その前にthe_*()のソースをきっちり確認する習慣を身につけましょう。

「取得値が欲しいから安易にgetつけちゃえ」だと、場合によってはセキュリティリスクの発生が起こる可能性もあるとのことなので、必ずどのような動きをしているか確認してから使わなければいけませんね!ご指摘くださって大変有難いです!

例外もたくさん

さて、ここまで書いてきてしまいましたが、全部のテンプレートタグがこの法則に当てはまるというわけでもないのです…。

ループ外でもtheを使えるものもある

例えばこちらのフォーラムを拝見すると、get_the_ID()はループ外でも使えるみたいです。

「ループ内の現在位置」じゃなく、「現在表示している記事IDの」という意味で使いたい時、という感じですね。

タグごとに書き方が違いそうですが、かっこの中に$post->IDを入れてやると、ループ外でも「現在表示している記事IDの」という意味になるんじゃないかなーと。

とはいえ、「ループの中で使う」と明示されているものは、やはり基本はループ内で使うのが無難なようです_(:3 」∠)_

get_the_が存在しないタグもある

例えばですが、パーマリンクに関するタグは、the_permalink()はあるのにget_the_permalink()はなくて、get_permalink()ならあるんです。

これは、前述のセキュリティリスクのことに関係があるのかな…、と、なんとなく。

getだけど出力するのもある

例えば、get_calendar()getと書いてありますが、これだけでカレンダーの出力をしてくれたります。

これらの情報は2014年3月現在で、今後のバージョンアップなどによりテンプレートタグの追加や書き方が変更になる可能性がおおいにあります。

その都度Codexで書き方を参照する!

いろいろ書いてみましたが、つまりはこの一言に尽きるのではないかと…。身も蓋もないですが_(:3 」∠)_

わたしのこの記事の記述で、間違ってたり不適切な部分がありましたらご指摘くださると大変ありがたいです!

教えていただきました!

get_the_*とget_*

なるほど…theの有無でまた違ってくるのですね。いつも本当に勉強させていただいております、ありがとうございます!

以上、私的まとめでした

いかがでしたでしょうか。分かっている方には今更なことだと思うのですが、少なくともわたしはこの違いが理解できてから、Codexなどに書いてあることの理解度も高まり、「こう書けばいいはず」というコードの予想が立てられるようになってきました。

分からないことが分かるようになるのって、楽しいな…!WordPress、楽しいな…!(*´ω`*)

公開日:2014/03/06
更新日:2014/03/07

1件のピンバック

  1. […] WordPressのテンプレートタグ、the_*()とget_the_*()の違い *Ateitexe […]

2件のコメント

  1. yuutoooo より:

    恐ろしいくらいわかりやすかったです!
    ありがとうございます!^^

    • *you より:

      yuutooooさん、コメントありがとうございます! かなり前に書いたものですが、いまでもお役に立てて嬉しいです~!


コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください

コメントは承認制ですので、反映までしばらくお待ち下さい。(稀にスパムの誤判定にて届かないこともあるようですので、必要な際はお問い合わせからお願い致します。)

YouTubeでQ&Aコンテンツを企画しています

運営しているYouTubeチャンネルで、ご相談やご質問を募集しています。動画のコメントやお問い合わせページからお気軽にご相談をお寄せください。