WordPressにて 子ページのタイトルだけでなく本文も一覧で取り出す

それにしても今年に入って、いわゆる〈アルファブロガー〉の方々の間でMTからWordPressへの乗り換え事例が多発しているのはどうしてなんでしょう? 個人的には3.1xあたりでMTをとっとと捨ててしまい(いちばんの乗り換え理由はライセンス料)MTOSが出てもまったく食指を動かすことがなかったので、局地的とはいえこのところの乗り換えブームには「何で今ごろ?」という印象で捉えております。

それはさておき、今とりかかっているWordPressの案件。

wp_list_pages タグを使い、子ページのタイトルリストを出力する「親ページテンプレート」を作りました。

……が、タイトルが異様に短い、とか、子ページの数が10個くらいしかない、といった仕様(?)が災いして、それはもう親ページがイヤになるくらい寒いレイアウトになってしまったのです。

そこで「子ページのタイトルだけでなく、本文も一緒に出力できないか?」と試行錯誤した結果、以下のようなコードにたどりつきました。本文が長いとこれまたレイアウトが煩雑になってしまうのですが、幸い、子ページの本文はさほど長くないので実用性はありかと思ってます。

例によって「ご利用は計画的に」のコードですのであしからず :-)

1
2
3
4
5
6
7
8
<?php
	$page_id = mysql_real_escape_string ( $post -> ID );
	$array = $wpdb -> get_results ( "SELECT ID, post_title, post_content FROM $wpdb->posts WHERE post_parent = '$page_id' AND post_status = 'publish'");
	foreach ( $array as $value ) {
		echo "<h2>" . $value -> post_title . "</h2>\n";
		echo apply_filters ( 'the_content', $value -> post_content );
	}
?>

3行目でデータベースを参照し

  • ページ・投稿の一覧から(FROM $wpdb->posts
  • 現在表示中のページを親に持ち、かつ post_status が publish になっているページについて(WHERE post_parent = '$page_id' AND post_status = 'publish'
  • ID・タイトル・本文を抽出(SELECT ID, post_title, post_content

という操作を行なっています。抽出された本文には改行タグが入っていないので nl2br 関数などで適宜整形する必要があるかもしれませんね。echo apply_filters ( 'the_content', $post -> post_content );とする方がよいです。上記のコード例も修正しました。

[2010.8.27追記]
コメントをお寄せくださったm.nakamuraさんのリクエスト+精度を高めたコードを別エントリーにまとめました。


WordPressにて 子ページのタイトルだけでなく本文も一覧で取り出す” への8件のコメント

  1. 貴重な情報をありがとうございます。今考えていることに、
    ビンゴでした。

    しかし、WP 3.01で、ちなみに、twentytenテーマなのですが、
    page.phpに上記コードをおいてみましたが、置いた部分から
    出力がありませんでした。また、function.phpに、そのまま
    置いてもダメでした。置く場所、その他、注意することがある
    のでしょうか?

    よろしくお願いします。

  2. m.nakamuraさん

    ウチのような辺境ブログの記事を参考にしていただきありがとうございます。
    コード自体は上記のまま、twentytenでも使えることを確認しました。

    が、エントリー本文時に入力した半角アポストロフィ( ' )が全角に変換されて出力されていたので、そのままコピペされてうまくいかなかったのかもしれませんね。

    ということで、コード部分を整形して再掲しました。page.phpなどに設置のうえ再度お試しいただければ幸いです。

  3. ご検討、誠に恐縮です。
    しかし、やはりエラーが出ます。例えば、page.phpに入れた場合は、
    Parse error: syntax error, unexpected $end, expecting T_VARIABLE or T_DOLLAR_OPEN_CURLY_BRACES or T_CURLY_OPEN in D:\Program Files\xampp\htdocs\wordpress-v3\wp-content\themes\twentyten\page.php on line 46
    となりますし、
    1カラムのテンプレートonecolumn-page.phpに入れた場合も、
    Parse error: syntax error, unexpected T_STRING in D:\Program Files\xampp\htdocs\wordpress-v3\wp-content\themes\twentyten\onecolumn-page.php on line 45
    となります。どの位置においても、ラインの数字が変わるだけで、
    メッセージ以外はホワイトページになるのです・・・?

    とても簡潔ですてきなコードだと思うのですが。
    どこがいけないのでしょうか?

  4. m.nakamuraさん

    こちらこそ、たびたびすみません。
    昨日、コード例を書き換えたときに、なぜか不要な文字が混入していたようです。ご迷惑をおかけしました。改めてコード例をチェックし、当方の環境で動作確認しましたので、お試しいただければ幸いです。

  5. 今度こそ、BINGOです。ありがとうございます!
    それで、できれば、もう一つ、お願いがあります。
    リストされる子ページのタイトル部分に、子ページへのリンク付きとなるよう
    (つまり、アンカー付きで出力されるよう)にできれば、より有難いです。

    いままで、いろいろなTIPSや、プラグインを試しましたが、こちらのコードが
    最適です。どうか、お手数ですが、よろしくお願いいたします。

  6. 度々で恐縮ですが、リストされるページは、デフォルトで何順になるのでしょうか?
    (多分ID順になっている?)
    これがWordPress管理画面で並べた順(例えば、My Page Orederプラグインなどで
    並べる)になってくれれば更によいのですが。プラグインを使った並び順が、MySQL
    のどこに入っているかはわからないので、そこまではちょっと難しいでしょうか?

    このコードをプラグイン化して、そのプラグインの設定項目の一つとして、ページID順を
    入力できるようになっていると、汎用的になると思いました。(この場合、ページを追加
    した際などに、ID設定窓で、出力順を見直す、といったことができる)
    こちらは私の妄想ですので、無視してくださって結構です。

  7. m.nakamuraさん

    こちらもいろいろと励みになります。ありがとうございます :-)
    エントリーに追記しましたが、精度を高めたコードを別エントリーにてまとめましたので、ご参照いただければ幸いです。

    > リストされるページは、デフォルトで何順になるのでしょうか?

    上記のコード例ですと $wpdb -> get_results で発行するSQL文にてソート順(ORDER BY)を明示していないので、並び順はDBまかせになってしまいますね。

    > これがWordPress管理画面で並べた順(例えば、My Page Orederプラグインなどで
    > 並べる)になってくれれば更によいのですが。プラグインを使った並び順が、MySQL
    > のどこに入っているかはわからないので、そこまではちょっと難しいでしょうか?

    ページの並び順は posts テーブルの menu_order フィールドに格納されているので、SQL文でこのフィールドを呼び出してソートをかければオッケイかと思います。
    そのあたりも別エントリーで追記しましたので、よろしければどうぞ。

    プラグイン化は……そのうちに、ということで……(汗)

  8. ピンバック: 2011年8月4日のブックマーク | Yuxu's Notebook

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

*

次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <img localsrc="" alt=""> <pre lang="" line="" escaped="" highlight="">