基本 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();
}