wordpress sub taxonomies are not showing properly - php

I want to display only 1st level of sub taxonomies, below is my code,it's just not working, can anyone please tell whats wrong with my code?? Many thanks.
<?php
$term_id = 31;
$taxonomy_name = 'kosher_category';
$args = array('child_of' => $term_id, 'parent' => $term_id);
$termchildren = get_terms($taxonomy_name, $args );
echo '<ul>';
foreach ( $termchildren as $child ) {
$term = get_term_by( 'id', $child, $taxonomy_name );
echo '<li>' . $term->name . '</li>';
}
echo '</ul>';
?>

Add hide_empty.
<?php
$term_id = 31;
$taxonomy_name = 'kosher_category';
$args = array(
'child_of' => $term_id,
'parent' => $term_id,
'hide_empty' => false // ADDED
);
$termchildren = get_terms($taxonomy_name, $args );
echo '<ul>';
foreach($termchildren AS $child) {
$term = get_term_by('id', $child, $taxonomy_name);
echo '<li>' . $term->name . '</li>';
}
echo '</ul>';
?>

Related

get_terms with Redis Object Cache question

By default, hide_empty => is set to be true. If Redis object cache is disabled, the below code works just fine. But when Redis is enabled, the empty term will not be hidden. It just shows all the terms. I have tried to flush the cache. The issue remains.
Any idea what may cause the issue? thanks
$parentid = 182;
$args = array(
'parent' => $parentid
);
$terms = get_terms( 'product_cat', $args );
if ( $terms ) {
echo '<ul>';
foreach ( $terms as $term ) {
echo '<li>';
echo '<a href="' . esc_url( get_term_link( $term ) ) . '" class="' . $term->slug . '">';
echo $term->name;
echo '</a>';
echo '</li>';
}
echo '</ul>';
}
I managed to solve it with term count
$parentid = 182;
$args = array(
'parent' => $parentid
);
$terms = get_terms( 'product_cat', $args );
$count = count($terms);
if ( $terms ) {
echo '<ul>';
foreach ( $terms as $term ) {
if ($term->count > 0){
echo '<li>';
echo '<a href="' . esc_url( get_term_link( $term ) ) . '" class="' . $term->slug . '">';
echo $term->name;
echo '</a>';
echo '</li>';
}
}
echo '</ul>';
}

If product category has children remove permalink from parent term in WooCommerce

Inspired from get woocommerce categories with subcategory, I am creating a drop down section and I was wondering if there is any way to remove the permalink from the parent category if it has a child category.
Here is my code example:
<?php
$args = array(
'taxonomy' => 'product_cat',
'hide_empty' => false,
'parent' => 0
);
$product_cat = get_terms( $args );
$thumbnail_id = get_woocommerce_term_meta( $term_id, 'thumbnail_id', true );
$image = wp_get_attachment_url( $thumbnail_id );
foreach ($product_cat as $term){
$term_link = get_term_link( $term, 'product_cat' );
$thumb_id = get_woocommerce_term_meta( $term->term_id, 'thumbnail_id', true );
$img_src = wp_get_attachment_url( $thumb_id );
//if parent category has children remove link
echo '<ul>
<li><img src="' . $img_src . '"/>'.$term->name.'
<ul>';
// else keep the parent link
$child_args = array(
'taxonomy' => 'product_cat',
'hide_empty' => false,
'parent' => $term->term_id
);
$child_product_cats = get_terms( $child_args );
foreach ($child_product_cats as $child_product_cat){
echo '<li>'.$child_product_cat->name.'</li>';
}
echo '</ul>
</li>
</ul>';
}
How can I display a link on top level product categories terms only when there are no children terms?
The following will display a list of product category terms where the top level term will not be linked if they have any child term:
<?php
$taxonomy = 'product_cat';
$parent_terms = get_terms( array(
'taxonomy' => $taxonomy,
'hide_empty' => false,
'parent' => 0
) );
echo '<ul>';
// Loop through top level terms
foreach ( $parent_terms as $parent_term ) {
$term_link = get_term_link( $parent_term, 'product_cat' );
$thumb_id = get_woocommerce_term_meta( $parent_term->term_id, 'thumbnail_id', true );
$image_html = $thumb_id > 0 ? '<img src="' . wp_get_attachment_url( $thumb_id ) . '"/>' : '';
// Get children terms
$child_terms = get_terms( array(
'taxonomy' => $taxonomy,
'hide_empty' => false,
'parent' => $parent_term->term_id
) );
// 1. There are children terms
if( ! empty($child_terms) ) {
echo '<li>' . $image_html . $parent_term->name . '</li>
<ul>';
// Loop through children terms
foreach ( $child_terms as $term ) {
$term_link = get_term_link( $term->term_id, $taxonomy );
echo '<li>' . $term->name . '</li>';
}
echo '</ul>';
}
// 2. There are NOT children terms
else {
$parent_term_link = get_term_link( $parent_term->term_id, $taxonomy );
echo '<li>' . $image_html . '' . $parent_term->name . '</li>';
}
}
echo '</ul>';
Tested and works.

ACF Taxonomy only returning child - want both parent and child

I have the following function:
function my_acf_load_field( $field )
{
global $post;
global $current_user;
$field['choices'] = array();
wp_reset_query();
$query = new WP_Query(array(
'post_type' => 'gear',
'orderby' => 'title',
'order' => 'ASC',
'author' => $current_user->ID,
'posts_per_page' => -1,
));
foreach($query->posts as $product_id=>$macthed_product){
$zz = get_field('brand_preselect',$macthed_product->ID);
$yy = get_field('category_tax',$macthed_product->ID);
$aa = get_field('weight',$macthed_product->ID);
foreach( $yy as $term ):
$choices[$macthed_product->ID] = '<u class="cat">' . $term->name . '</u>' . '<i class="brand">' . $zz . '</i>' . $macthed_product->post_title . ' (' . $aa . ' kg)';
endforeach;
}
$field['choices'] = array();
if( is_array($choices) )
{
foreach( $choices as $key=>$choice )
{
$field['choices'][$key] = $choice;
}
}
// wp_reset_query();
return $field;
}
add_filter('acf/load_field/name=choices', 'my_acf_load_field');
This works well in that it populates the checkboxes with the category name, brand and title. For some reason $term->name in the foreach only shows the child category. If I echo out $term->name before the $choices[$macthed_product->ID] it shows all that apply. How do I get $term->name in the foreach to show all taxonomy matches (parent and child)

Wordpress, foreach on taxonomy shows duplicates

I have the below code, it works initially with regards to the fact that it displays the products for all taxonomies. However if a product is set to 2 taxonomies then it will display twice on the page as opposed to showing the first instance of the product.
<?php if ( $terms && !is_wp_error( $terms ) ) {
foreach ( $terms as $term ) {
$args = array(
'post_type' => 'products',
'posts_per_page' => -1,
'orderby' => 'menu_order',
'tax_query' => array(
array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => $term->slug,
),
),
'order' => 'asc',
);
runQuery($args);
}
} ?>
Here is the runQuery function:
<?php $x = 0;
function runQuery($args) {
global $x;
$query = new WP_Query( $args );
if ($query->have_posts()) : while ($query->have_posts()) : $query->the_post();
$cat_terms = get_the_terms($post->id, 'product_cat');
$datagroups = '';
foreach ($cat_terms as $key => $cat) {
if (count($cat_terms) == ($key + 1)) {
$datagroups .= '"' . $cat->name . '"';
} else {
$datagroups .= '"' . $cat->name . '", ';
}
}
?>
HTML Here that is displayed;
<?php $x ++;
endwhile;
endif;
wp_reset_postdata();
}?>
I have figured this out, I essentially just had to check the current post in the loop to see if it had already been displayed:
<?php $x = 0;
$displayed = [];
function runQuery($args) {
global $displayed;
global $x;
$query = new WP_Query( $args );
if ($query->have_posts()) : while ($query->have_posts()) : $query->the_post();
$cat_terms = get_the_terms($post->id, 'product_cat');
$datagroups = '';
if ( in_array( get_the_ID(), $displayed ) ){
continue;
}
// update array with currently displayed post ID
$displayed[] = get_the_ID();
foreach ($cat_terms as $key => $cat) {
if (count($cat_terms) == ($key + 1)) {
$datagroups .= '"' . $cat->name . '"';
} else {
$datagroups .= '"' . $cat->name . '", ';
}
}
?>
Source that may help others: https://wordpress.stackexchange.com/questions/285091/avoid-duplicate-post-from-same-taxonomy

Only display Woocommerce child product categories

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.

Categories