Reputation: 544
This code works fine and list all parent, child and grandchild categories The code shows bootstrap toggle on parents and it works fine.
I need the grandchildren be be shown into another level ul li
and the toggle should be on children that contain grandchildren
<ul>
<?php
$get_parent_cats = array(
'parent' => '0' //get top level categories only
);
$all_categories = get_categories( $get_parent_cats );//get parent categories
foreach( $all_categories as $single_category ){
//for each category, get the ID
$catID = $single_category->cat_ID;
echo '<li><a data-toggle="collapse" href="#' . $single_category->name . '" role="button" aria-expanded="false" aria-controls="' . $single_category->name . '">' . $single_category->name . '<i class="fas fa-angle-down float-right mt-2"></i></a>'; //category name & link
$get_children_cats = array(
'child_of' => $catID //get children of this parent using the catID variable from earlier
);
$child_cats = get_categories( $get_children_cats );//get children of parent category
echo '<ul class="collapse show" id="' . $single_category->name . '">';
foreach( $child_cats as $child_cat ){
//for each child category, get the ID
$childID = $child_cat->cat_ID;
//for each child category, give us the link and name
echo '<li><a href=" ' . get_category_link( $childID ) . ' ">' . $child_cat->name . '<span class="float-right">('.$child_cat->count.')</span></a>';
}
echo '</ul></li>';
} //end of categories logic ?>
</ul>
Result of above code
<ul>
<li>
<a data-toggle="collapse" href="#DISPENSERS" role="button" aria-expanded="false" aria-controls="DISPENSERS">Parent1<i class="fas fa-angle-down float-right mt-2"></i></a>
<ul class="collapse show" id="DISPENSERS">
<li>Child</li>
<li>Child</li>
<li>GrandChild</li>
</ul>
</li>
<li>
<a data-toggle="collapse" href="#VULLING" role="button" aria-expanded="false" aria-controls="VULLING">Parent2<i class="fas fa-angle-down float-right mt-2"></i></a>
<ul class="collapse show" id="VULLING">
<li>Child</li>
<li>GrandChild</li>
<li>Child</li>
</ul>
</li>
Requirements
<ul>
<li>Parent1
<ul>
<li>Child</li>
<li> <a data-toggle="collapse" href="#DISPENSERS" role="button" aria-expanded="false" aria-controls="DISPENSERS">Child<i class="fas fa-angle-down float-right mt-2"></i></a>
<ul class="collapse show" id="DISPENSERS">
<li>
<li>GrandChild</li>
<li>GrandChild</li>
</li>
<ul>
<li>Child</li>
</ul>
</li>
Upvotes: 0
Views: 152
Reputation: 14312
There are 2 main changes you need to get this working:
1. Get only the direct children of the category instead of all children.
You are passing child_of
to get_categories
for the children... this will get all children. To get only the direct children, use get_categories( "parent=".$parentID );
instead.
2. Because this will only give you one level of children, you need to call get_categories
again for each child.
The working code for this is below. There are commented with each step numbered so you can see what I changed.
<ul>
<?php
$all_categories = get_categories( array('parent' => '0') );//get top level categories only
foreach( $all_categories as $single_category ){
echo '<li>' . $single_category->name;
// 1. GET THE DIRECT CHILDREN OF THE PARENT CATEGORY
$child_cats = get_categories( "parent=".$single_category->cat_ID);
if ($child_cats){
echo '<ul>';
foreach( $child_cats as $child_cat ){
//for each child category, get the ID
$childID = $child_cat->cat_ID;
// 2. GET THE DIRECT GRANDCHILDREN OF THE CHILD CATEGORY
$grandchild_cats = get_categories( "parent=".$childID);
// 3. IF THERE ARE GRANDCHILDREN, SHOW THEM IN A COLLAPSABLE LIST
if ($grandchild_cats){
echo '<li><a data-toggle="collapse" href="#' . $child_cat->slug . '" role="button" aria-expanded="true" aria-controls="' . $child_cat->slug . '">' . $child_cat->name . '<i class="fas fa-angle-down float-right mt-2"></i></a>'; //category name & link
echo '<ul class="collapse show" id="' . $child_cat->slug . '">';
foreach( $grandchild_cats as $grandchild_cat ){
$grandchildID = $grandchild_cat->cat_ID;
//for each child category, give us the link and name
echo '<li><a href=" ' . get_category_link( $grandchildID ) . ' ">' . $grandchild_cat->name . '<span class="float-right">('.$grandchild_cat->count.')</span></a></li>';
}
echo '</ul></li>';
}
else{
// 4. IF THERE ARE NO GRANDCHILDREN, JUST SHOW THE CHILD AS A LINK TO THE CATEGORY
echo '<li><a href=" ' . get_category_link( $childID ) . ' ">' . $child_cat->name . '<span class="float-right">('.$grandchild_cat->count.')</span></a></li>';
}
}
echo '</ul></li>';
}// end if child_cats
echo '</li>';
} //end of categories loop ?>
</ul>
3. Getting Great-Grandchildren
If you needed to get more levels of children (e.g. great-grandchildren, great-great-grandchildren etc) You can create a recursive function that will keep calling itself to get the children's children until there are no more children.
I don't know where you would put the toggle in this case, but the recursive function has an argument for the current level, so you could use it to check and change the display as required.
Working Code
The code is commented below with each step numbered so you can see what I changed.
<ul>
<?php
$all_categories = get_categories( array('parent' => '0') );//get top level categories only
foreach( $all_categories as $single_category ){
echo '<li>' . $single_category->name;
// 1. CALL OUR RECURSIVE FUNCTION TO LOOK FOR CHILDREN OF THIS CATEGORY
showChildCategories($single_category->cat_ID, $single_category->name, 1);
echo '</li>';
} //end of categories logic ?>
</ul>
<?php
function showChildCategories($parentID, $ul_id, $current_level){
// 2. GET THE DIRECT CHILDREN OF THE PARENT CATEGORY
$child_cats = get_categories( "parent=".$parentID);
// 3. IF THERE ARE NO CHILDREN, THEN DON'T CONTINUE
if (!$child_cats) return;
// 4. DISPLAY THE CHILDREN (This is the code you were already using to show the children)
echo '<ul id="' . $ul_id . '">';
foreach( $child_cats as $child_cat ){
//for each child category, get the ID
$childID = $child_cat->cat_ID;
//for each child category, give us the link and name
echo '<li><a href=" ' . get_category_link( $childID ) . ' ">' . $child_cat->name . '<span>('.$child_cat->count.')</span></a>';
// 5. CALL OUR RECURSIVE FUNCTION TO LOOK FOR CHILDREN OF THIS CATEGORY
showChildCategories($childID, $child_cat->name, $current_level+1);
}
echo '</ul></li>';
}
?>
Upvotes: 1