tips

投稿画面のカテゴリーをセレクトボックスにしたりラジオボタンにしたり。

sc-2015-01-25-13.23.51

投稿画面のカテゴリやタグのメタボックスを使いやすくするあれこれ

先日、wordpressの管理画面でのタグクラウドをデフォルトで表示する方法を書きましたが、同じくカテゴリーやカスタムタクソノミノーの表示をあれこれ変更する方法を書いておきます。CMSで納品するときなどには大事な心遣いだと思います。カスタムタクソノミに適用するときは、「category」となっているところをすべてタクソノミ名に変換します。

 

「よく使うもの」リンクとタブを消す。

よく使う項目を表示とか余計なお世話、というときは消してしまう。

div#category-pop, ul#category-tabs { display:none; }

「+ 新規カテゴリーを追加」リンクを消す

同じく、カテゴリを追加ボタンも投稿画面から触ってほしくないときは消してしまう。

div#category-adder { display:none; }

カテゴリメタボックスのmax-heightを解除

デフォルトのカテゴリメタボックスが高さが200pxを超えるとスクロール表示される。視認性を確保したいときはこの設定を消してしまう。

div#category-all { max-height:none; }

カテゴリのチェックボックスをラジオボタンに変換

var checklist = $( '#categorychecklist' );
checklist.each( function(){
    $( this ).find( 'input' ).attr( 'type', 'radio' );
    if ( $( this ).find( 'input' ).is(':checked') === false ) $( this ).children( 'li:first' ).find( 'input' ).prop('checked', true);
});

カテゴリをひとつしか選んでほしくないときは、jQueryでラジオボタンに変換します。

カテゴリのチェックボックスをセレクトボックスに変換

カテゴリの項目が多いときは、jQueryでセレクトボックスに変換して省スペース化を計るととても使いやすいです。

var options=[]; 
$( "#categorychecklist label" ).each(function(){ 
    options.push( '<option value="' + $(this).children("input").val()+ '">' + $(this).html().replace(/<input[^>]+>/g, '') + '</option>' ); 
});
$( "#categorychecklist" ).replaceWith( '<select id="categorychecklist" name="tax_input[category][]" style="width:100%; margin:10px 0; ">' + options.join( '' ) + '</select>' );

チェックボックスを並び替えないようにする

ついでに並び順のデフォルトが、チェックが入っているボックスが一番上にくるようになっていますので、それも外してみます。これはフックで。

add_filter( 'wp_terms_checklist_args', 'stop_checked_ontop' ,10,2); 
function stop_checked_ontop( $args, $post_id ){ 
    $args['checked_ontop'] = false; 
    return $args; //チェックボックスの並び替え停止
}

 

CODE : Hook to admin_head

タグクラウドのデフォルト表示もまとめたコードです。以下の関数をお好みでカスタマイズしてadmin_headフックしたものをfunctions.phpに記載します。当然ですが、このまま有効にすると、ラジオボタンに変換する関数とセレクトボックスに変換する関数とがコンフリクトします。

<?php
function my_admin_head(){ 
?>
<style type="text/css">
    /*  カテゴリ欄のタブ非表示  */ 
    /*  remove tabs from category metabox  */ 
    div#category-pop, ul#category-tabs { display:none; }

    /*  カテゴリ追加ボタン非表示  */ 
    /*  remove category add button from category metabox  */
    div#category-adder { display:none; }

    /*  カテゴリ欄を最大サイズに変更  */ 
    /*  unset max-height of category metabox  */
    div#category-all { max-height:none; }
</style>
<script type="text/javascript">
jQuery(function( $ ){ 

    /*  チェックボックスをラジオボタンに変換  */
    /*  change category check box into radio button  */
    var checklist = $( '#categorychecklist' );
    checklist.each( function(){
        $( this ).find( 'input' ).attr( 'type', 'radio' );
        if ( $( this ).find( 'input' ).is(':checked') === false ) $( this ).children( 'li:first' ).find( 'input' ).prop('checked', true);
    });

    /*  チェックボックスをセレクトボックスに変換  */
    /*  change category check box into select box  */
    var options=[]; 
    $( "#categorychecklist label" ).each(function(){ 
        options.push( '<option value="' + $(this).children("input").val()+ '">' + $(this).html().replace(/<input[^>]+>/g, '') + '</option>' ); 
    });
    $( "#categorychecklist" ).replaceWith( '<select id="categorychecklist" name="tax_input[category][]" style="width:100%; margin:10px 0; ">' + options.join( '' ) + '</select>' );

    /*  タグクラウドをデフォルトで表示に変更  */
    /*  automatically display the popular tags  */
    $( 'a.tagcloud-link' ).each( function(){ 
        tagBox.get( $(this).attr( 'id' ) ); 
        $(this).html('').unbind().click(function(){ 
            $(this).siblings( '.the-tagcloud' ).toggle(); return false; 
        }); 
        return false; 
    });
});
</script>
<?php 
}
add_filter( 'admin_head', 'my_admin_head' );

function stop_checked_ontop( $args, $post_id ){ 
    if ( $args['checked_ontop'] !== false ) $args['checked_ontop'] = false; 
    return $args; //チェックボックスの並び替え停止
} 
add_filter( 'wp_terms_checklist_args', 'stop_checked_ontop' ,10,2); 
?>

参考

ラジオボタンとチェックボックスのソート解除は以下を参考にしました。あとは見当たらなかったので自作。

Category checkbox list tree changes when editing a post

WordPressのカスタムタクソノミーのチェックボックスをラジオボタンにする方法(クイック編集でもチェックボックスの制限をしたい場合なども参考になります。)

「複数タクソノミーで絞り込めるアーカイブページを作成する。」への3件の返信

  1. 初めまして。

    今、不動産サイトを作成していて、イメージに近いものと感じました。

    こちらpostで作成した場合は、どのテンプレートに記述したら良いのでしょうか?archive.php で良いでしょうか?
    それともarchive-items.phpなどでしょうか?

  2. こんにちは。

    不特定多数のタクソノミで絞り込んでいくための、ループさせる記述の仕方がわからず、ご教授いただけますと幸いです。

    1. get_object_taxonomiesでポストタイプに基づいてタクソノミーを必要なだけループさせたらいいと思いますが、そうなったら上の記述はスタティックすぎるので、丸ごと変えたほうが早いと思います。

  3. はじめまして。

    まさに探していた内容で試してみたのですが、
    うまくいかず、分からないことがあるので教えていただけると嬉しいです。

    カスタム投稿games
    カスタムタクソノミー gamelist
    ターム a , b , c
    カスタムタクソノミー gameyear
    ターム 2014 , 2015

    gamelistとgameyearは必ず一つ選択するようになっている。

    作成したいのは、
    gamelist のターム a のターム 2014 とターム 2015 を固定ページaaaにて表示
    gamelist のターム b のターム 2014 とターム 2015 を固定ページbbbにて表示
    gamelist のターム c のターム 2014 とターム 2015 を固定ページcccにて表示

    「href=”~/aaa?gamelist=a&gameyear=2014” class=”current”」
    「href=”~/aaa?gamelist=a&gameyear=2015” class=”current”」
    と表示はされますが、クリックすると表示されなかったり、全部表示されたりとうまく表示されません。

    また、表示される項目は例題だとリスト形式でタイトルを取得している形ですが、


    タイトル
    項目3
    項目4
    項目5
    項目6

    ・上記のようなtableで6項目表示
    ・それらはAdvanced Custom Fieldsで入力したもの
    ・Advanced Custom Fieldsで入力した日付(gamedate)で新しい日付→古い日付の順で並べ替えをしたい

    質問ばかりで申し訳ないのですが、あと一歩のところ頑張りたいのでよろしくお願いいたします。

    1. こんにちわ。

      3つのページではそれぞれタクソノミひとつは固定されているわけですね。それでしたら、ここで書いているものよりも少し簡単にすることができます。きっちり検証してませんが、これで行けるのではないでしょうか。

      <?php
          $this_url = get_permalink( $post->ID );
      
          $tax1 = 'gamelist'; //TAX1に自由なタクソノミ名を設定
          if (is_page( 'aaa' )){
              $tax1_get = 'a';
          } elseif (is_page( 'bbb' )){
              $tax1_get = 'b';
          } elseif (is_page( 'ccc' )){
              $tax1_get = 'c';
          }
      
          $tax2 = 'gameyear'; //TAX2に自由なタクソノミ名を設定
          if ( isset( $_GET[$tax2] ) ) $tax2_get = $_GET[$tax2]; //URLパラメータを取得
          $terms = get_terms( $tax2, '&hide_empty=true' );
          if ( $terms ){ 
              foreach( $terms as $term ){
                  $current = '';
                  if ( empty ( $tax2_get ) ) $tax2_get = $term->slug; //未指定の場合、タームの最上位をデフォルトに設定
                  if ( $tax2_get == $term->slug ) $current = 'current';
                  echo '<a href="'.$thisurl.'?'.$tax2.'='.$term->slug.'" title="'.$term->name.'" class="'.$current.'">' .$term->name. '</a>'. "\n";
              }
          }
      
          $args = array(
              'post_type' => 'games', //自由なポストタイプを設定
              'paged' => $paged,
              'meta_key' => 'gamedate', //ソートキーに指定するカスタムフィールド
              'orderby' => 'meta_value',
              'order' => 'ASC',  //降順はDESC
              'tax_query' => array(
                  array( 
                      'taxonomy' => $tax1,
                      'field' => 'slug',
                      'terms' => $tax1_get,
                  ), array(
                      'taxonomy' => $tax2,
                      'field' => 'slug',
                      'terms' => $tax2_get,
                  ),
              ),
          );
          $wp_query = new WP_Query();
          $wp_query->query( $args );
          while ( $wp_query->have_posts() ) : $wp_query->the_post(); 
      ?>    
      <div class="post">
      <h1><?php the_title( $post->ID ); ?></h1>
      <div class="date">
      <?php 
          $date = get_post_meta( $post->ID, 'gamedate', true );
           echo date("Y/m/d",strtotime( $date ));
      ?>
      </div>
      </div>
      <?php endwhile; ?>
      <div class="page-navigation">
          <div class="older"><?php previous_posts_link( '« 前へ' ); ?></div>
          <div class="newer"><?php next_posts_link( '次へ »'); ?></div>
      </div>
    2. 早速のご回答、ありがとうございます!

      上記記述をpage-aaa.phpに記述して試したのですが、
      21行目の

      echo '<a href="'.$thisurl.'?'.$tax2.'='.$term- rel="nofollow">slug.'" title="'.$term->name.'" class="'.$current.'" rel="' .$term->slug. '">' .$term->name. '</a>'. "\n";

      の部分が「Parse error: syntax error, unexpected ‘=’, expecting ‘,’ or ‘;’ 」というエラーが出ます。

      あとエラーが出て見れてないのですが、説明がうまく伝わっていないかもしれないです。
      http://www.wasedabbc.org/game/tokyo-6-spring/
      上記サイトのように、例えばタームaの内容(上記サイトだと春季リーグ戦)をgameyear(2014、2015)ごとに表示したいです。
      その際、表示した内容の上側にカスタムタクソノミーgameyearのタームの名前「2014年」「2015年」とリンク表示させたいです。
      タームごとの年別表示をしたいのですが、調べてもできないようなので、年度のカスタム分類を作ったのです。
      それをうまく表示させる理想のものがこちらの記事でした。
      どうぞよろしくお願いいたします。

    3. 笑)wordpressのnofollowフィルターが掛かってるんですね。

      ご覧の通り「$term->slug」に「 rel=”nofollow”」が無理矢理挟まってます。
      で、そのエラーの箇所が2014 2015とリンクを吐き出すところです。ちょちょっとマークアップすれば参考サイトのようにセレクタにもできるかと思います。

      ひとつ前のコメント内のコードを見直して上書きしておきました。お試しください。

    4. すぐに回答していただきありがとうございました。

      バッチリと表示されました。
      思うようにできず、1か月ほど試行錯誤していたので本当に助かりました。
      本当に本当にありがとうございます!!!

      それでまた質問なんですが、2014年の内容が表示されているときに「2014年」、2015年の内容が表示されているときに「2015年」と内容の上に表示させたいのですが、

      <h3><?php echo esc_html( $term->name ); ?>オープン戦</h3>

      だとどちらも「2015年」と表示されてしまいます。

      それと。。。
      >ちょちょっとマークアップすれば参考サイトのようにセレクタにもできるかと思います。
      ご教授いただけるとありがたいです。

      質問ばかりで申し訳ないのですが、どうぞよろしくお願いいたします。

    5. 表示中のtax2(gameyear)は$tax2_getで取得していますので、その$tax2_getが取得されているところより下であればgameyearのタイトルも出力できます。

      ただし$tax2_getはスラッグですので、再度「get_term_by( ‘slug’, $tax2_get, $tax2 )」としてカテゴリ情報を取得する行程が必要です。以下、動作未検証です。

      <?php
          $this_url = get_permalink( $post->ID );
          $tax1 = 'gamelist'; //TAX1に自由なタクソノミ名を設定
          if (is_page( 'aaa' )){
              $tax1_get = 'a';
          } elseif (is_page( 'bbb' )){
              $tax1_get = 'b';
          } elseif (is_page( 'ccc' )){
              $tax1_get = 'c';
          }
          $tax2 = 'gameyear'; //TAX2に自由なタクソノミ名を設定
          if ( isset( $_GET[$tax2] ) ) $tax2_get = $_GET[$tax2]; //URLパラメータを取得
          $terms = get_terms( $tax2, '&hide_empty=true' );
          if ( $terms ){ 
              $select = '<select name="yearselect" onChange="location.href=value;">'. "\n";
              foreach( $terms as $term ){
                  $selected = '';
                  if ( empty ( $tax2_get ) ) $tax2_get = $term->slug; //未指定の場合、タームの最上位をデフォルトに設定
                  if ( $tax2_get == $term->slug ) $selected = ' selected="selected"';
                  $select .= "\t".'<option value="'.$thisurl.'?'.$tax2.'='.$term->slug.'"'.$selected.'>' .esc_html($term->name). '</option>'. "\n";
              }
              $select .= '</select>'. "\n";
          }
          echo $select;
      ?>
      <h3><?php echo esc_html(get_term_by( 'slug', $tax2_get, $tax2 )->name); ?>オープン戦</h3>
      <?php //以下略 ?>
    6. 迅速に対応していただいてありがとうございました!

      バッチリどちらも表示されました。
      もっとこちらに早くいきついていたらなあ。。。と思うくらい理想的な表示ができました。
      本当にありがとうございました。
      また分からないことがあったらお世話になるかもしれませんが、よろしくお願いいたします。

コメントを残す

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