Link to home
Start Free TrialLog in
Avatar of Crazy Horse
Crazy HorseFlag for South Africa

asked on

List all categories for posts (default Wordpress blog)

I thought this would be super easy to do but I can't seem to find an easy way.

When I go to my blog page I want to list all the categories available in a custom layout, so I don't want to use a widget.

I did this:

    <?php wp_list_categories( array(
        'orderby' => 'name'
    ) ); ?> 

Open in new window


But the formatting is awful.

Then I tried this:

    <?php $cats = get_categories(); ?>
    <div class="blog">
        <a href="#" class="button blog-category">show all</a>
        <?php foreach($cats as $cat): ?>
        <a href="<?php echo site_url() . '/category/' . $cat->slug; ?>" class="button blog-category"><?php echo $cat->name; ?></a>
        <?php endforeach; ?>
    </div>

Open in new window


But not sure that href is ideal. And the other problem is that I want the category I am on to add an active class to the nav item.
Avatar of Chris Stanyon
Chris Stanyon
Flag of United Kingdom of Great Britain and Northern Ireland image

Hi,

You're on the right track. To get the url for the category, you can use the get_category_link($catId) function.

If you're on a POST page, then you can use get_the_category() function to get a list of the categories assigned to the current post. If you use it inside the loop, you don't need the post id. If you're using it outside of the loop, then you'll need to pass in the post id. The function returns an array (a post can be assigned to more than one category), so how you decide which is active is up to you (maybe just select the first element in the array).

Something like this (untested):

$current_categories = get_the_category();
$current_category_id = $current_categories[0]->cat_ID;

foreach($cats as $cat):
    $cat_url = get_category_link($cat->cat_ID);
    $active = $cat_ID === $current_category_id ? 'active' : '';
    printf("<a href='%s' class='%s'>%s</a>", $cat_url, $active, $cat->name);
endforeach;

Open in new window

Avatar of Crazy Horse

ASKER

Hi Chris, sorry for late reply.

I am a bit lost here. I am trying to use $active in the class to either show that item as active or not. I see you are still using the foreach loop with my initial $cats = get_categories() but it isn't in your version of the code. So, I am sitting with this now:

    <div class="blog">
        <?php foreach($cats as $cat):
            $cat_url = get_category_link($cat->cat_ID);
            $active = $cat_ID === $current_category_id ? 'active' : '';
        ?>
        <a href="<?php echo site_url() . '/category/' . $cat->slug; ?>" class="button blog-category <?php echo $active; ?>"><?php echo $cat->name; ?></a>
        <?php endforeach; ?>
    </div>

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of Chris Stanyon
Chris Stanyon
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Ah, okay. I have changed implemented in my layout and it seems to work. Is this okay?

    <?php
        $current_categories = get_the_category();
        $current_category_id = $current_categories[0]->cat_ID;
        $cats = get_categories();
    ?>
    <div class="blog">
        <a href="<?php echo get_permalink( get_option( 'page_for_posts' ) ); ?>" class="button blog-category">show all</a>
        <?php foreach($cats as $cat):
            $cat_url = get_category_link($cat->cat_ID);
            $active = $cat->cat_ID === $current_category_id ? 'active' : '';
        ?>
        <a href="<?php echo site_url() . '/category/' . $cat->slug; ?>" class="button blog-category w-button <?php echo $active; ?>"><?php echo $cat->name; ?></a>
        <?php endforeach; ?>
    </div>

Open in new window

Yep. Looks about right, although you're making a call to get_category_link() and then not using it - instead you're building the URL (href) manually. If you ever decide to change your Category base in the permalink settings (for example, changing it to topics), then your code would fail because you've hardcoded the /category/ prefix in. If you use the get_category_link() then you don't have to worry about that:

<?php foreach($cats as $cat):
    $cat_url = get_category_link($cat->cat_ID);
    $active = $cat->cat_ID === $current_category_id ? 'active' : '';
    printf("<a href='%s' class='button blog-category w-button %s'>%s</a>", $cat_url, $active, $cat->name);
endforeach; ?>

Open in new window

Ah, good point and thanks for all your help!
No worries :)