First you need to get all the categories that don’t have parents (top-level categories). We’re going to use get_terms
for this. Get terms will either return an empty array, a WP_Error
object, or an array of objects representing terms. So we need to make sure our call works before continuing as well.
<?php
// very hackish get_terms call with the 0 as a string to return top level terms
$cats = get_terms( 'category', array( 'parent' => '0' ) );
if( ! $cats || is_wp_error( $cats ) ) return;
With that in place we can start by outputing a container div, then starting a foreach
loop to loop through all the categories. We’ll output the term and link inside a paragraph as per your request above.
<?php
$out="<div id="ref-list">" . "\n";
foreach( $cats as $cat )
{
$out .= sprintf(
'<p class="lit-author"><a href="https://wordpress.stackexchange.com/questions/25157/%s">%s</a></p>',
esc_url( get_term_link( $cat ) ),
sanitize_term_field( 'name', $cat->name, $cat->term_id, 'category', 'display' )
);
$out .= "\n"; // add some newlines to prettify our source
Still inside our foreach( $cats as $cat )
loop, we can loop for term children. If we find them, we’ll loop through each child, getting its link, name, and description.
<?php
$children = get_term_children( $cat->term_id, 'category' );
if( $children && ! is_wp_error( $children ) )
{
foreach( $children as $child )
{
$child = get_term( $child, 'category' );
if( is_wp_error( $child ) ) continue;
$out .= sprintf(
'<p class="lit-work"><a href="https://wordpress.stackexchange.com/questions/25157/%s"><em>%s</em></a>. %s</p>',
esc_url( get_term_link( $child ) ),
sanitize_term_field( 'name', $child->name, $child->term_id, 'category', 'display' ),
esc_attr( $child->description ) // sanitize_term_field adds autop, no good for this situation
);
$out .= "\n"; // prettifying newline
}
}
} // end of the foreach( $cats as $cat ) loop
$out .= "</div>\n";
return $out;
You can encapsulate this entire mess in a function (note: counts are added here, forgot them above).
<?php
function wpse25157_ref_list()
{
// very hackish get_terms call with the 0 as a string to return top level terms
$cats = get_terms( 'category', array( 'parent' => '0' ) );
if( ! $cats || is_wp_error( $cats ) ) return;
$out="<div id="ref-list">" . "\n";
foreach( $cats as $cat )
{
$out .= sprintf(
'<p class="lit-author"><a href="https://wordpress.stackexchange.com/questions/25157/%s">%s</a> (%s)</p>',
esc_url( get_term_link( $cat ) ),
sanitize_term_field( 'name', $cat->name, $cat->term_id, 'category', 'display' ),
sanitize_term_field( 'count', $cat->count, $cat->term_id, 'category', 'display' )
);
$out .= "\n"; // add some newlines to prettify our source
$children = get_term_children( $cat->term_id, 'category' );
if( $children && ! is_wp_error( $children ) )
{
foreach( $children as $child )
{
$child = get_term( $child, 'category' );
if( is_wp_error( $child ) ) continue;
$out .= sprintf(
'<p class="lit-work"><a href="https://wordpress.stackexchange.com/questions/25157/%s"><em>%s</em></a>. %s (%s)</p>',
esc_url( get_term_link( $child ) ),
sanitize_term_field( 'name', $child->name, $child->term_id, 'category', 'display' ),
esc_attr( $child->description ),
sanitize_term_field( 'count', $child->count, $child->term_id, 'category', 'display' )
);
$out .= "\n"; // prettifying newline
}
}
} // end of the foreach( $cats as $cat ) loop
$out .= "</div>\n";
return $out;
}
And add a shortcode to display it all on any page/post you like.
<?php
add_action( 'init', 'wpse25157_init' );
function wpse25157_init()
{
add_shortcode( 'ref-list', 'wpse25157_ref_list' );
}
As a plugin: https://gist.github.com/1196457