• このエントリーをはてなブックマークに追加

Youtube動画

はじめに

今日はかんたんなループの話

WordPressをインストールして、ちょっとカスタマイズしたくなった人に向けての話です。

メインループって?

ふつーに管理画面などに設定されたまま・インストールされたままの投稿を表示したい時。

トップページ(ホーム)のページやカテゴリー・日付などのアーカイブページ、検索結果、投稿の記事ページ(詳細ページ)など、
本来そのページに表示させる内容を繰り返して表示する時。

  • ホームならすべての最新の記事一覧のデータ
  • カテゴリーならそのカテゴリーに属している投稿の一覧のデータ
  • 投稿の記事ページはその記事の1件のデータ

といった、メインとなるループ(繰り返し)がメインループ。

サブループって?

ちょっと違うものを表示させたいな。って時。

えーと、それはどういう時?

  • 指定したカテゴリーに属している記事の一覧を表示したいーって時
  • このカテゴリーに属している記事は省きたい時
  • 日付の古い順に並べ替えたい時

などなど。

こういった時はテーマをカスタマイズしないと実現できないのでテンプレートファイルに追記したり自分で作ることになる。

というわけなのです。

ループってなに?

繰り返し処理。

簡単に言うと、

同じ形・同じ見た目で表示させるタイトルや日付などを繰り返して表示する。

WordPressでよく見かけるループの一つ。

アーカイブページ

現在表示している

  • カテゴリー
  • 日付(2019年とか、2019年6月とか)

に属している・設定されている記事を繰り返して表示。

各記事

投稿は1件分表示。

while

えーと、これは指定した条件の間(カッコ内の)処理を繰り返す。

条件が変化して繰り返しの条件が変わるとループを抜けて次に進む(次の処理)。

メインループなどでよく見かけるwhile

while (have_posts())

は次に投稿があるかどうかをwhile () で繰り返し

その中に入っているのが、

have_posts()

これは、次の投稿があるか調べる。

while (have_posts()){
// ここを繰り返す
}

インストールしたまま・カスタマイズしていない場合、普通は10回繰り返される。

繰り返すだけで何も表示されない。

while (have_posts()){
the_post();
?><h2><?php the_title(); ?></h2><?php
}

記事タイトルを10回繰り返す。

the_post();

は、次の投稿の情報を取得する。

これを行わないといつまでも繰り返し、1件目の記事が表示され続けて無限にループしてしまいます。

whileを使って表示するクエリ

  • メインクエリ
  • WP Query

foreach

こちらは同じく繰り返し。ふぉーいーち。

whileとの違いは、複数のデータが入った配列をもとに配列の数だけ繰り返して処理します。

foreach ( $myposts as $post ) {
// ここを繰り返す
}

配列である「$myposts」に入っているデータを1記事ずつ、$postに
代入(前に入れていたものを置き換えて入れる)する。

1回目は1件目の記事データ: 日付・タイトル・本文とか言った情報が$postに代入。

2回目は2件目の記事データ: 日付・タイトル・本文とか言った情報が$postに代入。

foreach ( $myposts as $post ) {
setup_postdata( $post );
?><h2><?php the_title(); ?></h2><?php
}

上記例では、そのあと

setup_postdata( $post );

して次(1件目の次なら2件目)の記事のセット・準備を行う。

ループの先頭に戻って、次に表示されるタイトルが2件目のタイトルが表示される。

といった感じです。

foreachを使って表示するクエリ

  • get_posts

さんぷる:デモ:WP_Query

<?php
// 条件
$args = array(
		'posts_per_page' => 3,
		'post_type' => 'post',
	);

$sample_query = new WP_Query( $args );

// The Loop
if ( $sample_query->have_posts() ) {
	echo '<ul>';
	while ( $sample_query->have_posts() ) {
		$sample_query->the_post();
		echo '<li>' . get_the_title() . '</li>';
	}
	echo '</ul>';
	/* Restore original Post Data */
	wp_reset_postdata();
} else {
	// no posts found
}
?>

WP_Queryで表示しています。

タイトルのみのリスト

最新最大3件。

サンプル

  • 日記タイトル3
  • 日記タイトル2
  • 日記タイトル1

さんぷる:デモ:WP_Query カテゴリーで絞り込み

<?php
// 条件
$args = array(
		'posts_per_page' => 3,
		'category_name' => 'diary',
		'post_type' => 'post',
	);

$sample_query = new WP_Query( $args );

// The Loop
if ( $sample_query->have_posts() ) {
	echo '<ul>';
	while ( $sample_query->have_posts() ) {
		$sample_query->the_post();
		echo '<li>' . get_the_title() . '</li>';
	}
	echo '</ul>';
	/* Restore original Post Data */
	wp_reset_postdata();
} else {
	// no posts found
}
?>

WP_Queryで表示しています。

  • さんぷるタイトル3
  • さんぷるタイトル2
  • さんぷるタイトル1

さんぷる:デモ:get_posts

ゲットポスツ。ポスト=投稿を取得する。

get_postsをつかったループ

最近の投稿あるいはパラメータに一致した投稿を取得

Codex

https://wpdocs.osdn.jp/%E3%83%86%E3%83%B3%E3%83%97%E3%83%AC%E3%83%BC%E3%83%88%E3%82%BF%E3%82%B0/get_posts

get_posts・WP Queryどちらを使う?

記述方法は違えど、やりたいことを満たせるならば、記述しやすい方法でどちらを使ってもOK

get_postsで済むならそちらで十分。get_posts内でWP Queryを使っている。

  • 複数ループする時
  • get_postsではできない処理を行う時

get_postsサンプルコード

<ul>
<?php
// 条件
$args = array(
				'posts_per_page' => 3,
				'post_type' => 'post',
			);

$sample_posts = get_posts( $args );
foreach ( $sample_posts as $post ) :
	setup_postdata( $post );
	?>
	<li>
		<?php the_title(); ?>
	</li>
	<?php
endforeach;
wp_reset_postdata();
?>
</ul>

query_postsについて

この関数はプラグインまたはテーマの中で使われることを想定されていません。

Codex

一般的な投稿の取得には、WP_Query または get_posts を使ってください。

Codex

https://wpdocs.osdn.jp/%E3%83%86%E3%83%B3%E3%83%97%E3%83%AC%E3%83%BC%E3%83%88%E3%82%BF%E3%82%B0/query_posts

query_postsテーマ・プラグイン側では使わない

テーマ・プラグイン側:
表示側では主にこちらのWordPressタグは使わない。

簡単に言うと、表示した各ページ・管理画面などで本来表示される値が変更されて、
違った内容となることがある。

ここだけ違った条件のものを表示したいとか、

1件だけ表示したいとか、

カテゴリーの絞り込みをしたいだとか、

もうちょっと複雑な条件で絞り込みたい時といったようなときは、
WP Queryやget_postsを使う。

発表内容はここまで

発表内容はここまで。

あとは補足用に用意していた内容ですが、話の中では分かりづらくなるかと思ったので、割愛しています。

リセットについて

リセットを行わないと、

乱暴に言うとおかしくなったまま:本来そのページで表示される・利用されるべきデータをもとに戻さないままになるので、そのあとの処理は場合により、意図しない表示内容となる。

どこが原因かわからなくなること・どうしたらいいのかわからなくなること、そのままにしておかないことが大事。

get_posts()&WP_Query()

wp_reset_postdata();

でリセットする。

query_posts()

基本的に、query_posts():こちらは使わない。

使ったあとは、

wp_reset_query();

で、リセットする。

メインクエリを変更する時は、query_posts()を使わず、

pre_get_posts

を使う。

$argsって?arguments

argumentsは引数(いんすう・ひきすう)。
※自分は誤解がないようにするために、話すときは「ひきすう」と言う。

サンプルで何者かぱっと分かるように説明の便宜上$argsとしているだけ

argument(あーぎゅめんと)の複数形なので、argではなくて、サンプルで見かける文字がargsとされている理由。

これは、ようするに、説明するために配列を指定していますよというのがパッと分かるようにしている作法と言うか、慣例なので、この名前じゃないと動かないわけではない。

任意の名称

あらかじめ他で用意されている名称:予約語 を避けて、
蕪なさそうな名前をつける。

なので、

名前は、

$toshima_array

とかでもOK。

カスタム投稿タイプで絞り込み

parts/query_last.phpを読み込んでます。

<ul>
<?php
// 条件
$args = array(
				'posts_per_page' => 3,
				'post_type' => 'toshima',
			);

$myposts = get_posts( $args );
foreach ( $myposts as $post ) :
	setup_postdata( $post );
	?>
	<li>
		<a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
	</li>
	<?php
endforeach;
wp_reset_postdata();
?>
</ul>

query_postsを使ってリセットしないとどうなるのか

// クエリをリセット
wp_reset_query();

今説明しているページはget_template_part();でパーツを読み込んでいるものを、
お見せしています。

C:\www\miewp.toshima\wp-content\themes\miewp\parts

リセットしないと…

query_postsが入っていると、

メインクエリが書き換わって処理されるため、
最大3件表示の指定したカスタム投稿タイプとなっちゃった。

  1. WP-PageNaviがおかしくなる
  2. サイドバーがおかしくなる

リセットすればいいといえばそうなのですが。

基本的に使わない

テーマやプラグインで使わないので、

  • サブループはWP Queryかget_posts
  • メインループを書き換えたい時はpre_get_posts

を使用すること。

このサンプルではあからさまにおかしいのがわかりますが、
分かりづらい問題にハマってしまうので使わない。

query_postsはあくまでコアの方で使われる関数。

感想

2回目の発表の場をいただきありがとうございました。

やっぱり画面を見ながらでも緊張しますね。次の言葉が出てこなくて、いっぱいいっぱいで、文章は何度か読み返したつもりでもなかなか自身が出てこないものですね。