Obtener categorías en orden jerárquico como wp_list_categories - con nombre, slug y enlace para editar categoría
Necesito encontrar una manera de listar todas las categorías - vacías o no - en una lista jerárquica - como wp_list_categories - mostrando también el slug, nombre de categoría y un enlace para editar en el admin.
Esto es lo que tengo hasta ahora:
$args = array(
'orderby' => 'name',
'order' => 'ASC',
'hide_empty' => '0',
);
$categories = get_categories($args);
foreach( $categories as $category ) {
$cat_ID = $category->term_id;
$cat_name = $category->name;
#$cat_desc = $category->description; if ( !$cat_desc { $cat_desc = '¡Nada!' } );
$cat_count = $category->count;
echo '<p><strong>'.$cat_name.'</strong>';
echo ' / <a href="' . get_category_link( $cat_ID ) . '" title="' . sprintf( __( "Ver todas las entradas en %s" ), $cat_name ) . '" ' . '>Ver ( '. $cat_count . ' entradas )</a> ';
#echo ' / Desc: '. $cat_desc . '';
echo ' / <a href="'. get_admin_url().'edit-tags.php?action=edit&taxonomy=category&tag_ID='.$cat_ID.'&post_type=post" title="Editar Categoría">Editar</a>';
echo '</p>';
}
Todo está bien, pero no está bien ordenado - solo es una lista alfabética.

salida como lista desordenada:
<?php
hierarchical_category_tree( 0 ); // llamada a la función; 0 para todas las categorías; o ID de categoría
function hierarchical_category_tree( $cat ) {
// wpse-41548 // alchymyth // una lista jerárquica de todas las categorías //
$next = get_categories('hide_empty=false&orderby=name&order=ASC&parent=' . $cat);
if( $next ) :
foreach( $next as $cat ) :
echo '<ul><li><strong>' . $cat->name . '</strong>';
echo ' / <a href="' . get_category_link( $cat->term_id ) . '" title="' . sprintf( __( "Ver todas las entradas en %s" ), $cat->name ) . '" ' . '>Ver ( '. $cat->count . ' entradas )</a> ';
echo ' / <a href="'. get_admin_url().'edit-tags.php?action=edit&taxonomy=category&tag_ID='.$cat->term_id.'&post_type=post" title="Editar Categoría">Editar</a>';
hierarchical_category_tree( $cat->term_id );
endforeach;
endif;
echo '</li></ul>'; echo "\n";
}
?>

¡genial! - hide_empty parece requerir un valor numérico para funcionar, el resto está perfecto - ¡gracias!

quizás no esté relacionado con mi pregunta original, pero ¿cómo podría determinar el "nivel" de la jerarquía de categorías en el que se encuentra cada categoría? - por ejemplo en una jerarquía de 3 niveles, necesitaría obtener 1, 2 o 3?

http://pastebin.com/GbZFnytw - salida de profundidad añadida como clase css de la etiqueta ul

increíble - ¿hay alguna manera de anidar los ul / li - para que todos se envuelvan? Me gustaría intentar colocarlos en una navegación tipo acordeón de apertura/cierre?

por anidación me refería a <ul><li><ul><li></li></ul></li></ul> - supongo que lo habías deducido...

nuevo código http://pastebin.com/TTvYPKPH - corregido con código añadido para una salida html estructurada - ignora el pastebin antiguo http://pastebin.com/GbZFnytw

gracias de nuevo, ¿podría enviarte por privado un enlace a una página? Tengo otra pregunta, pero no quiero hacer la URL pública.

no hay problema, solo usa el correo electrónico vinculado a mi nombre de usuario.

Una versión ligeramente actualizada de la respuesta de Michael para usar la función más genérica get_terms (así puedes obtener taxonomías personalizadas, en este caso quería la taxonomía de categoría de producto de WooCommerce product_cat
).
echo hierarchical_term_tree();
function hierarchical_term_tree($category = 0)
{
$r = '';
$args = array(
'parent' => $category,
);
$next = get_terms('product_cat', $args);
if ($next) {
$r .= '<ul>';
foreach ($next as $cat) {
$r .= '<li><a href="' . get_term_link($cat->slug, $cat->taxonomy) . '" title="' . sprintf(__("Ver todos los productos en %s"), $cat->name) . '" ' . '>' . $cat->name . ' (' . $cat->count . ')' . '</a>';
$r .= $cat->term_id !== 0 ? hierarchical_term_tree($cat->term_id) : null;
}
$r .= '</li>';
$r .= '</ul>';
}
return $r;
}
Simplificado un poco para quitar el enlace de edición, etc. Puedes añadirlos según sea necesario.

Error: Error fatal capturable de PHP: El objeto de la clase WP_Error no pudo convertirse a cadena. En esta línea: foreach ($next as $cat).

Esto se ve bien. ¿Cómo podría modificarlo para que muestre el término inicial en la parte superior de la lista? Actualmente, muestra todos los términos hijos, ¿verdad? Estoy usando un ID de término distinto de 0, es decir, un ID de término válido, no solo todos.

Puedes utilizar el siguiente código:
$args = array(
// Ocultar categorías vacías: 0 = mostrar todas
'hide_empty' => 0,
// Mostrar el resultado directamente: 1 = sí
'echo' => 1,
// Taxonomía a mostrar (en este caso categorías)
'taxonomy' => 'category',
// Mostrar jerarquía de categorías: 1 = sí
'hierarchical' => 1,
// Mostrar conteo de posts: 1 = sí
'show_count' => 1,
);
// Función para añadir clase CSS al listado de categorías
function add_class_wp_list_categories($wp_list_categories) {
$pattern = '/<li class="/is';
$replacement = '<li class="first ';
return preg_replace($pattern, $replacement, $wp_list_categories);
}
// Aplicar filtro a la función de listado de categorías
add_filter('wp_list_categories','add_class_wp_list_categories');
// Mostrar el listado de categorías con los argumentos definidos
echo wp_list_categories( $args );

Creo que necesitas incluir 'hierarchical' => 1,
en tu lista de argumentos. Además, tienes una coma de más al final de la lista de argumentos. Después del último argumento no necesitas una coma :)
Aquí tienes un ejemplo completo:
$args = array(
'orderby' => 'name',
'order' => 'ASC',
'hierarchical' => 1,
'hide_empty' => '0'
);

Lee más en http://codex.wordpress.org/Function_Reference/get_categories :)

Gracias, pero esto no los ordena jerárquicamente - el codex establece: -- Cuando es verdadero, los resultados incluirán subcategorías que están vacías, siempre que esas subcategorías tengan subcategorías que no estén vacías. El valor predeterminado es verdadero. Valores válidos:
