I've modified a function I found to do what I need, although it works, unfortunately the results returned are not in any specific order, I need them to be alphabetical.
This script returns a list of subcategories from Woocommerce:
function get_product_subcategories_list( $category_slug ){
$terms_html = array();
$taxonomy = 'product_cat';
// Get the product category (parent) WP_Term object
$parent = get_term_by( 'slug', $category_slug, $taxonomy );
// Get an array of the subcategories IDs (children IDs)
$children_ids = get_term_children( $parent->term_id, $taxonomy );
// Loop through each children IDs
foreach($children_ids as $children_id) {
$term = get_term( $children_id, $taxonomy ); // WP_Term object
$term_link = get_term_link( $term, $taxonomy ); // The term link
$thumbnail_id = get_woocommerce_term_meta( $term->term_id, 'thumbnail_id', true );
if ( is_wp_error( $term_link ) ) $term_link = '';
// Set in an array the html formatted subcategory name/link
$terms_html[] = '<li>' . $term->name . '</li>';
}
return '<ul>' . implode( $terms_html ) . '</ul>';
}
...and not that it matters, but this is in my template:
get_product_subcategories_list( $post->post_name );
The problem is that $terms_html[] is returning this...
<li>Pants</li>
<li>Shoes</li>
<li>Hats</li>
...but I need it to be alphabetical like this:
<li>Hats</li>
<li>Pants</li>
<li>Shoes</li>
Since get_term_children doesn't provide any way of sorting. Just treat the array with the sorting yourself.
Push the ->name in the array as key pairs. Then just utilize ksort(). Like so:
foreach($children_ids as $children_id) {
$term = get_term( $children_id, $taxonomy ); // WP_Term object
$term_link = get_term_link( $term, $taxonomy ); // The term link
$thumbnail_id = get_woocommerce_term_meta( $term->term_id, 'thumbnail_id', true );
if ( is_wp_error( $term_link ) ) $term_link = '';
// Set in an array the html formatted subcategory name/link
$terms_html[$term->name] = '<li>' . $term->name . '</li>';
// ^^ push the term name as key
}
ksort($terms_html); // sort it
return '<ul>' . implode( $terms_html ) . '</ul>';
Try sort function
like this
sort($terms_html)
foreach($terms_html as $item){
echo $item;
}
Related
Here is my code - I would to modify. i added "echo ". ";" which adds a space and full stop after every value. However it will be added even if a value is not more than one. I would like modify code to put a comma and space only if the value is more than one. Thanks
$terms = get_the_terms( $post->ID , 'book-author' );
foreach ( $terms as $term ) {
$term_link = get_term_link( $term, 'book-author' );
if( is_wp_error( $term_link ) )
continue;
echo '' . $term->name . '';
echo ". ";
}
?>
Put all your strings in an array, then use implode() to combine them with a delimiter.
$terms = get_the_terms( $post->ID , 'book-author' );
$links = [];
foreach ( $terms as $term ) {
$term_link = get_term_link( $term, 'book-author' );
if( !is_wp_error( $term_link ) ) {
$links[] = '' . $term->name . '';
}
}
echo implode('. ', $links);
I am trying to add Publisher, Topic and Author to a Single Product with help of categories/subcategories. This is how it looks after hours of coding/and copying (very fresh with WooCommerce tbh)
This is what I am getting, but it shows ALL subcategories, not only the ones associated to the Product, this is the code I am using
function get_product_subcategories_list( $category_slug ){
$terms_html = array();
$taxonomy = 'product_cat';
// Get the product category (parent) WP_Term object
$parent = get_term_by( 'slug', $category_slug, $taxonomy );
// Get an array of the subcategories IDs (children IDs)
$children_ids = get_term_children( $parent->term_id, $taxonomy );
// Loop through each children IDs
foreach($children_ids as $children_id){
$term = get_term( $children_id, $taxonomy ); // WP_Term object
$term_link = get_term_link( $term, $taxonomy ); // The term link
if ( is_wp_error( $term_link ) ) $term_link = '';
// Set in an array the html formated subcategory name/link
$terms_html[] = '' . $term->name . '';
}
return '<span class="subcategories-' . $category_slug . '">' . implode( ', ', $terms_html ) . '</span>';
}
add_action('woocommerce_single_product_summary','monolith_cat_scan', 31);
function monolith_cat_scan() {
echo '<p>Topic : ';
echo get_product_subcategories_list( 'topics' );
echo '</p>';
echo '<p>Publisher : ';
echo get_product_subcategories_list( 'publishers' );
echo '</p>';
echo '<p>Author: ';
echo get_product_subcategories_list( 'authors' );
echo '</p>';
}
But I can't get the whole thing to work like I want to and get the subcategories of the Single Product, in this example only Spirituality, SOUNDS TRUE INC (only sub cat in Publishers), and Allan Watts should be there.
I'd appreciate every help!
I got a working code (it doesn't look beautiful I know but it's the best I could do and it does the trick.
add_action('woocommerce_single_product_summary','monolith_cat_scan', 31);
function monolith_cat_scan() {
global $post;
$cats = get_the_terms( $post->ID, 'product_cat' );
if ( ! empty( $cats ) ) {
foreach ( $cats as $term ) {
if( $term->parent == 30 ) {
echo '<p>Topic : ' . $term->name . '';
}
}
}
}
add_action('woocommerce_single_product_summary','monolith_cat_scan2', 32);
function monolith_cat_scan2() {
global $post;
$cats = get_the_terms( $post->ID, 'product_cat' );
if ( ! empty( $cats ) ) {
foreach ( $cats as $term ) {
if( $term->parent == 31 ) {
echo '<p>Author : ' . $term->name . '';
}
}
}
}
add_action('woocommerce_single_product_summary','monolith_cat_scan3', 33);
function monolith_cat_scan3() {
global $post;
$cats = get_the_terms( $post->ID, 'product_cat' );
if ( ! empty( $cats ) ) {
foreach ( $cats as $term ) {
// If parent cat ID = 116 echo subcat name...
if( $term->parent == 32 ) {
echo '<p>Publisher : ' . $term->name . '';
}
}
}
}
I need an imploded list of terms from three custom Woocommerce taxonomies including the taxonomy name to display in the product loop. I'll also need to be able to display multiple terms for each taxonomy. However, I can only get it to work with one taxonomy. And I can't figure out how to display the corresponding taxonomy name.
My custom taxonomies are 'artists', 'illustrators' and 'authors'. Here's what I'm trying to accomplish:
Robert Douglas (Author), Bill Johnston (Illustrator), Kyle McBeth (Artist)
function list_author_terms() {
global $post;
$person = get_the_terms(get_the_ID(), 'authors', 'artists', 'illustrators');
if ( $person
&& !is_wp_error( $person )
) {
#usort( $person, function ( $a, $b )
{
return strcasecmp(
$a->slug,
$b->slug
);
});
// Display your terms as normal
$term_list = [];
foreach ( $person as $term )
$term_list[] = '' . esc_html( $term->name ) . '<span class="attribute"> (Author)</span> ';
$term_names[] = $term->name;
echo implode( ', ', $term_list);
echo '<br>';
}
}
Add follows code snippet to achieve your task -
add_action( 'woocommerce_after_shop_loop_item', 'list_author_terms', 6 );
function list_author_terms(){
$taxonomies = array( 'authors', 'artists', 'illustrators' );
$pro_list_terms = array();
foreach ( $taxonomies as $taxonomy ) {
$term_obj_list = get_the_terms( get_the_ID(), $taxonomy );
$tax_obj = get_taxonomy( $taxonomy );
if( $term_obj_list && ! is_wp_error( $term_obj_list ) ){
foreach ( $term_obj_list as $term ) {
$link = get_term_link( $term, $taxonomy );
$pro_list_terms[] = '' . $term->name . ' (' .$tax_obj->labels->singular_name . ')';
}
}
}
echo join( ', ', $pro_list_terms );
}
I've found various snippets online to list the woocommerce product categories, but I can't find a snippet that lists the subcategories and sub-sub categories for a given category.
How can I get the subcategories of a given product category?
This is possible with a custom function in which you will set your "parent" product category slug:
function get_product_subcategories_list( $category_slug ){
$terms_html = array();
$taxonomy = 'product_cat';
// Get the product category (parent) WP_Term object
$parent = get_term_by( 'slug', $category_slug, $taxonomy );
// Get an array of the subcategories IDs (children IDs)
$children_ids = get_term_children( $parent->term_id, $taxonomy );
// Loop through each children IDs
foreach($children_ids as $children_id){
$term = get_term( $children_id, $taxonomy ); // WP_Term object
$term_link = get_term_link( $term, $taxonomy ); // The term link
if ( is_wp_error( $term_link ) ) $term_link = '';
// Set in an array the html formated subcategory name/link
$terms_html[] = '' . $term->name . '';
}
return '<span class="subcategories-' . $category_slug . '">' . implode( ', ', $terms_html ) . '</span>';
}
Code goes in function.php file of your active child theme (or active theme).
Tested and works.
Usage example:
echo get_product_subcategories_list( 'clothing' );
You will get an horizontal coma separated list (with links) of all subcategories for this given category
This is the code for get subcategory of given category:
$categories = get_the_terms( get_the_ID(), 'product_cat' );
//For checking category exit or not
if ( $categories && ! is_wp_error( $category ) ) :
foreach($categories as $category) :
// get the children (if any) of the current cat
$children = get_categories( array ('taxonomy' => 'product_cat', 'parent' => $category->term_id ));
if ( count($children) == 0 ) {
// if no children, then echo the category name.
echo $category->name;
}
endforeach;
endif;
I am trying to show a list of the taxonomies a custom post type is in, excluding those which aren't hierarchical.
The code below currently works but shows all taxonomies, however I can't get it to check if the taxonomy is hierarchical before running it through the loop.
I know there is a WordPress function that runs this check, but as I usually work front-end, I can't seem figure out where to put it in order for it to take effect:
is_taxonomy_hierarchical( $taxonomy )
The following is the function I am using to output a list of the taxonomies:
// get taxonomies terms links
function custom_taxonomies_terms_links(){
// get post by post id
$post = get_post( $post->ID );
// get post type by post
$post_type = $post->post_type;
// get post type taxonomies
$taxonomies = get_object_taxonomies( $post_type, 'objects' );
$out = array();
echo '<a href="';
echo '/';
echo '">';
echo 'Home';
echo "</a> / ";
foreach ( $taxonomies as $taxonomy_slug => $taxonomy ){
// get the terms related to post
$terms = get_the_terms( $post->ID, $taxonomy_slug );
if (!empty( $terms )) {
foreach ( $terms as $term ) {
$out[] =
'<a href="'
. get_term_link( $term->slug, $taxonomy_slug ) .'">'
. $term->name
. "</a> / ";
}
$out[] = " ";
}
}
return implode('', $out );
}
If I understand your correctly, couldn't you just test the taxonomy like the following:
foreach ( $taxonomies as $taxonomy_slug => $taxonomy ){
if ($taxonomy->hierarchical) {
// get the terms related to post
$terms = get_the_terms( $post->ID, $taxonomy_slug );
if (!empty( $terms )) {
foreach ( $terms as $term ) {
$out[] =
'<a href="'
. get_term_link( $term->slug, $taxonomy_slug ) .'">'
. $term->name
. "</a> / ";
}
$out[] = " ";
}
}
}
When you use 'objects' as the second parameter in:
get_object_taxonomies( $post_type, 'objects' );
what you get back is an array of taxonomy objects, as opposed to just taxonomy names (the other option). The taxonomy object has a property "hierarchical" that indicates whether that taxonomy is hierarchical or not. You can test this to choose the types of taxonomies (hierarchical or not) that you want.