A couple of days ago I showed you how to make a category menu. In this post I'm going to show you how to create an even more advanced version of the same function, that not only has all the same features, but also includes the ability to be sorted into a different order.
Overview:
Here's the list of abilities we want our function to have once we're finished:
- Display all categories
- Exclude categories by will
- Highlight categories (not on single pages)
- Sortable
Step 1: Prep
Our first step is to open our theme's functions.php and header.php. Inside functions.php create a new function we'll call "category_list_menu".
function category_list_menu(){
// our code here
}
And we'll reference this function in header.php in the menu section.
<div id="menu">
<div class="mainwidth">
<?php category_list_menu(); ?>
</div>
</div><!-- #menu -->
Step 2: Basics
Last time when doing this, we used the get_all_category_ids() function to get the IDs to run through our loop. This time however we're going to be using the get_terms() function to do that because later on we're going to be sorting the categories by sorting the data in get_terms().
function category_list_menu(){
$terms = get_terms('category'); //gets only category related information
}
Next let's loop through array of information using a foreach statement. So you can see what's going on inside of the variable we're working with, we'll also print_r() the variable.
function category_list_menu(){
$terms = get_terms('category');
foreach($terms as $cat){
print_r($cat);
}
}
As you can see from the print_r, $cat is an object, not an array like last time, so we're going to need to remember that when we're getting information from it. Next we're going to be using the continue; statement to exclude certian categories from being parsed and then we'll collect information about the remaining categories.
function category_list_menu(){
$terms = get_terms('category');
foreach($terms as $cat){
// print_r($cat);
if($cat->term_id == '35'){ //find category 35
continue; // skip rest of foreach
}
if(in_category($cat->term_id)){
$IDs .= 'cat-item-'.$cat->term_id.' ';
// outputs: "cat-item-5 " (with space)
}
$name .= strtolower($cat->name).' ';
// outputs: "category " (with space)
}
}
Now we'll format that data a little bit to remove some excess baggage.
function category_list_menu(){
$terms = get_terms('category');
foreach($terms as $cat){
// print_r($cat);
if($cat->term_id == '35'){ //find category 35
continue; // skip rest of foreach
}
if(in_category($cat->term_id)){
$IDs .= 'cat-item-'.$cat->term_id.' ';
// outputs: "cat-item-5 " (with space)
}
$name .= strtolower($cat->name).' ';
// outputs: "category " (with space)
}
$active = substr($IDs,0,-1); // remove last character (aka: " ")
$cat_class = substr($name,0,-1); // remove last character (aka: " ")
Step 3: Build
Now that we have all the extra information we need, it's time to list out our categories. Luckily, Wordpress does have a default function that will do this for us, wp_list_categories(). And we'll be passing 3 arguments to it, hide_empty=, title_li=, exclude=35.
function category_list_menu(){
$terms = get_terms('category');
foreach($terms as $cat){
// print_r($cat);
if($cat->term_id == '35'){ //find category 35
continue; // skip rest of foreach
}
if(in_category($cat->term_id)){
$IDs .= 'cat-item-'.$cat->term_id.' ';
// outputs: "cat-item-5 " (with space)
}
$name .= strtolower($cat->name).' ';
// outputs: "category " (with space)
}
$active = substr($IDs,0,-1); // remove last character (aka: " ")
$cat_class = substr($name,0,-1); // remove last character (aka: " ")
echo '<ul id="cat-menu" class="'.$cat_class.'">';
wp_list_categories('hide_empty=0&title_li=&exclude=35');
echo '</ul>';
}
Step 4: Extending
What we have right there will work perfectly well for everything we need, except for individual posts or pages, so we need to extend this function a little bit more to include those features. To do this, we're going to place some extra information into the class attribute of the UL and we'll go from there with jQuery.
function category_list_menu(){
$terms = get_terms('category');
foreach($terms as $cat){
// print_r($cat);
if($cat->term_id == '35'){ //find category 35
continue; // skip rest of foreach
}
if(in_category($cat->term_id)){
$IDs .= 'cat-item-'.$cat->term_id.' ';
// outputs: "cat-item-5 " (with space)
}
$name .= strtolower($cat->name).' ';
// outputs: "category " (with space)
}
$active = substr($IDs,0,-1); // remove last character (aka: " ")
$cat_class = substr($name,0,-1); // remove last character (aka: " ")
if(is_single() && !is_page()){
echo '<ul id="cat-menu-single" class="'.$active.'">';
wp_list_categories('hide_empty=0&title_li=&exclude=35');
echo '</ul>';
}
else{
echo '<ul id="cat-menu" class="'.$cat_class.'">';
wp_list_categories('hide_empty=0&title_li=&exclude=35');
echo '</ul>';
}
}
Now switch over to your theme's main JS file, if it doesn't have one, just open header.php and open some script tags (if your theme doesn't use jquery, you'll need to include that in the header). We're going to start some jQuery then open some if statements to work in. Since the wp_list_pages function doesn't highlight on the home page, we're also going to be adding a highlight call to the jQuery so far.
$(document).ready(function(){
/* Highlighting fix */
if(document.getElementById('cat-menu-single')){ // if #cat-menu-single exists
}
if(document.getElementById('cat-menu')){ // if #cat-menu exists
}
$('#menu ul#cat-menu-home li:eq(0)').addClass('current-cat');
});
Now we're going to create a variable and store the classes from the UL we created earlier. Then we'll turn that string into an array using the javascript split() method.
$(document).ready(function(){
/* Highlighting fix */
if(document.getElementById('cat-menu-single')){ // if #cat-menu-single exists
var active = $('#menu #cat-menu-single').attr('class');
var active_array = new Array(); active_array = active.split(" ");
}
if(document.getElementById('cat-menu')){ // if #cat-menu exists
var cats = $('#menu ul').attr('class')
var classes = new Array(); classes = cats.split(" ");
}
$('#menu ul#cat-menu-home li:eq(0)').addClass('current-cat');
});
Next thing we need to do is run a for statement to loop through that array and add the data as classes to the list items. Or in the case of the single pages statement, we're going to be checking to see if there's a list item already there with the same class as the array item, then we'll add the active category class.
$(document).ready(function(){
/* Highlighting fix */
if(document.getElementById('cat-menu-single')){ // if #cat-menu-single exists
var active = $('#menu #cat-menu-single').attr('class');
var active_array = new Array(); active_array = active.split(" ");
for(x in active_array){
var highlight = active_array[x]; // gets value of current key
$('#menu #cat-menu-single li.'+highlight).addClass('current-cat');
}
}
if(document.getElementById('cat-menu')){ // if #cat-menu exists
var cats = $('#menu ul').attr('class')
var classes = new Array(); classes = cats.split(" ");
for(x in classes){
var cat = classes[x]; // gets value of current key
$('#menu ul li:eq('+x+')').addClass(cat);
}
}
$('#menu ul#cat-menu-home li:eq(0)').addClass('current-cat');
});
The Final Code
It took some doing covering 2 code languages, but we're finally able to both sort our categories (using any category sorting plugin
function category_list_menu(){
$terms = get_terms('category');
foreach($terms as $cat){
// print_r($cat);
if($cat->term_id == '35'){ //find category 35
continue; // skip rest of foreach
}
if(in_category($cat->term_id)){
$IDs .= 'cat-item-'.$cat->term_id.' ';
// outputs: "cat-item-5 " (with space)
}
$name .= strtolower($cat->name).' ';
// outputs: "category " (with space)
}
$active = substr($IDs,0,-1); // remove last character (aka: " ")
$cat_class = substr($name,0,-1); // remove last character (aka: " ")
if(is_single() && !is_page()){
echo '<ul id="cat-menu-single" class="'.$active.'">';
wp_list_categories('hide_empty=0&title_li=&exclude=35');
echo '</ul>';
}
else{
echo '<ul id="cat-menu" class="'.$cat_class.'">';
wp_list_categories('hide_empty=0&title_li=&exclude=35');
echo '</ul>';
}
}
$(document).ready(function(){
/* Highlighting fix */
if(document.getElementById('cat-menu-single')){ // if #cat-menu-single exists
var active = $('#menu #cat-menu-single').attr('class');
var active_array = new Array(); active_array = active.split(" ");
for(x in active_array){
var highlight = active_array[x]; // gets value of current key
$('#menu #cat-menu-single li.'+highlight).addClass('current-cat');
}
}
if(document.getElementById('cat-menu')){ // if #cat-menu exists
var cats = $('#menu ul').attr('class')
var classes = new Array(); classes = cats.split(" ");
for(x in classes){
var cat = classes[x]; // gets value of current key
$('#menu ul li:eq('+x+')').addClass(cat);
}
}
$('#menu ul#cat-menu-home li:eq(0)').addClass('current-cat');
});


Share the Love






No Reader Comments Yet