カテゴリー : 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つがあるそうだ。参照ブログ

WordPress ウィジェットの登録 widgets_init と init アクションフック

WordPress のプラグインを作るに当たって、オブジェクトをどこでインスタンス化するか悩む。

プラグインがロードされるタイミングの他、WordPressの各種機能が動作する際、それら機能にフックすることでも起動タイミングを掴むことができる。アクションフックのおおよその順番は、Plugin API/Action Reference に記されている。

自分としては、WordPressの大方の初期化が終了したところでインスタンス化したいと考え、「init」アクションフックを利用して自分の初期化処理を押し込めている。同様に管理画面では「admin_init」で、としたいのだがこれはうまくいかない。

さて本題のウィジェットであるが、ウィジェットを登録する際「widgets_init」というフックを利用するのだが、「init」フック処理の中でこれを呼び出しても機能しないので注意が必要だ。

なので、プラグインロード時にフックして動作するようにさせた。処理の順番については、意外と気を付けなければならない。

(WordPress 3.0.3)

WordPress 子テーマがカレントのときのテンプレートディレクトリの取得

プラグインを制作中、カレントテーマの URI を取得する必要が生じた。ところが、API 関数の「get_template_directory_uri()」を利用すると、カレントが子テーマであっても親テーマのパスを戻してくる。

Codex のドキュメントをよく読むと、子テーマが使われている場合は「get_stylesheet_directory_uri()」を使うようにとの事。時間を潰してしまった。

ところが暫くして、カレントテーマのディレクトリを取得する必要が生じた。これまた、「get_template_directory()」は親テーマのパスを戻すので、「get_stylesheet_directory()」を使わなければならない。ここでも、時間を潰してしまった。

で、ブログに備忘録として残しておこうかと。

情けない… orz

wordpress 3.0.1

WordPress 3.0.1 カスタム投稿タイプのパーマリンクでNot Found

カスタム投稿タイプを定義して投稿データを入力し、いざ表示しようとしたら無情にも「ファイルが見つかりません」の表示。

register_post_type()のパラメータである publicly_queryable、query_var、rewrite や、[管理画面]-[設定]-[パーマリンク設定]の変更、テーマの切り替えなどさんざん変更して試してみるも解決しない。

ただし、パーマリンク設定でデフォルトの状態で


http://example.com/?custom_post_name=slug

であれば、ページを表示する事ができた。同様に、query_var を利用してのクエリー指定だとページの表示ができた。

自分がリンク表示したいのは、


http://example.com/custom_post_name/slug

なのだが。

で、解決方法は、カスタム投稿タイプを登録する際「flush_rewrite_rules(false)」を実行したことだった。ようやくパーマリンクで表示するようになった(引っ張りすぎてゴメンナサイ)。

flush_rewrite_rules()のソースを見てみたが、オプションテーブルに登録された「rewrite_rules」を削除する程度の処理しかしてないようで、原因はよく分からない。動作するようになったので、それで「良し」とした。

解決方法を示してくれたページ
Custom Post Types display only 404

パーマリンクのクエリー指定を解り易く解説してくれたページ
Custom Post Type Permalinks

WordPress 3.0 アイキャッチ画像とTwentyTenテーマ

カスタム投稿タイプを調べている際、編集ページで title や edit 以外に「thumbnail」というのがあり、それが「アイキャッチ画像」という名称で編集ページ上に表示されていた。

使い方は、例えば TechCrunch JAPAN サイトのように、トップページで複数の記事を表示する際、1つの記事に導入文章(WordPressでは抜粋)と共に小さめの画像を表示するレイアウトが作り易いように、という事だと思われる。

WordPress のデータとしては、1つの記事に1つの画像を紐付けして、一覧表示や詳細表示で手軽に画像が表示できる機能として提供されているものであるようだ。記事中の画像リンクとは、異なった方法で表示指定する。

Twenty Ten テーマでの使われ方

Twenty Tenでは、サイト表示のヘッダーで 940×198ピクセルの画像が表示されるようになっている。そしてこの画像は、「管理画面-ヘッダー」で予め提供されている画像を選択したり、あるいは自分でアップロードした画像(トリミングもできる)を指定できる。

ところで、「header.php」テンプレートを見ると、56行目から次のようにプログラミングされている部分がある。

<?php
	// Check if this is a post or page, if it has a thumbnail, and if it's a big one
	if ( is_singular() &&
		has_post_thumbnail( $post->ID )  &&
		( /* $src, $width, $height */ $image = wp_get_attachment_image_src( get_post_thumbnail_id( $post->ID ), 'post-thumbnail' ) ) &&
		$image[1] >= HEADER_IMAGE_WIDTH ) :
			// Houston, we have a new header image!
			echo get_the_post_thumbnail( $post->ID, 'post-thumbnail' );
	else : ?>
		<img src="<?php header_image(); ?>" width="<?php echo HEADER_IMAGE_WIDTH; ?>" height="<?php echo HEADER_IMAGE_HEIGHT; ?>" alt="" />
	<?php endif; ?>

どうやら

記事1件の表示で
かつ アイキャッチ画像が登録されており
かつ イメージの幅が940(HEADER_IMAGE_WIDTH)ピクセル以上

ならば、サイトのヘッダーに「get_the_post_thumbnail()」でアイキャッチ画像を表示する仕掛けとなっているようだ。実際試してみたところ、次のように表示された。

アイキャッチ画像を利用するために

テーマの「functions.php」で、次のような設定をする必要がある。

  • テーマで利用できるように機能の有効化を行なう
    <?php add_theme_support(‘post-thumbnails’); ?>
    参考ページ:add_theme_support
  • テンプレートタグ the_post_thumbnail()を使って表示する
    参考ページ:the_post_thumbnail

Twenty Ten の functions.php をみると、アイキャッチ画像に関するファンクションとして、表示画像が大きい場合に指定サイズに切り取る「set_post_thumbnail_size()」が使われている。

子テーマの「index.php」テンプレートの置き換えについて

子テーマでループを置き換える、面白い方法が Twenty Ten テーマで示されていた。先ずは「index.php」テンプレートを見ると、21行目から次のようにプログラミングされている。

<?php
/* Run the loop to output the posts.
 * If you want to overload this in a child theme then include a file
 * called loop-index.php and that will be used instead.
 */
 get_template_part( 'loop', 'index' );
?>

子テーマに「index.php」に係るものが何もなければ、親テーマの「index.php」は、「loop.php」を読み出して実行する。もし、この「loop.php」に変更を加えたいなら、子テーマのディレクトリに変更した「loop.php」を置くのではなく、「loop-index.php」というファイル名にして置けば、「loop.php」の代わりに読み込まれて利用されるようになるのである。

子テーマを利用する場合は、親テーマに操作を加えなくてもいいように、いろいろと工夫されているようで感心してしまった。