WordPress Snippet

ワードプレスをカスタマイズしよう

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

query_posts

get_posts ( $args )

memo:setup_postdata()を使うなら、要リセットwp_reset_postdata();

get_posts

<?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();

?>

WP_Query

Tips: WP_Query()を使いページングを行うとき、そのままでは、next_posts_link()やprevious_posts_link()が動作しなくなります、その場合の対処法は

<div>
	<div class="left">
<?php 
	next_posts_link( __('&laquo; Older Entries', 'Raindrops' ), $the_query->max_num_pages ) 
?>
	</div>
	<div class="right">
<?php 
	previous_posts_link( __('Newer Entries &raquo;', '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>

ページネーション リンク

配列を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();
}