2

I have a list of categories in woo-commerce which I'm trying to customize to be displayed to look like the following image.

List of categories

I created the above image using normal HTML and css however I would like to now convert it to WordPress in order to have it dynamically created.

Here is the 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>

Here is the current WordPress code I'm working with (not sure if I should use the walker to customize the output to be generated like the HTML above):

  <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) How can I use wp_list_categories filter to add an "All" link at the top of the sub categories which links to a page which displays all items.

2) How can I also use the wp_list_categories filter to remove the link from the parent parent category and wrap it in an to make it bold (like in the example image)?

Any help would be appreciated

  • 1
    what you have should already print out the categories and subcategories of product_cat. Are you asking how to style it? If so you just need to use the classes that wordpress gives you. For example: "cat-item" for the parent category and "children" for the sub categories. – gdaniel May 8 '13 at 15:10
  • I updated the question to provide more detail as to what i'm trying to accomplish – Oudin May 8 '13 at 23:29
3

Even if a wp_list_categories filter exists, it passes (and so you have to return) the html markup generated by wp_list_categories() function. This means that if you want use that filter you have to alter the DOM with php, and even if it's possible (hopefully using external php libraries), sure it's not the best solution for your needs. Alternartive are use js to alter html after it was created. It's a possibility, but I'm a WP developer not a js one, so I'll give you the Worpress solution.

You have to create a custom Category Walker class and then use it inside a customuized version of wp_list_categories();

Let's start.

First of all the custom Category Walker class (put it in 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;
  }

}

It extends the WP Walker_Category and overwrite all the 4 methods with something that fits your needs.

After that, in the functions.php put the customized function:

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;
}

The hard part is done. Now the template code, put it everywhere you need:

<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>

Customize the $args if you want, I setted them according to you answer code. Only I have changed 'pattern_garment_type' to be class and not an id, because you can't have the same tag id multiple times in html (as in your markup).

That's all, hope it helps.

0

Oudin,

I will answer here the CSS part of your question:

Use this to remove the list bullets:

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

}

Use this to make only the main categories bold:

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

That's how you target those elements with css without having to write your own classes.

You can also add this to your wp_list_categories arguments

'hide_empty' => 0

To show all categories, even those who do not have a post.

There are two approaches you can take to the second part of your question (adding the ALL link, and removing the link from the main categories)

  1. You can use Javascript/jquery to remove/add what you want once the page has loaded
  2. You can write a wp_list_categories filter, to make those changes

Option 2, would be the clean way to do it. Option 1, would be the fastest way to do it.

I have not gotten to either, becasue of lack of time. But take a look into creating filters in wordpress.

  • Thanks for the response however I'm more interesting the WordPress coding rather than CSS as stated I've already created the HTML and CSS for the included image. What is required is the proper way to generate the HTML via WordPress similar to what I have provided. So if you can expand on the filters that would be great. – Oudin May 13 '13 at 4:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.