Shortcode - Taxonomy terms list with ACF term icon - php

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?

Related

Displaying the Woocommerce subcategory image in a shortcode

So I had a shortcode working well which pulled in the subcategories of a product and displayed the image and text but realised it was at the top of the content because I had used echo . . . so moved the HTML output into a variable so I could return it but the images are coming out of the list items, so seem to be having an issue with the function: woocommerce_subcategory_thumbnail()
Not too sure why but I presume the function must have an echo? I guess I want to just get the image url and put it in a container? Honestly have no idea what the best method is but this is where I'm at
add_shortcode( 'show_products_categories_os', 'categories_of_the_product_os' );
function categories_of_the_product_os() {
$term_id = get_term_by( 'slug', 'os', 'product_cat' );
$terms = get_the_terms( get_the_ID(), 'product_cat' );
if ( $terms ) {
$output_html .= '<ul class="product-cats osp">';
foreach ( $terms as $term ) {
if($term->parent === $term_id->term_id){
$output_html .= '<li class="category os">';
$output_html .= '' . woocommerce_subcategory_thumbnail( $term ) . '';
$output_html .= '<h2>' . $term->name . '</h2>';
$output_html .= '</li>';
}
}
$output_html .= '</ul>';
}
return $output_html;
}
Is there another function I can't find that can give me jst the url for the image? Or a way of stripping it from that other function?
You need to get the thumbnail_id from the term's metadata and pass that as a parameter to wp_get_attachment_url
add_shortcode( 'show_products_categories_os', 'categories_of_the_product_os' );
function categories_of_the_product_os() {
$term_id = get_term_by( 'slug', 'os', 'product_cat' );
$terms = get_the_terms( get_the_ID(), 'product_cat' );
if ( $terms ) {
$output_html .= '<ul class="product-cats osp">';
foreach ( $terms as $term ) {
$thumbnail_id = get_term_meta( $term->term_id, 'thumbnail_id', true );
$image_url = wp_get_attachment_url( $thumbnail_id );
if($term->parent === $term_id->term_id){
$output_html .= '<li class="category os">';
$output_html .= '' . $image_url . '';
$output_html .= '<h2>' . $term->name . '</h2>';
$output_html .= '</li>';
}
}
$output_html .= '</ul>';
}
return $output_html;
}
Source: https://stackoverflow.com/a/51465602/14481105
To Note
You now need to add that $image_url to the src attribute of an img tag for an image to be output, as currently just the URL would appear.

Display current category first then child categories in WooCommerce

I'm trying to display in the sidebar the current page's category and it's subcategories. The title should be the current category's name and linked to the current category as well. An example of what I'm trying to achieve can be seen here in the sidebar: https://food52.com/shop/pantry
This is my current site as an example:https://farmtofrank.wpengine.com/product-category/prepared-foods/
This is the code I've created so far:
<?php
$terms = get_terms([
'taxonomy' => get_queried_object()->taxonomy,
'parent' => get_queried_object_id(),
]);
global $post;
$terms = get_the_terms( $post->ID, 'product_cat' );
echo '<div>';
foreach ( $terms as $term) {
echo '<p class="filters">' . $term->name . '</p>';
}
echo '</div>';
?>
It works but it puts the parent link at the bottom of the list. How can I keep the parent link at the top above the subcategories?
I suppose that this is related to product category archive pages. In this case, you are very near, try:
$queried_object = get_queried_object();
if ( is_product_category() && is_a($queried_object, 'WP_Term') ) {
$taxonomy = $queried_object->taxonomy;
echo '<h2 class="shop__sidebar-heading">
' . $queried_object->name . '
</h2>';
$children_terms = get_terms(['taxonomy' => $taxonomy, 'parent' => $queried_object->term_id]);
if ( ! empty($children_terms) ) {
echo '<ul class="'.$queried_object->slug.' child-terms">';
// Loop through children terms
foreach ( $children_terms as $term) {
echo '<li class="filters">' . $term->name . '</li>';
}
echo '</ul>';
}
}
Tested and works. It will require some styling (CSS).

How to make an image link to an archive page with php/woocommerce

I've created a custom field for adding a brand logo image to a product in woocommerce. On the front end, the logo shows up at the start of the product summary - above the product title with this code:
/**Add MFG Logo Above Short Description*/
add_action( 'woocommerce_single_product_summary', 'brands');
function brands() {
global $post;
global $product;
$mfglogo= get_post_meta($post->ID, 'brand_logo', true);
echo '<div>';
echo '<img src="' . $mfglogo.'"></a>';
echo'</div>';
}
I'd like to make this image linkable to the corresponding brands archive page. I created a global attribute for brands as well so I can filter the products pages by brand.
I learned that you can make your attributes into a list on the front end, and they are clickable to their attribute archive pages with this code:
/**Add Brand Link to META List*/
function list_attributes( $product ) {
global $product;
global $post;
$attributes = $product->get_attributes();
if ( ! $attributes ) {
return;
}
foreach ( $attributes as $attribute ) {
// Get the taxonomy.
$terms = wp_get_post_terms( $product->id, $attribute[ 'name' ], 'all' );
$taxonomy = $terms[ 0 ]->taxonomy;
// Get the taxonomy object.
$taxonomy_object = get_taxonomy( $taxonomy );
// Get the attribute label.
$attribute_label = $taxonomy_object->labels->name;
// Display the label followed by a clickable list of terms.
echo get_the_term_list( $post->ID, $attribute[ 'name' ] , '<div class="attributes">' . $attribute_label . ': ' , ', ', '</div>' );
break;
}
}
add_action( 'woocommerce_product_meta_end', 'list_attributes' );
. How can I use this idea to make the logo image linkable???
You could replace this:
echo '<div>';
echo '<img src="' . $download4 .'">';
echo'</div>';
with the following:
foreach ( $attribute as $attr) {
echo '<div>';
echo '<img src="' . $download4 .'">';
echo'</div>';
// Uncomment the follwing line if you want to display the first attribute only (makes sense since you only have one logo image)
// break;
}

Display a list of taxonomies, only if they are hierarchical

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.

wordpress get_the_terms not work

this is my query to show my work in the portfolio
<?php
// The Query
$the_query = new WP_Query( array( 'post_type'=> 'portfolio' ) );
// The Loop
if ( $the_query->have_posts() ) {
while ( $the_query->have_posts() ) {
$the_query->the_post();
$thumb = wp_get_attachment_image_src( get_post_thumbnail_id($post->ID), 'thumbnail' );
$medium = wp_get_attachment_image_src( get_post_thumbnail_id($post->ID), 'large' );
$url_thumb = $thumb['0'];
$url_medium = $medium['0'];
$option = '<li>';
$option .= '<a data-value="' . get_the_terms($post->ID, 'portfolio' ) . '" data-largesrc="' . $url_medium .'" data-title="' . get_the_title() .'" data-description="' . get_the_content() .'">';
$option .= '<img src="' . $url_thumb . '" alt="img01" />';
$option .= '</a>';
$option .= '</li>';
echo $option;
}
} else {
}
/* Restore original Post Data */
wp_reset_postdata();
?>
The problem is here, in the data-value I need to extract the category of work
data-value="' . get_the_terms( 'portfolio', $post->ID ) . '"
I think the code that I use is wrong because if I put online I truncates the code and I do not show anything
Your code suggests that portfolio is a custom post type, not a custom taxonomy, but you are passing it as the taxonomy parameter for get_the_terms(). These are not the same things - post types are types of content (e.g. posts, pages) and taxonomies are ways to organize and group things (e.g. tags, categories).
You need to pass the slug of the custom taxonomy as the $taxonomy parameter, not the slug of the custom post type portfolio. I don't know what taxonomy you are querying but it is probably something like portfolio_categories or similar. For example if you were using the default category taxonomy with the post you would want get_the_terms($post->ID, 'category');
You are using wrong syntax, the right syntax is
<?php get_the_terms( $id, $taxonomy ); ?>

Categories