Как настроить wp_list_categories

8 мая 2013 г., 17:37:39
Просмотры: 30.1K
Голосов: 2

У меня есть список категорий в WooCommerce, который я пытаюсь настроить для отображения как на следующем изображении.

Список категорий с настроенным форматированием

Я создал изображение выше, используя обычный HTML и CSS, однако теперь я хотел бы преобразовать его в WordPress, чтобы он создавался динамически.

Вот HTML код:

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

            <li id="pattern_garment_type">
                <h5>Женщины</h5>
                <ul>
                    <li class="selected">                
                          <a href="#">Все</a>                        
                    </li>

                    <li class="">
                      <a href="#">Аксессуары</a>
                    </li>

                    <li class="">
                      <a href="#">Блузки</a>
                    </li>

                    .и т.д...

          </ul>
            </li>

            <li id="pattern_garment_type">
                <h5>Мужчины</h5>
                <ul>
                <li class="selected">

                      <a href="#">Все</a>

                </li>

                  <li class="">
                      <a href="#">Аксессуары</a>
                  </li>

                  <li class="">
                      <a href="#">Пальто</a>
                  </li>
                  ..и т.д..

                </ul>
            </li>


            <li id="pattern_garment_type">
                <h5>Дети</h5>
                <ul>
                <li class="selected">

                      <a href="#">Все</a>

                </li>

                  <li class="">
                      <a href="#">Малыши</a>
                  </li>

                  <li class="">
                      <a href="#">Девочки</a>
                  </li>

                  <li class="">
                      <a href="#">Мальчики</a>
                  </li>

                </ul>
            </li>

        </ul>
    </div>

Вот текущий WordPress код, с которым я работаю (не уверен, стоит ли использовать walker для настройки вывода, чтобы он генерировался как HTML выше):

  <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'   => __('Нет пунктов меню'),
    '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, чтобы добавить ссылку "Все" в начало подкатегорий, которая ведет на страницу, отображающую все элементы.

2) Как я также могу использовать фильтр wp_list_categories, чтобы удалить ссылку из родительской категории и обернуть её в тег для выделения жирным шрифтом (как на примере изображения)?

Буду благодарен за любую помощь

2
Комментарии

У вас уже должен выводиться список категорий и подкатегорий product_cat. Вы спрашиваете, как стилизовать их? Если да, то вам нужно использовать классы, которые предоставляет WordPress. Например: "cat-item" для родительской категории и "children" для подкатегорий.

gdaniel gdaniel
8 мая 2013 г. 18:10:03

Я обновил вопрос, чтобы подробнее описать, чего пытаюсь достичь.

Oudin Oudin
9 мая 2013 г. 02:29:27
Все ответы на вопрос 2
0

Даже если существует фильтр wp_list_categories, он передает (и вы должны вернуть) HTML-разметку, сгенерированную функцией wp_list_categories(). Это означает, что если вы хотите использовать этот фильтр, вам придется изменять DOM с помощью PHP, и хотя это возможно (желательно с использованием внешних PHP-библиотек), это точно не лучшее решение для ваших нужд.

Альтернатива — использовать JavaScript для изменения HTML после его создания. Это возможно, но я разработчик WordPress, а не JavaScript, поэтому я дам вам решение на WordPress.

Вам нужно создать собственный класс 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 по своему усмотрению, я установил их в соответствии с вашим кодом. Только я изменил 'pattern_garment_type' на класс, а не на id, потому что в HTML нельзя иметь один и тот же id у нескольких элементов (как в вашей разметке).

Вот и все, надеюсь, это поможет.

25 июл. 2013 г. 06:11:52
1

Oudin,

Отвечаю на часть вашего вопроса по CSS:

Используйте это, чтобы убрать маркеры списка:

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

}

Используйте это, чтобы сделать только основные категории жирными:

li {font-weight:normal} // сначала нужно установить обычное состояние списка

ul.product-categories > li{font-weight:bold;} // затем можно изменить верхний уровень списка, не затрагивая дочерние элементы

Вот как можно стилизовать эти элементы с помощью CSS, не создавая собственные классы.

Вы также можете добавить этот аргумент в wp_list_categories:

'hide_empty' => 0

Чтобы показать все категории, даже те, в которых нет записей.

Есть два подхода к решению второй части вашего вопроса (добавление ссылки ALL и удаление ссылок из основных категорий):

  1. Можно использовать Javascript/jQuery для удаления/добавления нужных элементов после загрузки страницы
  2. Можно написать фильтр для wp_list_categories, чтобы внести эти изменения

Вариант 2 будет более правильным с точки зрения архитектуры. Вариант 1 будет самым быстрым в реализации.

Я пока не реализовал ни один из них из-за нехватки времени. Но рекомендую изучить создание фильтров в WordPress.

9 мая 2013 г. 21:32:30
Комментарии

Спасибо за ответ, однако меня больше интересует кодинг для WordPress, а не CSS, как я уже упоминал, я уже создал HTML и CSS для приложенного изображения. Что требуется — это правильный способ генерации HTML через WordPress, аналогичный тому, что я предоставил. Так что если вы могли бы подробнее рассказать о фильтрах, это было бы замечательно.

Oudin Oudin
13 мая 2013 г. 07:12:32