1

I need to style the get_the_category_list() a tag but can't seem to find a way.

This is my code:

echo '<ul class="list-inline meta-list">';
    // Get the categories
    $terms = get_the_terms( get_the_ID(), 'category');

    if( !empty($terms) ) {

        $term = array_pop($terms);
        $category_color = get_field('category_color', $term );
    }

    $category_list = get_the_category_list( ' ' );
    if ( $category_list ) {
        echo '<li class="meta-categories">' . __( 'In ', 'my_theme' ) . $category_list . ' </li>';
    }

echo '</ul>';

Now I need to add style="color:$category_color;" to get_the_category_list() so every category has a different colour in the single.php template.

2
  • You might want to clarify if this is needed for distribution. Else you might get answers that tell you how to style it with CSS, not add the necessary mark up. – kaiser Mar 2 '16 at 23:36
  • Yes, it is needed for distribution. All I am trying to find out is a way of getting the category list "a" tag to accept the variable $category-color as its font colour(something like this style="color:' . $category_color . ';"). – Madeirense Mar 3 '16 at 8:54
4

get_the_category_list() does not really have any filters to achieve what you want. You will currently need PHP like preg_replace() to alter the anchor tags. The big issue would be to get the current link's term object, which in my opinion would turn it into a quite messy procedure.

You could however write your own function to achieve the same

function wpse_219554_term_list()
{
    $post = get_post();

    $separator = ' ';
    $output    = [];

    $post_categories = get_the_category( $post->ID );
    if ( $post_categories ) {
        foreach( $post_categories as $post_category ) {
            $category_color = get_field( 'category_color', $post_category );
            $output[] = '<li class="meta-category">
                             <a style="color:' . $category_color . ';" href="' . esc_url( get_category_link( $post_category ) ) . '" alt="' . esc_attr( sprintf( __( 'View all posts in %s', 'mytheme' ), $post_category->name ) ) . '"> 
                                 ' . esc_html( $post_category->name ) . '
                             </a>
                        </li>';
        }

        if ( $output )
            echo implode( $separator, $output );
    }
}

EDIT 08 March 2016

The source code of get_the_category_link() is quite messy and quite repetitive, so I have submitted a trac ticket for a possible clean-up and micro optimization of the code.

I have also suggested a new filter, the_category_list_links, which can be used to individually filter category links according to category. If this gets accepted into core, we can use the filter to filter the links as per OP needs, something like this will work then

add_filter( 'the_category_list_links', function ( $the_link_list, $category, $cat_parents )
{
    $category_color = get_field( 'category_color', $category );
    if ( !$category_color )
        return $the_link_list;

    $the_link_list = str_replace( '<a', '<a style="color:' . $category_color . '"', $the_link_list );

    return $the_link_list;
}, 10, 3 );

You can read and contribute to the current trac ticket #36171, and please, feel free to to propose changes so we can get this into the next major release

8
  • The code in the core get_the_category_list() has an interesting code duplication - two almost identical foreach loops. I drafted a way to address it here (untested), but I still think the core code is easier to follow ;-) When one starts with a small rewrite, like this, many other possible rewrites pop-up and in the end one would just like to rewrite the whole project, to e.g. increase re-usability, but that would most likely have more problems than the current version ;-) – birgire Mar 7 '16 at 11:02
  • @birgire Stranglely, I also started on a rewrite. The code is quite messy and not easy to follow and a clean-up in core would do wonders. What I had in mind was to create an array instead of a string, but it is where I left it (not quite sure why the array). My end goal was/is to incorporate a filter into $thelist to make every link filterable on category level. We would pass the link and current category object to the filter so that we can use the filter to change the link according to what the OP has suggested – Pieter Goosen Mar 7 '16 at 11:10
  • @birgire I think the array thought pattern came from my code in the answer. I actually answered a similar question from the OP, and I came to this later. What I was trying was to rewrite the functin to something similar, incorporating the filter I mentioned ;-) – Pieter Goosen Mar 7 '16 at 11:13
  • 1
    yes the array collection is more flexible and I usually like that approach better. My first draft goal/restriction was to have only a single foreach loop, hence the string appending ;-) (so I didn't even address the OP problem there ;-) For the core submission, I imagine someone might address performance for string setup vs array setup, but I think such difference here would just be a micro optimization. I don't have much spare time this week, so I'm looking forward to your rewrite and easier way to handle each link Good luck ;-) – birgire Mar 7 '16 at 11:31
  • 1
    @birgire I'm off to bed now, have finished rewritten the get_the_category_list() and added a new filter to filter each link separately. Will submit everything tomorrow to trac, will sent you the link so that you can also contribute to the suggested changes. I will also update my answer with the proposed filter. We might need to look at get_category_parents() as well – Pieter Goosen Mar 7 '16 at 19:21

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.