// create category and tags page - add a page called Categories for output
add_filter( 'template_include', 'to_category_page_template' );
function to_category_page_template( $template ) {
if ( ! is_page( array( 'categories', 'category' ) ) ) return $template;
add_filter( 'the_content', 'to_render_category_list' );
return $template;
}
function to_render_category_list( $content ) {
$categories = get_categories( array(
'orderby' => 'name',
'order' => 'ASC',
'hide_empty' => false,
'number' => 0, // get all, no limit
) );
if ( empty( $categories ) ) return $content;
// Index by term_id for easy lookup
$indexed = array();
foreach ( $categories as $cat ) {
$indexed[ $cat->term_id ] = $cat;
}
// Build tree
$tree = array();
foreach ( $categories as $cat ) {
$tree[ $cat->parent ][] = $cat;
}
$output = '<ul>' . to_render_category_branch( $tree, 0 ) . '</ul>';
// Tags
$tags = get_terms( array(
'taxonomy' => 'post_tag',
'orderby' => 'name',
'order' => 'ASC',
'hide_empty' => false,
'number' => 0,
) );
if ( ! empty( $tags ) && ! is_wp_error( $tags ) ) {
$output .= '<h2>Tags</h2><ul>';
foreach ( $tags as $tag ) {
$output .= '<li><a href="' . esc_url( get_tag_link( $tag->term_id ) ) . '">' . esc_html( $tag->name ) . '</a>';
if ( ! empty( $tag->description ) ) {
$output .= ' — ' . esc_html( $tag->description );
}
$output .= '</li>';
}
$output .= '</ul>';
}
return $content . $output;
}
function to_render_category_branch( $tree, $parent_id ) {
if ( empty( $tree[ $parent_id ] ) ) return '';
$output = '';
foreach ( $tree[ $parent_id ] as $category ) {
$output .= '<li>';
$output .= '<a href="' . esc_url( get_category_link( $category->term_id ) ) . '">' . esc_html( $category->name ) . '</a>';
if ( ! empty( $category->description ) ) {
$output .= ' — ' . esc_html( $category->description );
}
if ( ! empty( $tree[ $category->term_id ] ) ) {
$output .= '<ul>' . to_render_category_branch( $tree, $category->term_id ) . '</ul>';
}
$output .= '</li>';
}
return $output;
}
create page ‘categories’ for it to display on.