Display a list of taxonomies, only if they are hierarchical - php

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.

Related

Sort results alphabetically in custom foreach loop

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;
}

Shortcode - Taxonomy terms list with ACF term icon

I'm trying to create a [shortcode] that will display taxonomy terms of a post in a list with an icon.
I am using ACF for the icon with meta book_icon, then trying to call it into the shortcode following the ACF forum post here.
This is my code so far:
add_shortcode( 'show-books', 'books_output' );
function books_output($atts){
ob_start();
echo '<ul class="books-terms">';
global $post;
$taxonomy = 'books';
$terms = get_the_terms( $post, $taxonomy );
$image = get_field('book_icon');
if ( !empty( $terms ) ) {
foreach ($terms as $term) {
echo '<li><img src="' . $image['url'] . '" class="book-css-class">' . $term->name . '</li>';
}
}
echo '</ul>';
$output = ob_get_clean();
return $output;
}
I'm getting the taxonomy terms in a list, but not the image icon.
Where am I going wrong?

Display terms for multiple Woocommerce custom taxonomies

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 );
}

Current taxonomy item in custom taxonomy term page

I've got a custom taxonomy called trailer_type with terms long and short. When visiting my_site/trailers/short (a page powered by template taxonomy-trailer_type.php) I display my taxonomy terms this way:
$terms = get_terms( 'trailer_type' );
if ( ! empty( $terms ) && ! is_wp_error( $terms ) ) {
echo '<ul>';
foreach ( $terms as $term ) {
echo '<li>' . $term->name . '</li>';
}
echo '</ul>';
}
Works well but is there a simple way to add a "current" class? For example if I'm on the "long" page, I'd need "long" to have "current" class in this menu.
You need to look at the queried object. There's several ways to do it, here's what I tend to use: $wp_query->queried_object - this returns, as the name implies, the queried object.
In your case, something like this should work:
$curTerm = $wp_query->queried_object;
$terms = get_terms( 'trailer_type' );
if ( ! empty( $terms ) && ! is_wp_error( $terms ) ) {
echo '<ul>';
foreach ( $terms as $term ) {
$classes = array();
if ($term->name == $curTerm->name)
$classes[] = 'current';
echo '<li class="'. implode(' ',$classes) .'">' . $term->name . '</li>';
}
echo '</ul>';
}
I'm setting the classes to an array simply for future expansion. You could set it to a string right away as well.
Try using
get_query_var( 'term' )
and check
if ($term->name == get_query_var( 'term' )){
//make something
}

Getting Wordpress category name from post ID not working

The problem is that I cannot display the category of a post:
http://screencast.com/t/hdQjpSV0Q
I have the following code in a function.php file:
// GET FEATURED IMAGE
function ST4_get_featured_image($post_ID) {
$custom_meta = get_post_custom(get_the_ID());
return $custom_meta["lumen_portfolio_preview_image_image"][0];
}
add_filter('manage_posts_columns', 'ST4_columns_head');
add_action('manage_posts_custom_column', ('ST4_columns_content'), 10, 2);
// ADD NEW COLUMN
function ST4_columns_head($defaults) {
$defaults['featured_image'] = 'Featured Image';
$defaults['categories_portfolio'] = 'Category';
return $defaults;
}
// SHOW THE FEATURED IMAGE
function ST4_columns_content($column_name, $post_ID) {
if ($column_name == 'featured_image') {
$post_featured_image = ST4_get_featured_image($post_ID);
if ($post_featured_image) {
echo '<img style="width:300px;height:200px;" src="' . $post_featured_image . '" />';
}
}
elseif ($column_name == 'categories_portfolio') {
$terms = get_the_terms( $post->ID , 'category' );
foreach ( $terms as $term ) {
$term_link = get_term_link( $term, 'category' );
if( is_wp_error( $term_link ) )
continue;
echo '' . $term->name . '';
}
}
}
I have empty results, NULL, but I want to have the post category field. I used many wordpress functions, but no success.
I've noticed that your using the $post->ID as your parameter in your get_the_terms function, anyways I assume that the problem is you can't retrieve the category of the post, I would recommend using the get_the_category function in place of the get_the_terms in your code:
// SHOW THE FEATURED IMAGE
function ST4_columns_content($column_name, $post_ID) {
if ($column_name == 'featured_image') {
$post_featured_image = ST4_get_featured_image($post_ID);
if ($post_featured_image) {
echo '<img style="width:300px;height:200px;" src="' . $post_featured_image . '" />';
}
}
elseif ($column_name == 'categories_portfolio') {
//replace this $terms = get_the_terms( $post->ID , 'category' );
$terms = get_the_category($post_ID); //should you be using this instead of $post->ID?
foreach ( $terms as $term ) {
//replace this $term_link = get_term_link( $term, 'category' );
$term_link = get_category_link($term->term_id);
if( is_wp_error( $term_link ) )
continue;
echo '' . $term->name . '';
}
}
}
You can do a var_dump($terms) to further see the values being returned by this function, hope it helps, cheers!
I think you are using custom post type "Portfolio" as shown in attached screenshot.
Use wp_get_post_terms rather than get_the_terms
Update following code:
$terms = get_the_terms( $post->ID , 'category' );
to
$terms = wp_get_post_terms( $post->ID , 'category', array("fields" => "all") );
Note that 2nd parameter is the taxonomy name you are using while registering taxonomy.
See an example below where 'testimonials-cat' is used to register taxonomy.
register_taxonomy('testimonials-cat', 'testimonials', $args);
Your code for above taxonomy will be:
$terms = wp_get_post_terms($post->id, 'testimonials-cat', array("fields" => "all"));

Categories