WebTecNote

[WP]カスタムフィールドの値で記事を並び替える

質問された、カスタムフィールドで設定した値で記事を並び替えて表示するサンプルを晒してみる。
オススメ度とかでランキングっぽいことしたい時に使えるのか・・・な?
やってることはarray_multisortによる多次元配列のソートです。

サンプル関数の使い方は次の通りです。

  1. 記事にソート用のカスタムフィールドを作成
  2. 10進数の半角数字で値を入力
  3. テンプレートの表示したいところにサンプルのコードを入れる

以上。
サンプルソースは用途に応じて適当に変更するといいと思います。

参考ページ

追加

  1. 他のカスタムフィールドも表示したい場合
  2. ページナビゲーションによる分割表示

functions.phpとか

function sort_post_meta($m,$c){
	$myposts = get_posts('numberposts=5&cat='.$c);
	foreach ($myposts as $post){
		$meta = get_post_custom_values($m,$post->ID);
		$out[] =array('id'=>$post->ID,'title'=>$post->post_title,'guid'=>$post->guid,'rate'=>$meta[0]);
		$ar[] =$meta[0];
	}
	array_multisort($ar,SORT_NUMERIC,SORT_DESC,$out);
	return $out;
}

sort_post_meta($meta_key,$category_id)
$meta_key:カスタムフィールドのキー(文字列)
$category_id:カテゴリーID(整数)

get_postsで指定カテゴリの記事IDを取得して、get_post_custom_valuesでカスタムフィールドの値を取得します。
先頭だけ取得して配列に入れるので、複数在る場合は他の値が無視されます。
return用の配列に記事のタイトルとか入れて、array_multisortでカスタムフィールドの値を元に並び替え、
ソートし終わったら返す。という感じ。

配列に入れてる記事情報はID・タイトル・URLだけですが、get_posts()関数で返されるオブジェクトにあるものなら何でも追加できます。
面倒なら$out[]=$post;とかにしても良い。(この場合オブジェクトになるので出力の書き方がちと変わる)
また、並び替える基準も新しくソート用の配列を作れば「カスタムフィールドの値が重複した場合にタイトルを基準にする」、とかいうことも出来ます。
その辺は用途に応じてお好みでー。
なお、日本語の場合漢字が混じってるとソートの順序が微妙なので、並び替える基準とする値はひらがな・カタカナや半角英数が良いと思います。

index.phpとかのテンプレートファイル内

$array =sort_post_meta("star",7);

foreach ($array as $arr){
	print "★$arr[rate] <a href=\"$arr&#91;guid&#93;\">".$arr[title]."</a><br />";
}

出力結果▼

カスタムフィールドの値を数値にしとけば、下記のように応用が利く。

星の数で表現する例▼

$array =sort_post_meta("star",7);
$star = array('-','★','★★','★★★','★★★★','★★★★★');
foreach ($array as $arr){
	print "★".$star[$arr[rate]]." <a href=\"$arr&#91;guid&#93;\">".$arr[title]."</a><br />";
}

他のカスタムフィールドも表示したい場合

ソートとは別に”sample”というカスタムフィールドを記事に追加したので、これも一緒に表示したいとします。

上記のサンプルではカスタムフィールドのキーを並び替え用のものだけに限定してるので、
他のカスタムフィールドの値はどう頑張っても取得出来ません。
ですので他のカスタムフィールドも出力したい場合は以下のように変更します。

function sort_post_meta2($c){
	$myposts = get_posts('numberposts=5&cat='.$c);
	foreach ($myposts as $post){
		$meta = get_post_custom($post->ID);
		$out[] =array('id'=>$post->ID,'title'=>$post->post_title,'guid'=>$post->guid,'rate'=>$meta["rate"][0],'sample'=>$meta["sample"][0]);
		$ar[] =$meta["rate"][0];
	}
	array_multisort($ar,SORT_NUMERIC,SORT_DESC,$out);
	return $out;
}

一番重要な変更点はget_post_custom()です。
最初のサンプルで使用しているget_post_custom_value()はキー指定による値だけ返す関数でしたが、
get_post_custom()は記事に設定されているカスタムフィールドを全て配列形式で返します。

※キーの指定をしなくなるので、関数の引数はカテゴリー($c)だけになります。

この配列は$metaに代入されるので、
あとは出力用の配列$outに入れる配列へ欲しいやつだけ追加すればおk。

'sample'=>$meta["sample"][0]

出力サンプル

$array =sort_post_meta2(8);
foreach ($array as $arr){
	print "★$arr[rate] <a href=\"$arr&#91;guid&#93;\">".$arr["title"]."</a><br />".$arr["sample"];
}

ページナビゲーションによる分割表示

すごい今更ですが思い出しついでに書いてみたので晒しときます…。
上のソースをベースにしてますが、ナビゲーション表示する関係で出力も全部関数内に移してあります。

//$c=カテゴリID $ppp=1ページあたりの表示数
function sort_post_meta3($c,$ppp=5){
	$myposts = get_posts('numberposts=-1&cat='.$c);
	foreach ($myposts as $post){
		$meta = get_post_custom($post->ID);
		//表示したいデータ($post=記事 $meta=カスタムフィールド)
		$out[] =array('id'=>$post->ID,'title'=>$post->post_title,'guid'=>$post->guid,'rate'=>$meta["rate"][0],'sample'=>$meta["sample"][0]);
		$ar[] =$meta["rate"][0];
	}
	$total = count($out);
	
	array_multisort($ar,SORT_NUMERIC,SORT_DESC,$out);
	
	$spm = wp_html_excerpt($_GET["spm"],3);
	$start = 0;
	$max = $ppp;
	
	if(isset($spm)&&$spm>=2){
		$start =($spm-1)*$ppp;
		$max = $s+($ppp);
		$out = array_slice($out,$start,$max);
	}else{
		$out = array_slice($out,$start,$max);
	}
	
	//出力
	foreach ($out as $arr){
		print "★$arr[rate] <a href=\"$arr&#91;guid&#93;\">".$arr["title"]."</a><br />";
	}
	
	global  $wp_rewrite;
	$paginate_base = '%_%';
	if (strpos($paginate_base, '?') || ! $wp_rewrite->using_permalinks()) {
		$paginate_format = '';
		$paginate_base = add_query_arg('spm', '%#%');
	} else {
		$paginate_format = (substr($paginate_base, -1 ,1) == '/' ? '' : '/') .
		user_trailingslashit('spm/%#%/', 'spm');
		$paginate_base .= '%_%';
	}
	//ナビゲーション
	echo paginate_links( array(
	'base' => $paginate_base,
	'format' => $paginate_format,
	'total' => $total/$ppp,
	'current' => ($spm ? $spm : 1),
	));
}

yurikoさんが書いたソースまるっと流用してますん。

2番目の引数(1ページあたりの表示数)は省略可

sort_post_meta3(8);

あんまり検証してないのでおかしいところがあったら教えてください

モバイルバージョンを終了