基本 while
<?php if (have_posts()) : ?> <?php while (have_posts()) : the_post(); ?> //do stuff <?php endwhile; ?> <?php endif;?>
<?php if ( have_posts() ) { while( have_posts() ) { the_post(); // do stuff } } ?>
基本 foreach
<?php if( have_posts() ): ?> <?php foreach($posts as $post): ?> <?php setup_postdata($post);?> //do stuff <?php endforeach; ?> <?php endif; ?> <?php wp_reset_postdata( );?>
<?php if( have_posts() ){ foreach($posts as $post){ setup_postdata($post); } } wp_reset_postdata( ); ?>
ループで使う関数
*複数ループを使う時
<?php rewind_posts(); ?>
Call major cache updating functions for list of Post objects.
<?php update_post_caches($posts);?>
ループの前処理 Query
<?php $posts= query_posts(); //loop wp_reset_query(); ?>
get_posts ( $args )
memo:setup_postdata()を使うなら、要リセットwp_reset_postdata();
<?php // クエリ $the_query= new WP_Query( $args ); // ループ while ( $the_query->have_posts() ) : $the_query->the_post(); echo '<li>'; the_title(); echo '</li>'; endwhile; // 投稿データをリセット wp_reset_postdata(); ?>
Tips: WP_Query()を使いページングを行うとき、そのままでは、next_posts_link()やprevious_posts_link()が動作しなくなります、その場合の対処法は
<div> <div class="left"> <?php next_posts_link( __('« Older Entries', 'Raindrops' ), $the_query->max_num_pages ) ?> </div> <div class="right"> <?php previous_posts_link( __('Newer Entries »', 'Raindrops' ), $the_query->max_num_pages ) ?> </div> </div>
グローバル変数
$wp_the_query ..... WP_Query オブジェクト。URL のクエリーバックアップ用。 $wp_query ......... WP_Query オブジェクト。カレントのクエリー。 $posts ............ クエリーを実行して取得した記事オブジェクトの配列。 $post ............. カレントの記事オブジェクト。
クエリに関連するmemo
*pre_get_posts アクションフック
add_action( 'pre_get_posts', 'my_pre_get_posts' ); function my_pre_get_posts( $query ) { if ( ! is_admin() && is_category() ) { $query->set( 'posts_per_page', 20 ); $query->set( 'order', 'ASC' ); } }
WordPress ループ&クエリーのモヤモヤを解消しよう!
このフックは、wp-includes/query.php get_posts()のなかにあります。
Memo:書き方
if ( !$q['suppress_filters'] ) { // get_posts() はこれがデフォルトで true! ... apply_filters_ref_array( 'posts_where_paged', array( $where, &$this ) ); apply_filters_ref_array( 'posts_groupby', array( $groupby, &$this ) ); apply_filters_ref_array( 'posts_join_paged', array( $join, &$this ) ); apply_filters_ref_array( 'posts_orderby', array( $orderby, &$this ) ); apply_filters_ref_array( 'posts_distinct', array( $distinct, &$this ) ); apply_filters_ref_array( 'post_limits', array( $limits, &$this ) ); apply_filters_ref_array( 'posts_fields', array( $fields, &$this ) ); ... }
suppress_filters というパラメータはその名の通り、true に設定されているとフィルタを実行しません。WP_Query::&get_posts() や query_posts() を使うときは敢えて true を指定しない限り false になるので何も心配しなくてもフィルタ実行してくれます。が、get_posts() という素の関数ではデフォルトパラメータとしてこれが true という仕様なのでフィルタを使用したい場合は false を明示的に指定します。
query_posts, get_posts で複数の order 指定に対応する
ページテンプレートで、get_postsを使ったページング
<?php $posts_per_page = 6; //ページあたりのリンク件数 $paged = ''; $content = ''; $html_structure = '<li><a href="%1$s">%2$s</a></li>'; $html_list_wrapper = '<ul>%1$s</ul>'; $html_pagenate_links_wrapper= '<p class="pagenate_links">%1$s</p>'; $args_plus = array(); //$args_plus = array( 'category'=> '509,510' ); //カテゴリなどでの絞込は、ここに追加 $paged= get_query_var( 'paged' ); if ( !isset( $posts_per_page ) ) { $posts_per_page= get_option( 'posts_per_page' ); } $args = array( 'paged'=> $paged, 'posts_per_page'=> $posts_per_page, ); $args = array_merge( $args, $args_plus ); if ( !is_paged() ) { $args[ 'numberposts' ] = $posts_per_page; $paged = 1; } elseif ( $paged== 2 ) { $args[ 'offset' ]= $posts_per_page; } else { $args[ 'offset' ]= $posts_per_page * ( $paged - 1 ); } $paging_contents= get_posts( $args ); if ( $paging_contents ) { foreach ( $paging_contents as $q ) { $content .= sprintf( $html_structure, esc_url( $q->guid ), $q->post_title ); $content .= implode( wp_get_post_categories( $q->ID ) ); } printf( $html_list_wrapper, $content ); } /* Make pagenate links */ $pagenate_args = array( 'numberposts'=> -1 ); $pagenate_args = array_merge( $pagenate_args, $args_plus ); $total_content = get_posts( $pagenate_args ); $page_total = ceil( count( $total_content ) / $posts_per_page ); $pagination = array( 'base' => @add_query_arg( 'paged', '%#%' ), 'format' => '', 'total' => $page_total, 'current' => $paged, 'show_all' => false, 'type' => 'plain', 'end_size' => 0, 'mid_size' => 0, ); if ( $wp_rewrite->using_permalinks() ) { $pagination[ 'base' ]= user_trailingslashit( trailingslashit( remove_query_arg( 's', get_pagenum_link( 1 ) ) ) . 'page/%#%/', 'paged' ); } if ( $page_total - $paged >= 0 ) { printf( $html_pagenate_links_wrapper, paginate_links( $pagination ) ); } ?>
ページテンプレートでquery_postsを使ったページング
<?php $posts_per_page= 6; $paged= get_query_var('paged'); if( empty( $paged ) ) { $paged= 1; } if ( !isset( $posts_per_page ) ) { $posts_per_page = get_option('posts_per_page'); } $args= array( 'posts_per_page'=> $posts_per_page, 'paged'=> $paged ); query_posts( $args ); while ( have_posts() ) { the_post(); ?> <li> <a href="<?php the_permalink();?>"><?php the_title( );?></a> </li> <?php } posts_nav_link('|', '<span class="next">< next</span>', '<span class="prev">previous ></span>'); wp_reset_query(); ?>
おまけ Pearを使ったページングのサンプルコード
<?php require_once("Pager/Pager.php"); $totalItems= 100; $perPage= 10; $options= array( "totalItems"=> $totalItems, "perPage"=> $perPage ); $pager=& Pager::factory($options); $navi= $pager -> getLinks(); print($navi["all"]); $currentPageID= $pager -> getCurrentPageID(); $index= ($currentPageID - 1) * $perPage + 1; for($i= $index; $i < $index + $perPage ; $i++){ if ($i <= $totalItems){ print('<p>'.$i.'</p>'."\n"); } } ?> <p>現在のページ番号は <?php print($currentPageID); ?> です</p>
ページネーション リンク
- CODEX Pagination
- pagedとpageの違い
- CODEX is_paged()
- How to Add Numeric Pagination in Your WordPress Theme
配列をwhile文でループする
$dummy_posts= array( 'aa', 'bb', 'cc', 'dd', 'ee', 'ff', 'gg', 'hh', 'ii', 'jj' ); while ( list( $key, $post )= each( $dummy_posts ) ) { echo "---$post---"; }
foreach $key=>$val でループ
if ( have_posts() ) { foreach ( $posts as $key=> $post ) { the_post(); setup_postdata(); $count = $key + 1; $html = '<div class="count-%1$d">%2$s</div>'; printf( $html, $count, the_title( '<h2>', '</h2>', false ) ); } wp_reset_postdata(); }