WordPress

WordPress wp_list_pages() でカスタムフィールドの値を表示する

サイドバーやフッターに、ページのリンク先を階層表現でリスト表示するテンプレート関数、wp_list_pages()がある。ul タグや li タグと共に、a タグでページのタイトル名がリンク表示される。

ところで自分が作成したプラグイン Download Leader を使って、ページに張られているダウンロードファイルのダウンロード数を前述の階層表示リンクに含めたい、というご要望をいただいた。

それを実現するために、先ずは登録されたダウンロードファイルのダウンロード回数だけを取得する機能を、プラグインに新たに追加した。後はダウンロードが張られているページのカスタムフィールド(例えばキー名をfilenameとする)にダウンロードのファイル名を登録し、WordPress ループ内でそのページから get_post_meta() を使ってファイル名を取り出し、プラグインの回数を取得する API 関数をコールすればよい。

WordPress ループの例は次の通りだ。

<?php
	if (have_posts()) :
		while (have_posts()) :
			the_post();
			echo mtsdl_download_data(get_post_meta($post->ID, 'filename', true), 'count');
		endwhile;
	endif;
?>

さて本題に戻る。

wp_list_pages() で表示されるページのリンク中に、そのページに関連するデータをダイナミックに含めるにはどうしたらいいのだろうか?具体的には、カスタムフィールドに登録されたファイル名からダウンロードされた回数を取得し、タイトル名の後ろに表示する方法だ。

get_page_children() を使って、自分で ul、li、a タグを出力する方法もあるが、もっと簡単に操作する方法があった。それは、タグを出力するクラスモジュールをオーバーライドする方法だ。

wp_list_pages() の引数に「walker」というパラメータがある。このパラメータにオーバーライドしたインスタンスを渡せばよい。タグを出力するクラスは「Walker_Page」で、「wp-includes/classes.php」にある。

このクラスのメソッドを眺めて見ると、リンクを出力するメソッド「start_el()」がある。そのメソッドには、タイトルの後ろに wp_list_pages()のパラメータ「link_after」で指定された文字を付加している行がある。これに細工をすれば、タイトルの後ろにダウンロード回数を挿入できそうだ。

Walker_Pageクラスを継承するクラスをテーマの functions.php に登録し、そのクラスで start_el() メソッドをオーバーライドする。

<?php
class Mts_Walker_Page extends Walker_page {

	function start_el(&$output, $page, $depth, $args, $current_page) {
		$args['link_after'] = ' (' . mtsdl_download_data(get_post_meta($page->ID, 'filename', true), 'count') . ')';
		parent::start_el($output, $page, $depth, $args, $current_page);
	}
}
?>

後は、テンプレートで wp_list_pages() を呼び出す直前に Mts_Walker_Page のインスタンス化を行い、wp_list_pages() に渡せばよい。

	<?php
		$mts_walker = new Mts_Walker_page;
		$children = wp_list_pages(array('child_of'=>$post->ID', 'echo'=>0, 'walker'=>$mts_walker));
		if ($children) { ?>
			<ul>
			<?php echo $children; ?>
			</ul>
		<?php }
	?>
 

ところでこの walker であるが、ビルトインで次の5つがあるそうだ。参照ブログ