サポート » 使い方全般 » 子ページのタイトルをカスタムフィードで分類したい

  • 解決済 azunai

    (@azunai)


    はじめまして。
    コチラのトピックを参考に、親ページに属した子ページのタイトルとカスタムフィールドを取得し、リスト表示に挑戦しています。
    更に、このカスタムフィールドの値を使って、子ページのタイトルを分類し、親ページにリスト表示したいのです。、↓こんな感じで。

    子ページA(カスタムフィールド値:abc)
    子ページB(カスタムフィールド値:def)
    子ページC(カスタムフィールド値:abc)
    子ページD(カスタムフィールド値:def)

    カスタムフィールド値:abc
    ・子ページA
    ・子ページC
    カスタムフィールド値:def
    ・子ページB
    ・子ページD

    どのようにコードを書き換えていいのかわかりません。
    どなたかご教授をお願致します。

8件の返信を表示中 - 1 - 8件目 (全8件中)
  • モデレーター jim912

    (@jim912)

    azunaiさん、こんにちは。

    参考のトピックは、ループ中でカスタムフィールドを取得して、そのまま出力していますが、ご希望のケースでは、一旦、カスタムフィールドの値をキーとした2次元配列に再配備し、できあがった配列を、再度ループし、表示するような手順で可能です。

    トピック投稿者 azunai

    (@azunai)

    jim912さん、ありがとうございます。
    PHPのコードの変数を変えるくらいしかスキルがなくて…2次元配列って何ですか?状態ですが、jim912さんのアドバイスを参考に格闘してみます。
    が、もし可能でしたらサンプルコードなど教えて頂ければ助かります。

    モデレーター jim912

    (@jim912)

    azunaiさん、こんにちは。

    まずは、子ページを全て取得してリスト表示させるところからやってみましょう。難しいことは段階的に実現していかないとわからなくなってしまいます。

    ご自分で記述されたコードなどありましたら、ご提示ください。

    トピック投稿者 azunai

    (@azunai)

    jim912さん、ありがとうございます。
    PHPの解説書を見ながらコードを書いてみました。子ページが配列(解説書丸写し)で設定した数ずつ表示するだけで分類されません。私には難問過ぎてどこが間違っているのかもわかりません。

    <?php
    if ( $post->post_parent == ID3) {
    	$child_posts = get_posts( 'numberposts=5&order=ASC&post_type=page&meta_key=example' );
    	if ( $child_posts ) {
    		foreach ( $child_posts as $child ) {
    			$c_pagelink = get_page_uri( $child->ID );
    			$c_title = apply_filters( 'the_title', $child->post_title );
    			$c_example = get_post_meta( $child->ID, example, true );
    	$list = array('0'=>array('exampl' => 'abc'),'1'=>array('exampl' => 'def'));
    		foreach ( $list as $c_example ) {
    			print "<li><a href=".$c_pagelink.">".$c_title."</a></li>\n";
    		}
    		}
    	}
    }
    ?>

    Codexのサンプルコードから、以下の方法を見つけましたので、親ページにカスタムフィードの値分、記述して分類することにしました(このコードなら理解できました)

    <?php
      $children = wp_list_pages('title_li=&child_of='.$post->ID.'&echo=0&meta_key=example&meta_value=abc&sort_column=post_date&show_date=created&sort_order=desc');
      if ($children) { ?>
    <h3>カスタムフィードの値:abc</h3>
      <ul>
      	<?php echo $children; ?>
      </ul>
    <?php } ?>

    ちゃんと基礎から勉強しなくては…でも頭がついていかない(五十の手習いです)

    モデレーター jim912

    (@jim912)

    azunaiさん、こんにちは。

    呈示いただいたコードでは、

    foreach ( $child_posts as $child ) {

    のループで、すぐに表示を行いますが、カスタムフィールド毎に分類するには、ここでタイトルや、リンクの取得は行わず、別な配列に再分配を行います。

    // 再分配用の配列を初期化
    $children = array();
    // 子ページが存在する場合のみ実行
    
    if ( $child_posts ) {
    	foreach ( $child_posts as $child ) {
    		// カスタムフィールドの値を取得
    		$c_meta = get_post_meta($child->ID, 'example', true);
    		// カスタムフィールドの値が取得できた場合のみ、カスタムフィールドの値毎に再分配
    		if ( $c_meta ) {
    			$children[$c_meta][] = $child;
    		}
    	}

    上記の用にすると、$childrenは、カスタムフィールドの値を1次とした2次元配列となり、カスタムフィールド毎に分類されることとなります。どのようなデータ構造になっているかわからないのであればループ終了後に

    var_dump( $children );

    を記述してみて、どのような配列ができているか確認してみてください。

    ループの終了後に、出来上がった配列を2重ループとして、最初のループでカスタムフィールドの値を、内部のループでページのリストを表示させます。

    // 再分配された配列があったらリストを表示
    	if ( $children ) {
    ?>
    <ul class="classified_children">
    <?php
    		// カスタムフィールド値でのループ
    		foreach ( $children as $c_meta => $classified_children ) {
    ?>
    	<li class="meta_name"><?php echo esc_html( $c_meta ); ?>
    		<ul class="meta_posts">
    <?php
    		// カスタムフィールドの値毎に分類されたページの配列をループ
    			foreach ( $classified_children as $child ) {
    				$link = get_page_link( $child->ID );
    				$title = apply_filters( 'the_title', $child->post_title );
    ?>
    			<li><a href="<?php echo esc_url( $link ); ?>"><?php echo $title; ?></a></li>
    <?php
    
    			}
    ?>
    		</ul>
    	</li>
    <?php
    		}
    	}
    ?>
    </ul>
    <?php

    取得から、表示までをくっつけると概ね、下記で実現できるはずです。細かいパラメータなどは調整してください。(検証していないので、間違っているかもしれませんが。。。)
    下記のコードの場合、カスタムフィールドの値の表示順序が取得されたページのカスタムフィールドの値の現出順になってしまいます。何らかの表示順の希望があるのであれば、表示のループ前の配列のソートを行う必要が出てきますね。

    // 表示中のページの子ページでmeta_keyがexampleを持つページを順序順に全て取得
    $child_posts = get_posts( 'numberposts=-1&order=ASC&orderby=menu_order&post_type=page&meta_key=example&post_parent=' . $post->ID );
    // 再分配用の配列を初期化
    $children = array();
    // 子ページが存在する場合のみ実行
    
    if ( $child_posts ) {
    
    	foreach ( $child_posts as $child ) {
    		// カスタムフィールドの値を取得
    		$c_meta = get_post_meta($child->ID, 'example', true);
    		// カスタムフィールドの値が取得できた場合のみ、カスタムフィールドの値毎に再分配
    		if ( $c_meta ) {
    			$children[$c_meta][] = $child;
    		}
    	}
    	// 再分配された配列があったらリストを表示
    	if ( $children ) {
    ?>
    <ul class="classified_children">
    <?php
    		// カスタムフィールド値でのループ
    		foreach ( $children as $c_meta => $classified_children ) {
    ?>
    	<li class="meta_name"><?php echo esc_html( $c_meta ); ?>
    		<ul class="meta_posts">
    <?php
    		// カスタムフィールドの値毎に分類されたページの配列をループ
    			foreach ( $classified_children as $child ) {
    				$link = get_page_link( $child->ID );
    				$title = apply_filters( 'the_title', $child->post_title );
    ?>
    			<li><a href="<?php echo esc_url( $link ); ?>"><?php echo $title; ?></a></li>
    <?php
    
    			}
    ?>
    		</ul>
    	</li>
    <?php
    		}
    	}
    ?>
    </ul>
    <?php
    }
    トピック投稿者 azunai

    (@azunai)

    jim912さん、ありがとうございます。
    呈示いただいたコードでリスト表示されました!
    表示順は sort_column=post_date を入れて希望通りになりました。
    あと、ページの作成日も表示させたくて、「カスタムフィールドの値毎に分類されたページの配列をループ」の箇所に
    $date = apply_filters('the_date', $child->post_date);
    を追加して
    <a href="<?php echo esc_url( $link ); ?>"><?php echo $title; ?></a> | <?php echo $date; ?>
    としたのですが、時間まで表示されます。
    ページリストのパラメータにdate_format="Y-m-d"と書式指定しているのですが、apply_filtersで取りだした場合、これは無視されるのでしょうか?

    モデレーター jim912

    (@jim912)

    azunaiさん、こんにちは。

    日付の整形は、mysql2date関数を使うと便利です。

    apply_filtersは、取得するための関数ではなく、WordPressのプラグインフックを起動させるための関数ですので、お間違いのないよう。

    the_dateフックは、デフォルトで動作するフックは存在していませんし、整形後のデータを受け取ることを前提としてますので、利用方法が少々異なります。

    ご希望のケースでは、

    $date = mysql2date( 'Y-m-d', $child->post_date );

    としてあげればよいはずです。

    トピック投稿者 azunai

    (@azunai)

    jim912さん、丁寧なアドバイスありがとうございます!
    日付だけを取り出すことができました。
    mysql2dateとapply_filters、またひとつ関数の使い方がわかりました。
    コード書き、まだまだ難解ですが、いろいろ知って楽しくなってきました。
    他にもトライしてみます。

8件の返信を表示中 - 1 - 8件目 (全8件中)
  • トピック「子ページのタイトルをカスタムフィードで分類したい」には新たに返信することはできません。