1

I'm trying to list a set amount of product categories (x) in a dropdown menu, but if the total amount of product categories are greater than x then only list x minus 1 and display “view all categories” link in last place. What I'm trying to achieve is only 8 entries per column (including view all link) with 4 columns total.

Im a beginner and have exhausted my knowledge of if/else logic. Everything I have tried has messed up the results.

Here is the basic code that lists them in columns of 8 up to total of 32. Id like if there are 33 or more categories for the 32nd to be a link to all of them. If only 32 then just list all 32 with no link.

<?php

$args = array(
    'taxonomy'     => 'product_cat',
     'orderby'      => 'name',
     'number'       => 32,   //maximum to list
     'title_li'     => '',
     'show_count'   => 0,    // 1 for yes, 0 for no
     'pad_counts'   => 0,    // 1 for yes, 0 for no
     'hierarchical' => 1,    // 1 for yes, 0 for no
     'hide_empty'   => 0,    // 1 for yes, 0 for no
     'echo'  => 0,           // 1 for yes, 0 for no
     'exclude' => '73, 74, 16', //best sellers, new, and uncategorized
     'depth'  => '1',        //top level categories, not sub
     'style'  => '',         //default is list with bullets, '' is without
);

// Grab top level categories
$get_cats = wp_list_categories($args);

// Split into array items
$cat_array = explode("<br />",$get_cats);

// Amount of categories (count of items in array)
$results_total = count($cat_array);

// How many tags to show per list-8)
$remainder = ($results_total-8);
$cats_per_list = ($results_total-$remainder);

// Counter number for tagging onto each list
$list_number = 1;

// Set the category result counter to zero
$result_number = 0;
?>

<div class="cat_columns" id="cat-col-<?php echo $list_number; ?>">

<?php     
foreach($cat_array as $category) {        
    $result_number++;

    if($result_number >= $cats_per_list) { 
        $result_number = 0; 
        $list_number++;
        echo '<div>'.$category.'</div> </div> <div class="cat_columns" id="cat-col-'.$list_number.'">';
    }
    else {         
        echo '<div>'.$category.'</div>'; 
    }
}
echo '<a href="https://www.aaaa.com/all-categories//">View Categories</a>';
?> 

1 Answer 1

3

The following will display in 4 columns 32 terms max at all (product categories) so 8 items by column. If there is more than 32 terms, it replace the 32th term by "View Categories" custom linked item:

<?php

## Settings
$items_per_col  = 8; // Number of items by column
$number_of_cols = 4; // Number of columns
$taxonomy       = 'product_cat'; // WooCommerce product category taxonomy
$excluded_ids   = '73, 74, 16'; // Excluding "best sellers", "New" and "Uncategorized" terms Ids

## Initializing variables
$col_count = 1;
$counter   = 0; 
$html      = '';

$max_items = $number_of_cols * $items_per_col; // Max number of items (calculation)

$terms_list = wp_list_categories( array(
    'taxonomy'     => $taxonomy,
    'number'       => ( $max_items + 1 ), // 33 max
    'title_li'     => '',  // disabled
    'pad_counts'   => 0,   // no
    'hide_empty'   => 0,   // no
    'echo'         => 0,   // return (not echo)
    'style'        => '',  // Without style (bullets)
    'depth'        => '1', // Top level terms only
    'exclude'      => $excluded_ids,
) );

$terms_array = explode( "<br />", $terms_list ); // Split each item in an array of terms

array_pop($terms_array); // <== We remove last empty item from the array.

$items_count = count($terms_array); // get items (terms) count

// Loop through product categories terms
foreach ( $terms_array as $term_html ) {
    if ( $counter == 0 ) { // column start
        $html .= '<div class="cat-columns" id="cat-col-' . $col_count . '" style="float:left; margin: 0 10px;">';
    }

    if( $items_count > $max_items && $col_count == $number_of_cols && $counter == ($items_per_col - 1) ) {
        $link    = home_url( "/all-categories/", "https" );
        $html .= '<div><a href="' . $link . '">' . __("View Categories") . '</a></div>';
    }
    else {
        $html .= '<div data-counter="'.$counter.'">' . $term_html . '</div>';
    }

    $counter++; // Increase items counter

    if ( $counter == $items_per_col ) { // column end
        $html .= '</div>';

        $counter = 0; // Reset items counter
        $col_count++; // Increase colum count

        if ( $col_count > $number_of_cols ) {
            break; // Stop the loop (to be sure)
        }
    }
}

## html output
echo '<div class="categories-wrapper">' . $html. '</div>'; 
?>

Tested and works.

5
  • Thanks, however at the moment I only have 18 categories. $number_of_cols=4 breaks the menu. When I change it to 2 it works, however I would like this number to be flexible and grow with the categories without need for changing the code.
    – aye cee
    Commented Sep 8, 2019 at 10:09
  • @Whee This answer is answering your initial question which is a menu with 4 columns and 8 items in each (so 32 items at all)... As this works, therefore you should please accept the answer, Thank you. Now if you need something different you should ask a new question. Commented Sep 8, 2019 at 11:52
  • Thank you again but categories are variable, they get deleted and added all the time, hence why i referred to ‘x’ and 4 columns as a total, as in no more than that. The numbers given were in regards to the max and to illustrate what I was trying to achieve. Do I really need to post a new question for this?
    – aye cee
    Commented Sep 8, 2019 at 12:41
  • by the way you also changed the title of my question. My question title also referred to listing 'x' amount of categories.
    – aye cee
    Commented Sep 8, 2019 at 12:51
  • @Whee The initial title of your question was "List x amount of categories in dropdown menu"… 1) It is about a custom columnized menu (but not a "dropdown menu)… 2) It's about Woocommerce product categories (but not WordPress post categories)... Please note that people that answer here do it gently for free and answers can be fine tuned by askers (and other readers) to fit their own specific needs. Commented Sep 8, 2019 at 14:26

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