サポート » 使い方全般 » wp_list_pages() でIDではなくpagetitleを利用する方法

  • 解決済 shokun0803

    (@shokun0803)


    wp_list_pages()を利用してページのリストを出したいと考えています。
    ページには親-子の関係があって、特定の親Aを基準とするリストを抽出します。
    この時、親Aに子Aを親とする階層があり、この子Aを親とするリストは除外したいと思います。
    この場合、親AのIDが1、子AのIDが3だったとすれば、

    wp_list_pages('title_li=&child_of=1&exclude_tree=3');

    で実現できるのですが、複数サイトで同じテンプレートを流用するにはページIDが変わってしまうため利用できません。
    このページリストは親Aの下層にあるページにしか表示しないという条件で、親Aは

    $ancestor = array_pop( get_post_ancestors( $post->ID ) );
    wp_list_pages('title_li=&child_of=' . $ancestor . '&exclude_tree=3');

    でIDを取得して表示できましたが、子AのIDを取得できません。

    条件として子Aのページタイトルは違うサイトでも必ず同じ(英数文字のみで構成、例:a_pagesなど)なので、ループなどで子Aのページタイトルを取得しIDを割り出せば可能かと思いましたが、ページタイトルからどのようにして該当ページのIDを取得すればよろしいのでしょうか。
    また、変にループを重ねたり、あまり回数の多いループを構成するのも負荷が高くなるのではないかと思い、なにか良い関数でもないかと探しておりますがなかなか見つかりません・・・
    良い方法がありましたらご教授お願いいたします。

6件の返信を表示中 - 1 - 6件目 (全6件中)
  • ページタイトルからはなかなか難しいかと思いますが、
    もしページのスラッグからIDを取得ということでよろしければ、
    下記の方法があります。

    $child = get_page_by_path('a_pages');
    echo $child->ID;

    「a_pages」がIDを取得したいページのスラッグです。

    モデレーター jim912

    (@jim912)

    shokun0803さん、どうもです。

    子Aを指定できるなんらかの条件があるなら、もう少しスマートな取得の仕方もできるのかもしれませんが、一応、wp-includes/post.phpの2130行目(Ver2.8)にあるget_page_by_titleが参考になるかと思います。

    function get_page_by_title($page_title, $output = OBJECT) {
    	global $wpdb;
    	$page = $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_title = %s AND post_type='page'", $page_title ));
    	if ( $page )
    		return get_page($page, $output);
    
    	return null;
    }

    ただし、目的はページのIDのみ取得できればよいので、上記関数の後半部分は逆に不要です。
    改造してオリジナルの関数にしてみてはいかがでしょう。

    function get_page_id_by_title($page_title) {
    	global $wpdb;
    	return $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_title = %s AND post_type='page'", $page_title ));
    }

    ※ この関数は、DBへのクエリーが発生しますので、アクセスの多いサイトなどなら負荷軽減のためにwp_list_pagesに該当IDを埋め込んでしまった方が良いと思います。
    ※ 必要に応じてpost_statusの条件指定を追加してください。

    umbrella_processさん、jim912さん、ありがとうございます。
    早速検証させていただきます。

    実は最初にwp_list_pagesを使おうと思っていた箇所は、リストにした際にpagetitleを英数字で入力しているため、別に日本語で入力しているカスタムフィールドを表示させなくてはいけないことに気がついて、別の方法を模索していました。(wp_list_pagesはソースを吐き出してしまうため加工が面倒だった、、汗)

    ただwp_list_pagesでなくとも親-子関係が複雑なため(何の話題だ?)pagetitleからIDを取得する方法はどうしても必須なのです。とても助かります。
    どちらの方法が最適解なのかはまだわかりませんが検証してみます。ありがとうございました。

    追記:
    ちなみにいま

    <div class="menu"><h2>TOPICS</h2>
    <ul style="font-size:11px;">
    <?php
    	$ancestor = array_pop( get_post_ancestors( $post->ID ) );
    	$child_posts = get_posts( 'numberposts=-1&order=ASC&orderby=post_title&post_type=page&post_parent=' . $ancestor );
    	if( $child_posts ) {
    		foreach ( $child_posts as $child ) {
    			$c_pagetitle = get_post_meta($child->ID, 'ページタイトル');
    			$c_pagelink = get_permalink($child->ID);
    			if( $c_pagetitle[0] ) {
    				$c_pagetitle[1] = mb_strimwidth($c_pagetitle[0],0,32,"…",'UTF-8');
    				if( $child->ID == $post->ID ) {
    					echo "<li>{$c_pagetitle[1]}</li>\n";
    				} else {
    					echo "<li><a href=\"{$c_pagelink}\" title=\"{$c_pagetitle[0]}\">{$c_pagetitle[1]}</a></li>\n";
    				}
    			}
    		}
    	}
    ?>
    </ul>
    </div><!-- END div.menu -->

    このようなソースで同じようなことを実現していますが、なぜか表示したくない子ページが表示されません。結果オーライなのですが問題の解決にはなりませんね。。
    ページの構成は

    papa1---page3(papa2)※表示したくない階層(カスタムフィールドタイトル無)
           |   |-page4(タイトル有)
           |-page1(タイトル有)
           |-page2(タイトル有)
           |-page5(タイトル有)
           |-page6(タイトル有)
           |-page7(タイトル有)

    この状態でpage1,2,5,6,7のリストが生成されます。本来はpage3(papa2)のIDを取得してはずす必要があると思うのですが、今の状態で既に表示されません。なんででしょ・・・
    がんばって検証してみます。。

    モデレーター jim912

    (@jim912)

    shokun0803さん、遅レスすみません。。

    解決されましたか?
    page3ですが、$child_postsには含まれているものの、「ページタイトル」が無いため、$c_pagetitle[0]のif分岐ではじかれているものと思います。

    あああ・・・自分でソース組んでおきながら確実に見落としていますね・・・

    確かにテストでタイトルを入力したら一覧に表示されました。
    他の部分のソースを組んでいてこの部分を棚上げしていましたが、喉の痞えが取れた感じです。
    まだ提示していただいたソースの組み込みもままならないままですが、混乱をしないように解決済みにしておきます。

    大変ありがとうございました。

6件の返信を表示中 - 1 - 6件目 (全6件中)
  • トピック「wp_list_pages() でIDではなくpagetitleを利用する方法」には新たに返信することはできません。