サポート » 使い方全般 » get_the_categoryで取得したカテゴリ(複数)の表示順序の変更

  • 解決済 yacchi

    (@yacchi)


    当方WordPress初心者でございます。
    もしかしたら極簡単な質問内容かもしれず恐縮でございますが、お力添えいただければ幸いでございます。

    さて、現在個別投稿ページ(single.php)のループ内において、以下のコードで特定の親に属する子カテゴリを取得しております。

    <?php $categories = get_the_category(); ?>
    <dl>
    <dt>親カテゴリ(ID=1)</dt>
    <?php foreach($categories as $category) :
           if(cat_is_ancestor_of(1, $category))
    			 echo '<dd>:'. $category ->  cat_name . '</dd>';
    			 endforeach;
    ?>
    <dt>親カテゴリ(ID=2)</dt>
    <?php foreach($categories as $category) :
           if(cat_is_ancestor_of(2, $category))
    			 echo '<dd>:'. $category ->  cat_name . '</dd>';
    			 endforeach;
    ?>
    ・・・・・
    </dl>

    カテゴリはきちんと取得できているのですが、表示順序が「名前順」になってしまっております。
    順序を「ID順」にしたいため、色々と調べた結果、以下のサイトがまさに解決方法を示していたのですが、記載されている「category-template.php」の修正内容が当方のもの(WP3.2.1)とマッチせず、うまく修正・解決することができませんでした。
    http://www.muchacolla.com/wordpress/customize/233/

    「get_the_category」で取得したカテゴリが複数だった場合の表示順序をID順にする方法をご教示いただけませんでしょうか。
    よろしくお願いいたします。

11件の返信を表示中 - 1 - 11件目 (全11件中)
  • こんにちは

    よかったら、このスニペット試していただけませんか?
    ループの外側で使ってください

    <?php
    	$args=array('orderby' => 'ID');
    	$terms = wp_get_post_terms( $post->ID , 'category', $args);
    ?>
    <dl>
    <dt>親カテゴリ(ID=1)</dt>
    <?php
    foreach($terms as $term){
    	if(cat_is_ancestor_of(1, $term)){
    
    		$html = '<dd>:<a href="%1$s" title="%2$s">%3$s</a> </dd>';
    
    		printf(	$html,
    				esc_url(get_term_link($term, 'category')),
    				sprintf( __( "タイトル %s" ), sanitize_title($term->name,'...')),
    				esc_html($term->name)
    		);
    	}
    }
    ?></dl>
    トピック投稿者 yacchi

    (@yacchi)

    nobitaさま、早速のご教示ありがとうございます。
    教えていただいた内容で、希望通りに完璧に実現することができました!

    しかも表示されるカテゴリにリンクまでついている状態になっているのですね!
    これはとてもありがたいです。ありがとうございます。

    今回の投稿内容とは関係なく恐縮なのですが、リンクのtitleに関しまして、日本語部分が「パーセントエンコード」になってしまっているのですが、これを解決する方法がわかりましたらご教示いただければ幸いです。

    よろしくお願いいたします。

    yacchiさん

    ごめんなさい 
    私が、この関数の使いどころを間違えていたのかもしれないです

    エンコードしないための方法は、
    1. sanitize_titleを使わない
    2.urldecode(sanitize_title($term->name,'...'))//PHPでデコードする
    3. esc_attr()//他のワードプレス関数を使う
    4. sanitize_title //hookを使って、sanitize_title関数の挙動を修正する

    4.は、関数の挙動が「日本語環境に適さない」など根拠がはっきりしない状態では、やるべきではないと思います。

    トピック投稿者 yacchi

    (@yacchi)

    nobitaさま、関係のないご質問にまでご対応いただき大変感謝いたします。
    また色々な方法をご教示いただきありがとうございます!

    取り急ぎ「2」の方法を試させていただき、日本語エンコードの問題はすぐに解決できました。
    ただ英字が小文字になってしまうようでしたので、「3」の方法を試させていただいたところ、完璧に問題解決することができました!

    ※「4」の方法は私の知識では難しそうだったため試しておりません。。すみません。。

    お忙しい中、誠にありがとうございました。
    重ねて御礼申し上げます。

    トピック投稿者 yacchi

    (@yacchi)

    nobitaさま、ちなみになのですが、条件分岐か何かを使って、以下を実現することは可能かおわかりになりますでしょうか。

    <?php
    	$args=array('orderby' => 'ID');
    	$terms = wp_get_post_terms( $post->ID , 'category', $args);
    ?>
    <dl>
    <dt>親カテゴリ(ID=1)</dt>
    <?php
    foreach($terms as $term){
    	if(cat_is_ancestor_of(1, $term)){
    		$html = '<dd>:<a href="%1$s" title="%2$s">%3$s</a></dd>';
    		printf(	$html,
    				esc_url(get_term_link($term, 'category')),
    				sprintf( __( "%s" ), esc_attr($term->name,'...')),
    				esc_html($term->name)
    		);
    	}
    }
    ?>
    </dl>

    子カテゴリがある場合は、
    親カテゴリ:子カテゴリ
    と表示され、

    子カテゴリがない場合は、
    親カテゴリ
    だけの表示になりますが、

    親カテゴリ:
    のように「:」を表示させることは可能でしょうか。

    <?php
    	$args=array('orderby' => 'ID');
    	$terms = wp_get_post_terms( $post->ID , 'category', $args);
    ?>
    <dl>
    <dt>親カテゴリ(ID=1)</dt>
    <?php
    foreach($terms as $term){
    	if(cat_is_ancestor_of(1, $term)){
    		$html = '<dd>:<a href="%1$s" title="%2$s">%3$s</a></dd>';
    		printf(	$html,
    				esc_url(get_term_link($term, 'category')),
    				sprintf( __( "%s" ), esc_attr($term->name,'...')),
    				esc_html($term->name)
    		);
    	}
    	else echo '<dd>:</dd>';
    }
    ?>
    </dl>

    最後の方に「else echo ‘<dd>:</dd>’;」を加えたりしてみたのですが、こうすると「:」が大量に(おそらく登録されている子カテゴリの数ぶん)表示されてしまいました。

    解決方法がわかればご教示いただきたいと思います。

    度々投稿内容と関係のないご質問で大変申し訳ございません。
    よろしくお願いいたします。

    こんにちは

    書き方間違っていますよ、PHPのif文のマニュアル当たってみてください。

    yacchiさんなら、きっと一人でできると思います がんばってください

    トピック投稿者 yacchi

    (@yacchi)

    <dl>
    <dt>親カテゴリ(ID=1)</dt>
    <?php
    foreach($terms as $term){
    	if(cat_is_ancestor_of(1, $term)){
    		$html = '<dd>:<a href="%1$s" title="%2$s">%3$s</a></dd>';
    		printf(	$html,
    				esc_url(get_term_link($term, 'category')),
    				sprintf( __( "%s" ), esc_attr($term->name,'...')),
    				esc_html($term->name)
    		);
    	}
    	else {
    		echo ("<dd>:</dd>");
    	}
    }
    ?>
    </dl>

    調べて書き直してみました。
    ただ結果は変わらず、「:」が登録されている子カテゴリの数ぶん表示されてしまいました。
    「cat_is_ancestor_of」に対する条件分岐をうまく記述しなければならないのだと思いますが、「:」を一つだけ出力したいだけなのに、なかなか難しいです。

    ちなみに、フォーラムメンバーであるjim912さんが本投稿内容の解決方法+αをブログでご紹介してくださっております。(もしかしたら本投稿内容を見て記事にしてくださったのかもしれません(._.))

    こちらも大変参考になると思いますので、皆様ご参照いただければと思います。
    http://www.warna.info/archives/1816/

    yacchiさん

    あぁ、すごいですね jim912さんに一票

    ラッキーですね、コードを書くことは努力すればできますが、そのコードの課題を見つけるのは、結構大変ですから

    流れなので、コロンの付け方のアイディアと、foreachループの省エネ対策の2点を考えて、コードを書き直してみました
    (けど、結果foreachループの省エネ対策にはなっていないですね)

    コロンを1個付けるために、foreachループの最終回で、これまでに、$colonがtrueになっていないかどうかをチェックしてfalseだったら、コロンを付けるという考え方です。

    配列を使っているので、コードが読みにくくなったと思いますが、$idsの配列に列挙していただければ、ID毎にコピペする必要がありません

    ちょっとしか試していないので、おかしいところあるかもしれませんがよろしく

    <dl>
    <?php
    	$args		= array('orderby' => 'ID');
    	$terms		= wp_get_post_terms( $post->ID , 'category', $args);
    	$html		= '<dd>:<a href="%1$s" title="%2$s">%3$s</a></dd>';
    	$colon		= array();
    	$result		= array();
    	/*表示したいIDを列挙*/
    	$ids		= array(19,1);
    
    	foreach($terms as $key=>$term){
    
    		foreach($ids as $id){
    			if($key== 0){
    				//loopの最初
    				$result[$id] = '<dt>親カテゴリ('.$id.')</dt>';
    				$colon[$id] = false;
    
    			}
    			if(cat_is_ancestor_of($id, $term)){
    
    				$result[$id] .= sprintf(	$html,
    						esc_url(get_term_link($term, 'category')),
    						sprintf( __( "%s" ), esc_attr($term->name)),
    						esc_html($term->name)
    				);
    				$coron[$id] = true;
    			}
    
                            if($key == count($terms) - 1){
    				//loopの最後
    
    				if($coron[$id] == false){
    					$result[1] .= '<dd>:</dd>';
    				}
    			}
    		}
    	}
    	// 表示
    	array_walk($result, 'print_named_array');
    
    	function print_named_array($item, $key){
        	echo $item."\n";
    	}
    ?>
    </dl>
    トピック投稿者 yacchi

    (@yacchi)

    nobitaさま、本当にありがとうございます・・・!
    if/elseだけでなんとかしようとしていた自分では、到底解決できなかったと思います。

    教えていただいた内容を試してみたところ、かなり近いところまでたどり着きましたので、あとは何とか自分でやってみようと四苦八苦しておりました。

    というのも、例えば「親カテゴリ1」の子カテゴリを1つだけチェックして、他は無しの状態で「$ids = array(1,2,3);」とした場合、

    親カテゴリ(1):子カテゴリ
             :
             :
    親カテゴリ(2)
    親カテゴリ(3)

    となり、なぜか「:」がずれてしまっていたからです。

    私が無知なせいでかなり時間がかかってしまいましたが、
    $result[1] .= '<dd>:</dd>';」を「$result[$id] .= '<dd>:</dd>';」にすることで、無事解決することができました!
    本当にありがとうございました!

    さて、ID毎にコピー不要の便利な配列処理にしていただきましたので、現在は親カテゴリ名を取得しようと頑張っているのですが、なかなかうまくいきません。。。

    <dl>
    <?php
    	$args	= array('orderby' => 'ID');
    	$terms	= wp_get_post_terms( $post->ID , 'category', $args);
    	$html	= '<dd>:<a href="%1$s" title="%2$s">%3$s</a></dd>';
    	$colon	= array();
    	$result	= array();
    	/*表示したいIDを列挙*/
    	$ids	= array(1,2,3);
    	/*親カテゴリ名を取得*/
    	$parent	= get_category_parents($ids, true,'');
    
    	foreach($terms as $key=>$term){
    		foreach($ids as $id){
    			if($key== 0){
    				//loopの最初
    				$result[$id] = '<dt>'.$parent.'</dt>';
    				$colon[$id] = false;
    			}
    			if(cat_is_ancestor_of($id, $term)){
    				$result[$id] .= sprintf(	$html,
    						esc_url(get_term_link($term, 'category')),
    						sprintf( __( "%s" ), esc_attr($term->name)),
    						esc_html($term->name)
    				);
    				$coron[$id] = true;
    			}
    			if($key == count($terms) - 1){
    				//loopの最後
    				if($coron[$id] == false){
    					$result[$id] .= '<dd>:</dd>';
    				}
    			}
    		}
    	}
    	// 表示
    	array_walk($result, 'print_named_array');
    	function print_named_array($item, $key){
        	echo $item."\n";
    	}
    ?>
    </dl>

    試行錯誤を繰り返し、最終的に上記のように「$parent = get_category_parents($ids, true,'');」を加えてみたのが解決に一番近かったのですが、全て「親カテゴリ1」の名前になってしまうのです。

    もしかしたらこれを実現するのはとても簡単なことなのかもしれず恐縮なのですが、お知恵をお貸しいただければありがたいです。

    よろしくお願いいたします。

    こんにちは、

    へっぽこなコード書いて、お手数かけました ごめんなさい
    こうすればどうですか?

    <dl>
    <?php
    	$args	= array('orderby' => 'ID');
    	$terms	= wp_get_post_terms( $post->ID , 'category', $args);
    	$html	= '<dd>:<a href="%1$s" title="%2$s">%3$s</a></dd>';
    	$colon	= array();
    	$result	= array();
    	/*表示したいIDを列挙*/
    	$ids	= array(1,2,3);
    	/*親カテゴリ名を取得*/
    
    	foreach($terms as $key=>$term){
    		foreach($ids as $id){
    			if($key== 0){
    				//loopの最初
    				$result[$id] = '<dt>'.get_category_parents($id, true,'').'</dt>';
    				$colon[$id] = false;
    			}
    			if(cat_is_ancestor_of($id, $term)){
    				$result[$id] .= sprintf(	$html,
    						esc_url(get_term_link($term, 'category')),
    						sprintf( __( "%s" ), esc_attr($term->name)),
    						esc_html($term->name)
    				);
    				$coron[$id] = true;
    			}
    			if($key == count($terms) - 1){
    				//loopの最後
    				if($coron[$id] == false){
    					$result[$id] .= '<dd>:</dd>';
    				}
    			}
    		}
    	}
    	// 表示
    	array_walk($result, 'print_named_array');
    	function print_named_array($item, $key){
        	echo $item."\n";
    	}
    ?>
    </dl>
    トピック投稿者 yacchi

    (@yacchi)

    nobitaさま、ご返信が遅くなり申し訳ございません。
    教えていただいた内容で完璧に実現することができました!!
    解決方法がもう一歩だったとは本当に恥ずかしいです。

    この度は長くお付き合いいただき大変感謝いたします。
    自分ももっと精進できるよう頑張ります。
    また機会がありましたらぜひよろしくお願いいたします!

11件の返信を表示中 - 1 - 11件目 (全11件中)
  • トピック「get_the_categoryで取得したカテゴリ(複数)の表示順序の変更」には新たに返信することはできません。