web-dev-qa-db-ja.com

Wp_list_categoriesをカスタマイズする方法

次の画像のように表示されるようにカスタマイズしようとしている、Wooコマースのカテゴリのリストがあります。

List of categories

上記の画像は通常のHTMLとcssを使って作成しましたが、動的に作成するためにWordPressに変換したいと思います。

これがHTMLです。

<div class="col tertiary" id="filters">
        <ul class="product-categories">        

            <li id="pattern_garment_type">
                <h5>Women</h5>
                <ul>
                    <li class="selected">                
                          <a href="#">All</a>                        
                    </li>

                    <li class="">
                      <a href="#">Accessories</a>
                    </li>

                    <li class="">
                      <a href="#">Blouses</a>
                    </li>

                    .etc...

          </ul>
            </li>

            <li id="pattern_garment_type">
                <h5>Men</h5>
                <ul>
                <li class="selected">

                      <a href="#">All</a>

                </li>

                  <li class="">
                      <a href="#">Accessories</a>
                  </li>

                  <li class="">
                      <a href="#">Coats</a>
                  </li>
                  ..etc..

                </ul>
            </li>


            <li id="pattern_garment_type">
                <h5>Kids</h5>
                <ul>
                <li class="selected">

                      <a href="#">All</a>

                </li>

                  <li class="">
                      <a href="#">Babies</a>
                  </li>

                  <li class="">
                      <a href="#">Girls</a>
                  </li>

                  <li class="">
                      <a href="#">Boys</a>
                  </li>

                </ul>
            </li>

        </ul>
    </div>

これが現在作業中のWordPressコードです(上記のHTMLのように生成される出力をカスタマイズするためにwalkerを使用する必要があるかどうかはわかりません)。

  <div id="content-filters" class="two columns">
<?php $args = array(
    'style'              => 'list',
    'show_count'         => 0,
    'use_desc_for_title' => 1,
    'child_of'           => 0,
    'title_li'           => __( '' ),
    'show_option_none'   => __('No Menu Items'),
    'number'             => null,
    'echo'               => 1,
    'depth'              => 2,
    'taxonomy'           => 'product_cat',
); ?>

<div class="col tertiary" id="filters">
    <ul class="product-categories">   
        <?php wp_list_categories( $args ); ?>
    </ul>
</div>

1)wp_list_categoriesフィルターを使用して、すべての項目を表示するページにリンクするサブカテゴリーの上部に「All」リンクを追加する方法を教えてください。

2)wp_list_categoriesフィルタを使用して、親の親カテゴリからリンクを削除し、それを太字にするためににラップすることもできます(例の画像のように)。

任意の助けがいただければ幸いです

2
Oudin

wp_list_categoriesフィルタが存在していても、それはwp_list_categories()関数によって生成されたhtmlマークアップを通過させます(そしてあなたは返さなければなりません)。つまり、そのフィルタを使いたいのであれば、phpを使ってDOMを変更する必要があり、たとえそれが可能であっても(できれば外部のphpライブラリを使って)、それがあなたのニーズに最適なソリューションではないことを確認してください。それが作成された後に別の方法はhtmlを変更するためにjsを使用することです。それは可能性です、しかし私はWP開発者ではなくjs開発者です、それで私はあなたにWorpressの解決策をあげるでしょう。

あなたはカスタムの Category Walker クラスを作成し、それをカスタマイズ版のwp_list_categories()の中で使う必要があります。

始めましょう。

すべてのカスタムCategory Walkerクラスの最初のもの(functions.phpに入れる):

class My_Category_Walker extends Walker_Category {

  var $lev = -1;
  var $skip = 0;
  static $current_parent;

  function start_lvl( &$output, $depth = 0, $args = array() ) {
    $this->lev = 0;
    $output .= "<ul>" . PHP_EOL;
  }

  function end_lvl( &$output, $depth = 0, $args = array() ) {
    $output .= "</ul>" . PHP_EOL;
    $this->lev = -1;
  }

  function start_el( &$output, $category, $depth = 0, $args = array(), $id = 0 ) {
    extract($args);
    $cat_name = esc_attr( $category->name );
    $class_current = $current_class ? $current_class . ' ' : 'current ';
    if ( ! empty($current_category) ) {
      $_current_category = get_term( $current_category, $category->taxonomy );
      if ( $category->term_id == $current_category ) $class = $class_current;
      elseif ( $category->term_id == $_current_category->parent ) $class = rtrim($class_current) . '-parent ';
    } else {
      $class = '';
    }
    if ( ! $category->parent ) {
      if ( ! get_term_children( $category->term_id, $category->taxonomy ) ) {
          $this->skip = 1;
      } else {
        if ($class == $class_current) self::$current_parent = $category->term_id;
        $output .= "<li class='" . $class . $level_class . "'>" . PHP_EOL;
        $output .= sprintf($parent_title_format, $cat_name) . PHP_EOL;
      }
    } else { 
      if ( $this->lev == 0 && $category->parent) {
        $link = get_term_link(intval($category->parent) , $category->taxonomy);
        $stored_parent = intval(self::$current_parent);
        $now_parent = intval($category->parent);
        $all_class = ($stored_parent > 0 && ( $stored_parent === $now_parent) ) ? $class_current . ' all' : 'all';
        $output .= "<li class='" . $all_class . "'><a href='" . $link . "'>" . __('All') . "</a></li>\n";
        self::$current_parent = null;
      }
      $link = '<a href="' . esc_url( get_term_link($category) ) . '" >' . $cat_name . '</a>';
      $output .= "<li";
      $class .= $category->taxonomy . '-item ' . $category->taxonomy . '-item-' . $category->term_id;
      $output .=  ' class="' . $class . '"';
      $output .= ">" . $link;
    }
  }

  function end_el( &$output, $page, $depth = 0, $args = array() ) {
    $this->lev++;
    if ( $this->skip == 1 ) {
      $this->skip = 0;
      return;
    }
    $output .= "</li>" . PHP_EOL;
  }

}

これはWP Walker_Categoryを拡張し、4つのメソッドすべてを自分のニーズに合ったもので上書きします。

その後、functions.phpにカスタマイズした関数を入れます。

function custom_list_categories( $args = '' ) {
  $defaults = array(
    'taxonomy' => 'category',
    'show_option_none' => '',
    'echo' => 1,
    'depth' => 2,
    'wrap_class' => '',
    'level_class' => '',
    'parent_title_format' => '%s',
    'current_class' => 'current'
  );
  $r = wp_parse_args( $args, $defaults );
  if ( ! isset( $r['wrap_class'] ) ) $r['wrap_class'] = ( 'category' == $r['taxonomy'] ) ? 'categories' : $r['taxonomy'];
  extract( $r );
  if ( ! taxonomy_exists($taxonomy) ) return false;
  $categories = get_categories( $r );
  $output = "<ul class='" . esc_attr( $wrap_class ) . "'>" . PHP_EOL;
  if ( empty( $categories ) ) {
    if ( ! empty( $show_option_none ) ) $output .= "<li>" . $show_option_none . "</li>" . PHP_EOL;
  } else {
    if ( is_category() || is_tax() || is_tag() ) {
      $current_term_object = get_queried_object();
      if ( $r['taxonomy'] == $current_term_object->taxonomy ) $r['current_category'] = get_queried_object_id();
    }
    $depth = $r['depth'];
    $walker = new My_Category_Walker;
    $output .= $walker->walk($categories, $depth, $r);
  }
  $output .= "</ul>" . PHP_EOL;
  if ( $echo ) echo $output; else return $output;
}

難しい部分は終わりました。テンプレートコードは、必要な場所に配置します。

<div id="content-filters" class="two columns">
<div class="col tertiary" id="filters">
<?php
$args = array(
  'taxonomy' => 'product_cat',
  'show_option_none' => __('No Menu Items.'),
  'echo' => 1,
  'depth' => 2,
  'wrap_class' => 'product-categories',
  'level_class' => 'pattern_garment_type',
  'parent_title_format' => '<h5>%s</h5>',
  'current_class' => 'selected'
);
custom_list_categories( $args );
?>
</div>
</div>

必要に応じて$ argsをカスタマイズします。私はあなたの回答コードに従ってそれらを設定しました。マークアップのようにhtmlで同じタグIDを複数回使用することはできないため、 'pattern_garment_type'をクラスではなくIDに変更したのは私だけです。

それがすべてです、それが役立つことを願っています。

3
gmazzap

ウーディン、

私はあなたの質問のCSS部分に答えます。

これを使用してリストの箇条書きを削除します。

.ul.product-categories, ul.children{
    list-style-type: none;

}

これを使用して、主要なカテゴリのみを太字にします。

li {font-weight:normal} // you need to set the default state first of the list

ul.product-categories > li{font-weight:bold;} //then you can change the top level list without affecting its children

そういうわけであなたはあなた自身のクラスを書かずにcssでそれらの要素をターゲットにします。

これをwp_list_categories引数に追加することもできます。

'hide_empty' => 0

投稿がない場合でも、すべてのカテゴリを表示します。

質問の後半部分には2つの方法があります([ALL]リンクを追加する、およびメインカテゴリからリンクを削除する)。

  1. ページが読み込まれたら、Javascript/jqueryを使用して必要なものを削除または追加できます。
  2. Wp_list_categoriesフィルタを書いてそれらの変更を加えることができます

選択肢2は、それを行うためのきれいな方法でしょう。オプション1は、それを実行するための最速の方法でしょう。

時間が足りないので、私はどちらにもたどり着きませんでした。しかし、ワードプレスでフィルタを作成することを検討してください。

0
gdaniel