I am currently using the following code to fetch WooCommerce product categories:
<?php
$orderby = 'name';
$order = 'asc';
$hide_empty = false ;
$cat_args = array(
'orderby' => $orderby,
'order' => $order,
'hide_empty' => $hide_empty,
);
$product_categories = get_terms( 'product_cat', $cat_args );
if( !empty($product_categories) ){
echo '<ul>';
foreach ($product_categories as $key => $category) {
echo '<li>';
echo '<a href="'.get_term_link($category).'" >';
echo $category->name;
echo '</a>';
echo '<li>';
}
echo '</ul>';
}
?>
This currently displays all categories, however I wish this to only show the child categories.
For example, if you are on the Category 1 page, it should show all children within that category only.
I've looked at many examples on here but have been unable to find something that works for what I need.
You can add this to woocommerce/archive-product.php file
$queried_object = get_queried_object();
$parent = $queried_object->term_id;
$categories = get_term_children( $parent, 'product_cat' );
if ( $categories && ! is_wp_error( $category ) ) :
echo '<ul>';
foreach($categories as $category) :
$term = get_term( $category, 'product_cat' );
echo '<li>';
echo '<a href="'.get_term_link($term).'" >';
echo $term->name;
echo '</a>';
echo '</li>';
endforeach;
echo '</ul>';
endif;
This will only work on your archives. And categories with children.
It will also output grand child categories.
Hope this helps.
Here is a way to get only product subcategories linked list ordered by name ASC:
// The product category taxonomy
$taxonomy = 'product_cat';
// Get the parent categories IDs
$parent_cat_ids = get_terms( $taxonomy, array(
'parent' => 0,
'hide_empty' => false,
'fields' => 'ids'
) );
// Get only "child" WP_Term Product categories
$subcategories = get_terms( $taxonomy, array(
'exclude' => $parent_cat_ids,
'orderby' => 'name',
'order' => 'asc',
'hide_empty' => false,
) );
if( ! empty( $subcategories ) ){
echo '<ul>';
foreach ($subcategories as $subcategory) {
echo '<li>
<a href="'. get_term_link($subcategory) .'" >' . $subcategory->name.'</a>
</li>';
}
echo '</ul>';
}
The code is tested and works
Add Below Code in theme's functions.php file.
add_filter('get_child_category', 'get_child_cat', 10, 1);
function get_child_cat($term_id = 0){
global $wpdb;
$result = array('status' => 'fail');
if($term_id != 0){
$result = $wpdb->get_results( "select ".$wpdb->prefix."terms.term_id, ".$wpdb->prefix."terms.name, ".$wpdb->prefix."terms.slug, ".$wpdb->prefix."terms.term_group, ".$wpdb->prefix."term_taxonomy.term_taxonomy_id, ".$wpdb->prefix."term_taxonomy.taxonomy, ".$wpdb->prefix."term_taxonomy.description, ".$wpdb->prefix."term_taxonomy.parent, ".$wpdb->prefix."term_taxonomy.count from ".$wpdb->prefix."terms left join ".$wpdb->prefix."term_taxonomy on ".$wpdb->prefix."term_taxonomy.term_id = ".$wpdb->prefix."terms.term_id where ".$wpdb->prefix."term_taxonomy.parent = $term_id" );
}
return $result;
}
Use below code for get array output for child category.
$cat = apply_filters( 'get_child_category', $term_id ); // where $term_id is your parent category id.
NOTE: This code is only used for single level term.
change code as per your requirement.
Related
I have to display product categories grid, where a single column will look like this:
child category
main category
number of products
I am trying to do this with the following code. Instead of "main category" I get the "child" name, which is the same in all cases.
<?php
$taxonomy = 'product_cat';
$parent_cat_ids = get_terms( $taxonomy, array(
'parent' => 0,
'hide_empty' => false,
'fields' => 'ids'
) );
$subcategories = get_terms( $taxonomy, array(
'exclude' => $parent_cat_ids,
'orderby' => 'name',
'order' => 'asc',
'hide_empty' => false,
) );
$category_id = $cat->term_id;
if( ! empty( $subcategories ) ){
echo '<ul>';
foreach ($subcategories as $subcategory) {
echo '<li>
<h4><a href="'. get_term_link($cat->slug, 'product_cat') .'">'. $cat->name .'</h4>
<a href="'. get_term_link($subcategory) .'" >' . $subcategory->name.'</a>
</li>';
echo ' ('.$cat->count.')';
}
echo '</ul>';
}
?>
i want to display Woocommerce category and product in dropdown like this:
when click on "category dropdown" then show products in the category selected.
may code for category is :
$orderby = 'name';
$order = 'asc';
$hide_empty = false ;
$cat_args = array(
'orderby' => $orderby,
'order' => $order,
'hide_empty' => $hide_empty,
);
$product_categories = get_terms( 'product_cat', $cat_args );
if( !empty($product_categories) ){
echo '
<select>';
foreach ($product_categories as $key => $category) {
echo '
<option>';
echo '<a href="'.get_term_link($category).'" >';
echo $category->name;
echo '</a>';
echo '</option>';
}
echo '</select>
';
}
how can i add product and other field? or is there any plugin for this?
I have a custom post type with a taxonomy "section" and I have a template page with a query loop to display a list of categories with thumbnails. I only want to show the child categories of the current parent taxonomy and want to be ably to get the ID of the parent category when on a child page.
I have currently set the parent as id 40 in my code but need this to be dynamic. How would dynamically change the 40 to the current parent id?
This is the code I have in my taxonomy template page.
<?php
$terms = get_terms( [
'taxonomy' => 'section',
'parent' => 40,
'hide_empty' => true,
'relationship' => [
'id' => 'categories_to_posts',
'to' => get_the_ID(), // You can pass object ID or full object
],
] );
if ( $terms && ! is_wp_error( $terms ) ) {
foreach ( $terms as $term ) {
$term_link = get_term_link( $term->term_id );
$term_name = $term->name;
$url = get_term_meta( $term->term_id, 'kte_sec_thumbnail_image', true );
echo '<img src="' . esc_url( $url ) . '">';
$term = get_term_by( 'id', $child, $taxonomy_name );
echo '' . $term_name . '';
}
}
As i can understand that you want to show current parent taxonomy's child terms on parent taxonomy page. So use this code to achieve your functionality..
<?php
$term123 = get_queried_object();
$slug=$term123->slug;
$parent_id =$term123->parent;
$child_id=$term123->term_id;
$taxonomy_name ='section';
$termchildren = get_term_children( $child_id, $taxonomy_name );
echo "<ul>";
foreach ( $termchildren as $child ) {
$term = get_term_by( 'id', $child, $taxonomy_name );
?>
<?php if ($term->parent == $child_id) { ?>
<li><?php echo $term->name; ?></li>
<?php }
?>
<?php }
echo "</ul>";
?>
I have this code that is getting all categories and subcategories from a woocommerce based website in a hierarchical order, and it works but each and every time when I want to add a new level of depth
category
->sub-cat
->sub-sub-cat
->sub-sub-sub-cat
->etc
I have to add one more foreach loop inside the last loop (I'm not even sure if you can understand me to cause honestly I don't even know how to explain this - sorry, please be patient, it is my second month in PHPs 'fields')
So, I'm trying to get rid of all those foreach loops (to make it more dynamic) and I heard that there is a way to do that by using something called recursion, the kind of stuff that I can use to make this happen. I don't really understand how that works and I've read like the whole day about it so if there is somebody who can help me understand how to get this done I'll be happy?
Here is my code, part of it is taken from StackOverflow.
<ul>
<?php
$taxonomy = 'product_cat';
$orderby = 'name';
$hierarchical = 1;
$args = array(
'taxonomy' => $taxonomy,
'orderby' => $orderby,
'hierarchical' => $hierarchical
);
$cat = get_categories( $args );
foreach ($cat as $c) {
if($c->category_parent == 0) {
$catID = $c->term_id;
echo '<li>'. $c->name .'';
$args = array(
'taxonomy' => $taxonomy,
'parent' => $catID,
'orderby' => $orderby,
'hierarchical' => $hierarchical
);
$cat = get_categories( $args );
if($cat) {
echo '<ul>';
foreach($cat as $c) {
$catID = $c->term_id;
echo '<li>'. $c->name , apply_filters( 'woocommerce_subcategory_count_html', ' (' . $c->count . ')', $category ) .'';
$args = array(
'taxonomy' => $taxonomy,
'parent' => $catID,
'orderby' => $orderby,
'hierarchical' => $hierarchical
);
$cat = get_categories( $args );
if($cat){
echo '<ul>';
foreach ($cat as $c) {
$catID = $c->term_id;
echo '<li>'. $c->name , apply_filters( 'woocommerce_subcategory_count_html', ' (' . $c->count . ')', $category ) .'';
$args = array(
'taxonomy' => $taxonomy,
'parent' => $catID,
'orderby' => $orderby,
'hierarchical' => $hierarchical
);
$cat = get_categories( $args );
if($cat){
echo '<ul>';
foreach ($cat as $c) {
$catID = $c->term_id;
echo '<li>'. $c->name , apply_filters( 'woocommerce_subcategory_count_html', ' (' . $c->count . ')', $category ) .'</li>';
}
echo '</ul>';
}
echo '</li>';
}
echo '</ul>';
}
echo '</li>';
}
echo '</ul>';
}
echo '</li>';
}
}
?>
It works perfectly, though I'm aware that it is not too smart, so please don't be too harsh on me.
Here is an example of recursion:
You create a function that looks at the item of the array if it's an array you call the function again and pass the item to it (the subarray).
If it's not an array you echo it.
$arr = [1,2,3,[4,5,[6]]];
print_items($arr);
Function print_items($arr){
Foreach($arr as $item){
If(is_array($item)){
print_items($item);
}Else{
Echo $item;
}
}
}
https://3v4l.org/vbjaO
A WordPress-specific printing function might look like this:
<?php
function display_child_categories_of($category_id) {
$subcategories = get_categories(array('child_of' => category_id));
foreach ($subcategories as $subcategory) {
echo '<li>';
echo $subcategory->name;
echo '<ul class="children">';
display_child_categories_of($subcategory);
echo '</ul>';
echo '</li>';
}
}
?>
<ul>
<?php
display_child_categories_of(0); // gets all top-level categories
?>
</ul>
This is a barebones version; you'll want to add in the additional parameters you're using to the get_categories() arguments and then tweak the HTML as needed.
However, as #jaswrks mentioned in the comments, you should use the built-in walk_category_tree() WordPress function instead if it works for your situation.
I am trying to display list of all created categories, regardless they have a post or not. I found this function which get the categories list in category-template.php. I am not sure what edits should I do to this function to get my required results.
function get_the_category( $id = false ) {
$categories = get_the_terms( $id, 'category' );
if ( ! $categories || is_wp_error( $categories ) )
$categories = array();
$categories = array_values( $categories );
foreach ( array_keys( $categories ) as $key ) {
_make_cat_compat( $categories[$key] );
}
return apply_filters( 'get_the_categories', $categories );
}
Roaming here, I have seen a manual way here by Scott B. But unfortunately I can't fully understand it.
This works for me:
<ul>
<?php $args = array(
'orderby' => 'name',
'order' => 'ASC'
);
$categories = get_categories($args);
foreach ( $categories as $category ) {?>
<li><?php echo '<a href="' . get_category_link( $category->term_id ) . '" >' . $category->name.'</a>'; ?></li>
<?php } ?>
</ul>