0

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>';
?> 

closed as off-topic by Jacob Peattie, Howdy_McGee Sep 24 at 3:26

This question appears to be off-topic. The users who voted to close gave this specific reason:

If this question can be reworded to fit the rules in the help center, please edit the question.

2

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.

  • 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. – Whee Sep 8 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. – LoicTheAztec Sep 8 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? – Whee Sep 8 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. – Whee Sep 8 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. – LoicTheAztec Sep 8 at 14:26

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