[wp-hackers] wp_list_categories()

Mike Schinkel mikeschinkel at gmail.com
Sun Dec 28 01:26:10 GMT 2008


Hi all:

I've been working on a category plugin for a client.  I would have thought
something like it would exist but couldn't find one so I'm building it
myself.

However, I've run into several annoying issues with using *
wp_list_categories()* which I'd far prefer to use than to code all the SQL
myself (not because I don't have the skills but because I'd rather use a
core WP function for future compatibility.) Let me provide a output snippet
from the site I'm working on (I removed titles from <a> tags and removed the
domain from the <a> @href attribute to make it easier to understand the
HTML, and I reformatted):

<li class="cat-item cat-item-186">
    <a href="/category/human-rights/">Human Rights</a> (428)
    <ul class='children'>
        <li class="cat-item cat-item-52"><a
href="/category/human-rights/civil-rights/">Civil Rights</a> (255)</li>
        <li class="cat-item cat-item-53"><a
href="/category/human-rights/freedom-of-speech/">Freedom of Speech</a>
(174)</li>
        <li class="cat-item cat-item-55"><a
href="/category/human-rights/democracy/">Democracy</a> (110)</li>
        <li class="cat-item cat-item-72"><a
href="/category/human-rights/censorship/">Censorship</a> (110)</li>
    </ul>
</li>
<li class="cat-item cat-item-521">
    <a href="/category/fun-recreation/">Fun and Recreation</a> (104)
    <ul class='children'>
        <li class="cat-item cat-item-56"><a
href="/category/fun-recreation/funny-news/">Funny News</a> (41)</li>
        <li class="cat-item cat-item-117"><a
href="/category/fun-recreation/humor/">Humor</a> (35)</li>
        <li class="cat-item cat-item-138"><a
href="/category/fun-recreation/fun-stuff/">Fun Stuff</a> (34)</li>
        <li class="cat-item cat-item-63"><a
href="/category/fun-recreation/satire/">Satire</a> (25)</li>
    </ul>
</li>


The first issue is with how it organizes it's HTML.  Although I would
logically prefer having the <li> elements enclose <ul ="children"> elements
it makes it hard to clumsy to target with CSS and jQuery (i.e. using
"li:hover" ends up highlighting everything, including children) and it makes
it hard to appropriate place background images using "background:url(...)"
Neither "background-position:left top;" nor "background-position:left
center;" work well for icons that otherwise work well on a single-line <li>.


So here's what I'd like to see instead:

<li class="cat-item cat-item-186">
    <a href="/category/human-rights/">Human Rights</a> (428)
</li>
<ul class='children'>
        <li class="cat-item cat-item-52"><a
href="/category/human-rights/civil-rights/">Civil Rights</a> (255)</li>
        <li class="cat-item cat-item-53"><a
href="/category/human-rights/freedom-of-speech/">Freedom of Speech</a>
(174)</li>
        <li class="cat-item cat-item-55"><a
href="/category/human-rights/democracy/">Democracy</a> (110)</li>
        <li class="cat-item cat-item-72"><a
href="/category/human-rights/censorship/">Censorship</a> (110)</li>
</ul>
<li class="cat-item cat-item-521">
    <a href="/category/fun-recreation/">Fun and Recreation</a> (104)
</li>
<ul class='children'>
        <li class="cat-item cat-item-56"><a
href="/category/fun-recreation/funny-news/">Funny News</a> (41)</li>
        <li class="cat-item cat-item-117"><a
href="/category/fun-recreation/humor/">Humor</a> (35)</li>
        <li class="cat-item cat-item-138"><a
href="/category/fun-recreation/fun-stuff/">Fun Stuff</a> (34)</li>
        <li class="cat-item cat-item-63"><a
href="/category/fun-recreation/satire/">Satire</a> (25)</li>
</ul>

Of course that could cause all kinds of backward compatibility issues should
it should be triggered by a new parameter, maybe "*li_contains_ul*?"

In addition, this would almost require that the <ul> be given a class that
identifies the parent category ID, maybe "*cat-child-{nnn}*", like so:

<li class="cat-item cat-item-186">
    <a href="/category/human-rights/">Human Rights</a> (428)
</li>
<ul class='children *cat-child-186*'>
        <li class="cat-item cat-item-52"><a
href="/category/human-rights/civil-rights/">Civil Rights</a> (255)</li>
        <li class="cat-item cat-item-53"><a
href="/category/human-rights/freedom-of-speech/">Freedom of Speech</a>
(174)</li>
        <li class="cat-item cat-item-55"><a
href="/category/human-rights/democracy/">Democracy</a> (110)</li>
        <li class="cat-item cat-item-72"><a
href="/category/human-rights/censorship/">Censorship</a> (110)</li>
</ul>
<li class="cat-item cat-item-521">
    <a href="/category/fun-recreation/">Fun and Recreation</a> (104)
</li>
<ul class='children *cat-child-521*'>
        <li class="cat-item cat-item-56"><a
href="/category/fun-recreation/funny-news/">Funny News</a> (41)</li>
        <li class="cat-item cat-item-117"><a
href="/category/fun-recreation/humor/">Humor</a> (35)</li>
        <li class="cat-item cat-item-138"><a
href="/category/fun-recreation/fun-stuff/">Fun Stuff</a> (34)</li>
        <li class="cat-item cat-item-63"><a
href="/category/fun-recreation/satire/">Satire</a> (25)</li>
</ul>

I don't see any backward compatibility issues with adding that class so I
wouldn't see a need to enable with a parameter, even with old style markup
so I would just add in.

On another note, is there any reason to have absolute links and include the
full domain in the <a> href?  For a long list of categories it adds
unneccesary output.  What about an "*omit_domain*" parameter?

The last two items are 1.) it would really be nice to be able to get the
list of categories as an array as opposed to as HTML (parameter "*as_array*?"),
and 2.) why is there no equivalent wp_list_tags()?

I'd be happy to do the work to add these options assuming you guys agree
with the concept(s) and would recommend it for inclusion in 2.8.   Let me
know...

-Mike Schinkel
http://mikeschinkel.com/


More information about the wp-hackers mailing list