WordPressに関する情報や技術紹介です

サブカテゴリ毎に記事をまとめて表示2

前回の記事で不満だった部分を解消してみた。
具体的には以下のようにする

  1. 親カテゴリのトップページにサブカテゴリの一覧を表示
  2. 各サブカテゴリ毎に記事をまとめて表示

前回で解決できなかった問題は自動でサブカテゴリの一覧を取得してループさせながら各HTMLを出力させる事。
そもそもつまづきの原因はサブカテゴリのIDを取得できなかったから。
逆に言うと「親カテゴリに属するサブカテゴリのIDを全て取得」できれば実現可能という事になる。
そこでかなり微妙ながらサブカテゴリのIDを取得するように試みた。

まずはサブカテゴリを取得する

wp_list_categories(‘引数’)

カテゴリ一覧を取得できる。引数に親カテゴリのIDを指定すればサブカテゴリの一覧が取得できる。

echo
すぐに出力するかPHPのデータとして利用するか
title_li
タイトル
style
リスト形式で出力するか<br>で出力するか
child_of
親カテゴリのIDを指定

他に必要であれば足す。ここで変更するのはchild_ofだけで、他は全て下と同じで構わない。

/*
 これで$subCategoriesにサブカテゴリが配列として収められる。
$subCategories[0] = <a href="サブカテゴリのURL">サブカテゴリ名</a>
*/
$subCategories = explode('<br />', wp_list_categories('echo=0&title_li=&style=none&child_of=3'));

次にサブカテゴリの名前だけを取得してそこからIDを取得する。
下はサブカテゴリ名からIDを取得する関数。

get_cat_ID(‘カテゴリ名’)

引数にカテゴリ名を指定するとIDが取得できる。

上記関数でIDが取得できるのが分かったので、先の$subCategories 配列からサブカテゴリ名だけを抽出してIDを取得すれば良いかと。
そこで何となく怪しい正規表現を駆使して$catList配列からサブカテゴリ名を抽出していき、IDを取得していく。

//IDを入れる配列を宣言
$catIDs = array();
//リンク付サブカテゴリを入れる配列を宣言
$catList = array();

//正規表現を作成
$reg = '/<a.*?>(.*)?<.*/si';

foreach($subCategories as $cat) {
	if(preg_match($reg, $cat, $value)) {
		//カテゴリ名からIDを取得して配列に追加
		array_push($catIDs, get_cat_ID($value[1]));
		array_push($catList, $cat);
	}
}

本当にこんな正規表現で大丈夫かしら?と不安一杯だが、少なくとも私の環境では大丈夫なので良しとする。
これで、
【 $catList 】にリンク付きのサブカテゴリ一覧
【 $catIDs 】にサブカテゴリのID一覧
が取得できる。

※ この記事よりスマートなサブカテゴリの取得方法がありますので併せて読んでみてください。

IDまで取得できれば後はループで回していけばOKではないかと。
以下が一連のコード。

<?php
//親カテゴリに属するサブカテゴリを配列で取得
$subCategories = explode('<br />', wp_list_categories('echo=0&title_li=&style=none&child_of=3'));

$catIDs = array();
$catList = array();

//正規表現を作成
$reg = '/<a.*?>(.*)?<.*/si';

/*
 サブカテゴリ名だけを取得後、
 サブカテゴリに対応するIDを取得して配列に追加
*/
foreach($subCategories as $cat) {
	if(preg_match($reg, $cat, $value)) {
		//カテゴリ名からIDを取得して配列に追加
		array_push($catIDs, get_cat_ID($value[1]));
		array_push($catList, $cat);
	}
}

//ループしてHTMLを作成
for($i=0; $i<count($catIDs); $i++) {
?>

<h3 class="title"><?php echo $catList[$i]; ?></h3>
<ul class="ul-content-list">
<?php if (have_posts()) : query_posts('posts_per_page=5&cat=' . $catIDs[$i] . '&orderby=ID&order=desc');  ?>
<?php while (have_posts()) : the_post(); ?>
	<li><?php the_time('y-m-d'); ?>&nbsp;&nbsp;<a href="<?php the_permalink() ?>" class="bluelink"><?php the_title(); ?></a></li>
<?php endwhile; endif; wp_reset_query(); ?>
</ul>

<?php } ?>

もうちょっとまともなやり方があれば、誰か教えてください。

タグ
, , , , ,
トラックバックURL
  • BBking さん:
    2010/6/15 火曜日 14:09:54

    はじめまして。
    何気にググってこちらにたどり着きました。

    WPでこんな事ができないかなぁ・・なんて思っていたところ、
    まさにストライクな記事に出会えて感激です!

    そこで一つご質問なのですが、
    以下のページですと各カテゴリリストの右下に、
    more…で該当カテゴリへのリンクが追加されています。

    http://www.is-p.cc/wordpress

    この場合、リンケージのURLはどのように取得すればよろしいのでしょうか?
    構想としては、カスタムフィールドで指定したサムネイルを表示させて、
    そこに同様のリンクを貼りたいと思っています。

    大変お忙しいとは思いますが、ご教授いただけましたら幸いに存じます。
    何卒、よろしくお願い致します。

  • ISプランニング さん:
    2010/6/15 火曜日 14:55:49

    >BBking さん
    コメントありがとうございます。

    ストライクですか?良かったです。
    なにぶん正規表現が怪しいので、あんまりお勧めはしませんが…。

    ご質問の件ですが、リンケージの意味が私はよく分かっておりませんが(お恥ずかしい!)、単純にリンクのURLという事でしたら、WP関数の get_category_link() を使っているだけだと思います。

    もし意味が違ってたらすいません。もう少し詳しく説明していただけたらお答えできると思います。

  • BBking さん:
    2010/6/15 火曜日 15:58:56

    早々にレスを頂きましてありがとうございます。
    こちらの説明が分かりずらくてすいません。

    例えば、サンプルのソースでは、
    以下の部分で各子カテゴリのタイトル取得とリンクを同時に設定しています。

    それで実際の出力は以下になります(他の子カテゴリも同様)。

    <a href=”http://www.is-p.cc/category/wordpress/install” rel=”nofollow”>インストール</a>

    当方がしたいのは子カテゴリのタイトルとは別に、
    任意のテキストや画像に対してもリンクを設定したいのです。

    more…を例にすると以下のURLの取得方法が分からないということになります。

    <a href=”○○○○” rel=”nofollow”>more…</a>

    これでご質問の意味が伝わりますでしょうか?
    お手数をお掛けします。

  • ISプランニング さん:
    2010/6/15 火曜日 16:20:50

    >BBkingさん
    ムムム…?
    (^-^; ますます分からなくなりました。
    先程の回答は回答になっていなかったでしょうか?

    具体的に言うと、for文のループ中で $catIDs[$i] という箇所がサブカテゴリのIDになります。

    なので、

    <a href=”<?php echo get_category_link($catIDs[$i]); ?>”>何かしらの画像とか</a>

    という書き方をすればサブカテゴリのカテゴリページのURLにリンクします。

    もしかしてBBkingさんの仰るリンク先というのは全然別のリンクを指すのでしょうか?
    もしそうならちょっと私の理解している事と全然違うので答えようがないのですが…。

  • BBking さん:
    2010/6/15 火曜日 16:49:29

    まさにこれです!!
    的を得た説明が出来ずに大変お手数をお掛けしました。

    WordPressをCMS化して企業サイトを構築する場合、
    サブカテゴリ一覧⇒サブカテゴリ⇒詳細ページという遷移はある意味必須だと思うのですが、
    なかなか分かりやすい情報が見つからず悶々としておりました。

    これで一歩前進出来そうです。
    お忙しい中、本当にありがとうございました!!

  • ISプランニング さん:
    2010/6/15 火曜日 17:26:59

    >BBking さん

    そうですか、良かったです。

    ちなみにこのやり方だと何かしら問題が出てくる可能性もありますので、ちょっと先程データベースから直接サブカテゴリIDを取得する関数を作成してみましたので時間があればそちらを試してみてください。

    サブカテゴリIDを取得する関数

  • pyon-yon さん:
    2010/9/20 月曜日 18:59:25

    お世話になります。最上位のカテゴリーを設定し、そのカテゴリーアーカイブを表示すると
    下の階層のカテゴリーに投稿した記事の一覧が表示されるようにしたいと思っています。

    カテゴリーアーカイブ(最上位カテゴリー)
     カテゴリーA
      記事a1
      記事a2
     カテゴリーB
      記事b1
      記事b2
      記事b3
    など

    ご紹介いただいているコードは、一般的なテーマのarchive.phpテンプレートの、おおよそどの辺りにコピペすればよいのでしょうか?また、archive.php以外にも設定は必要になりますか?

    php初心者ですが、よろしくお願いします。

  • ISプランニング さん:
    2010/9/21 火曜日 09:22:32

    >pyon-yonさん
    archive.phpですか?

    でしたら始めに「is_category(最上位カテゴリ)」の条件分岐タグを利用してやればいけるのではないでしょうか?

    具体的には、

    <?php get_header(); ?>

    <div id=”body”>

    <div id=”contents”>
    <?php if(is_category(‘最上位のカテゴリidとか’)) : ?>
    ※ここに上のコードを入れます。
    <?php endif; ?>
    </div><!– conetnts-end –>

    <!– サイドバー –>
    <div id=”sidebar”>
    <?php get_sidebar(); ?>
    </div><!– sidebar-end –>

    </div><!– body-end –>

    <?php get_footer(); ?>

    みたいな感じだと思います。
    もし、category.phpファイルがある場合は、そちらが優先されて表示されますのでcategory.phpファイルに上のような設定をします(その場合はarchive.phpは何もする必要がありません)。

    ちなみに上のコードよりもっとスマートな方法がありますのでそちらを利用された方が良いかも…。

  • pyon-yon さん:
    2010/9/23 木曜日 17:02:15

    ISプランニング さま
    ご教示、誠にありがとうございました。「スマートな方法」のコードで目的が達成できました。
    もし可能であれば、サブカテゴリーの順番を、WordPress3.xのカスタムメニューで設定した
    カテゴリーの順番で表示したいのですが・・?
    運用していく中で、カスタムメニューで順番を変更したら、親カテゴリーに表示される
    サブカテゴリーも、自動的に変更されている、という状態にしたいと思います。
    どうか、よろしくお願い致します。

  • ISプランニング さん:
    2010/9/24 金曜日 15:37:46

    >pyon-yonさん
    本来であれば「ここを調べれば良いかもしれません。頑張ってください!」と言うところですが、カスタムメニューを利用するのはなかなか面白いと思いましたのでこちらで調べました。
    記事にさせていただきましたのでそちらを参考にしてみてください。
    カスタムメニューのデータを利用する

    もちろん並び順も自動で変更されて取得できるのでお望みのものが出来ると思います。

  • pyon-yon さん:
    2010/9/24 金曜日 17:37:33

    ISプランニングさま
    お調べくださって、ありがとうございました。
    ここからは自分で考えなければと思いますが、プログラミング力がなく、難しそうです。
    現在やりたいのは、カスタムメニューで表示される項目が「甲、乙、平、定」として、
    カテゴリーになっているのが、例えば「乙」といたします。メニューで「乙」をクリック
    すると、乙を親としたA,B,C,Dのサブカテごとに、投稿記事一覧のアーカイブが表示
    されてほしい、という訳です。カスタムメニューでは、アブブカテ順も任意に並べ替えれるので、
    並べ替えた結果がA,B,C,Dであれば、
    メニューに現れ、Aをクリックすると、Aカテに含まれる投稿記事一覧のアーカイブも
    Aごとに記事一覧、Bごとに記事一覧、・・・・、という具合になっていてほしい、という訳です。
    かなり、ややこしそうですね?初心者でも簡単にできますでしょうか?

  • pyon-yon さん:
    2010/9/24 金曜日 20:47:27

    スミマセン。「アブブカテ順」刃、「サブカテ(ゴリー)順」のタイプミスです。

  • ISプランニング さん:
    2010/9/27 月曜日 12:01:31

    >pyon-yonさん
    うーん、ちょっとイメージが沸きにくいのですが、カスタムメニューで作成したメニューが入れ子になっているという感じでしょうか?

    ちょっと簡単には出来そうにないと思いますよ。

    前述の記事の内容で整形前のデータを取得してforeachで回しながら特定のカテゴリーで「wp_nav_menu」を呼ぶとかすれば出来ると思いますが…。


    $menu_items = wp_get_nav_menu_items('カスタムメニューA');
    foreach($menu_items as $menu) {
    if($menu->title == "乙") {
    wp_nav_menu(array('menu_id' => 'カスタムメニューB'));
    //もしくは、まだ入れ子にする場合などは、更にwp_get_nav_menu_items関数で自前で加工
    }
    }

    無理やり&柔軟性は無いですが、上記方法であれば出来そうです。

  • pyon-yon さん:
    2010/9/27 月曜日 14:51:23

    話を複雑にしてしまってすみません。いただいたコメントで、少し見えてきたものがあるような
    気もしますが。。。
    作成するカスタムメニューはとりあえず一つで、その名前を「globalnavi」とかしますと、
    この「乙」という項目の下にカテゴリA,B,C・・・が、またA,B,Cには、もう一段程度は細分の
    カテゴリーがある(入れ子になっている)という状態を想定しています。
    要は、メニューの「乙」をマウスオーバーすると現れるサブメニューの順番で、カテゴリーごとの
    記事一覧(アーカイブ)を出力したい、というものです。
    もし何かお知恵頂けることがあれば、よろしくお願いします。

  • ISプランニング さん:
    2010/9/28 火曜日 11:37:12

    >pyon-yonさん
    (^-^; うーん、やはりよく分かりません…。

    上記のような私の手順を応用したりして色々試されてみるか、フォーラムなどに投稿してもう少し詳しい人にお聞きになった方が良いかもしれません。

    お役に立てず申し訳ありません。

Leave a Reply

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

*

ページTOPに戻る