This should be pretty straight forward and I'm looking forward to learning how to do it.
The code below excludes the top level parent only. How do I modify this code to exclude the next level down as well?
EG:
My hierarchical terms are World>Country>USA
I'd like to display USA and not World or Country
$terms = get_the_terms( $post->ID, 'From' );
if ( !empty( $terms ) ) {
$output = array();
foreach ( $terms as $term ){
if( 0 != $term->parent )
$output[] = '' . $term->name . '';
}
if( count( $output ) )
echo '' . __('Categories:','om_theme') . '</b> ' . join( ", ", $output ) . '';
}
echo '' . __('Categories:','om_theme') . '</b> ' . end($output) . '';
Related
I am trying to display certain attributes that have data on a custom tab in woocommerce. I have found several examples of code but none are working for me.
I was given the following code
add_filter( 'woocommerce_display_product_attributes', 'remove_product_information', 10, 2 );
function remove_product_information( $product_attributes, $product ) {
// Remove an attribute from the array
unset($product_attributes['color']);
return $product_attributes;
}
echo wc_display_product_attributes( $product );
but its not filtering anything out it still displays 'color' or any other attribute name I put in there. Also I need t filter out several attributes, so do I just add additional unset lines? or is there a cleaner way to do that? Any insight on this?
Solution 1:
If you want to customize single product page attributes, You need to customize/override the product attribute page with your custom attribute page, after that, you can modify the attribute accordingly.
To customise the page like:
Copy
plugins/woocommerce/templates/single-product/product-attributes.php
To
themes/your-theme/woocommerce/single-product/product-attributes.php
and modify that.
Solution 2:
You have to define first the desired product attributes slugs in an array, after that you will get in single product pages:
add_action( 'display_product_attributes', 'display_product_attributes', 25 );
function display_some_product_attributes(){
// HERE define the desired product attributes to be displayed
$defined_attributes = array('fyllighet', 'carrier', 'billing-e-number');
global $product;
$attributes = $product->get_attributes();
if ( ! $attributes ) {
return;
}
$out = '<ul class="taste-attributes">';
foreach ( $attributes as $attribute ) {
// Get the product attribute slug from the taxonomy
$attribute_slug = str_replace( 'pa_', '', $attribute->get_name() );
// skip all non desired product attributes
if ( ! in_array($attribute_slug, $defined_attributes) ) {
continue;
}
// skip variations
if ( $attribute->get_variation() ) {
continue;
}
$name = $attribute->get_name();
if ( $attribute->is_taxonomy() ) {
$terms = wp_get_post_terms( $product->get_id(), $name, 'all' );
// get the taxonomy
$tax = $terms[0]->taxonomy;
// get the tax object
$tax_object = get_taxonomy($tax);
// get tax label
if ( isset ( $tax_object->labels->singular_name ) ) {
$tax_label = $tax_object->labels->singular_name;
} elseif ( isset( $tax_object->label ) ) {
$tax_label = $tax_object->label;
// Trim label prefix since WC 3.0
if ( 0 === strpos( $tax_label, 'Product ' ) ) {
$tax_label = substr( $tax_label, 8 );
}
}
$out .= '<li class="' . esc_attr( $name ) . '">';
$out .= '<p class="attribute-label">' . esc_html( $tax_label ) . ': </p> ';
$tax_terms = array();
foreach ( $terms as $term ) {
$single_term = esc_html( $term->name );
// Insert extra code here if you want to show terms as links.
array_push( $tax_terms, $single_term );
}
$out .= '<span class="attribute-value">' . implode(', ', $tax_terms) . '</span><progress value="' . implode(', ', $tax_terms) .
'" max="10"><div class="progress-bar"><span style="width:'
. implode(', ', $tax_terms) . '0%">'
. implode(', ', $tax_terms) . '</span></div></progress></li>';
} else {
$value_string = implode( ', ', $attribute->get_options() );
$out .= '<li class="' . sanitize_title($name) . ' ' . sanitize_title( $value_string ) . '">';
$out .= '<p class="attribute-label">' . $name . ': </p> ';
$out .= '<progress value="' . esc_html( $value_string ) . '" max="10"></progress></li>';
}
}
$out .= '</ul>';
echo $out;
}
So the code I posted does work, I was just using the wrong name for the attribute. I needed to add 'attribute_pa_' so for example 'attribute_pa_brand'
I have this Continent -> Country category setup for a custom post type.
- Africa (parent 1)
- Uganda
- Zambia
- Zimbabwe
- Asia (parent 2)
- Afghanistan
- Bahrain
- Bangladesh
- Bhutan
If parent category is checked for a post, don't echo the children categories. (even if one or more children is checked) echo => Africa, Asia
And the revert, if one or more child categories is checked, but the parent category is NOT checked. Show only the child categories. echo => Uganda, Zambia, Zimbabwe, Afghanistan, Bahrain, Bangladesh, Bhutan
UPDATE
Also if Africa (parent 1) is checked, while Asia (parent 2) is NOT checke, but Afghanistan and Bhutan (children of parent 2) is checked the output should be: echo => Africa, Afghanistan, Bhutan.
This will only output IF there is one or more parent categories checked.
<?php
$post = get_post(); // If $post is already available, skip.
$terms = get_the_terms( $post->ID, 'custom-category' );
foreach ( $terms as $term ) :
if ( $term->parent === 0 ) :
echo '<a href="' . esc_url( get_term_link( $term->term_id, 'custom-category' ) ) .
'" title="' . esc_html( $term->name ) . '" ' . '>' . esc_html( $term->name ) .
'</a> ';
endif;
endforeach;
?>
How to output the child catergories if their parent is NOT checked?
Please try below code which help you for logic of the need you may modify it for your output requirements
$post = get_post(); // If $post is already available, skip.
$terms = get_the_terms( $post->ID, 'category' );
$outputparent = $outputchild = array();
foreach( $terms as $term ) :
if( $term->parent === 0 ) :
$outputparent[] = '<a href="' . esc_url( get_term_link( $term ) ) .
'" title="' . esc_html( $term->name ) . '" ' . '>' . esc_html( $term->name ) .
'</a> ';
else :
$outputchild[] = '<a href="' . esc_url( get_term_link( $term ) ) .
'" title="' . esc_html( $term->name ) . '" ' . '>' . esc_html( $term->name ) .
'</a>';
endif; //Endif
endforeach;
if( !empty( $outputparent ) ) :
echo 'Parent category is checked<br>';
echo implode('<br>', $outputparent);
$outputchild = array();
elseif( !empty( $outputchild ) && empty( $outputparent ) ) :
echo 'Only Childs<br>';
echo implode('<br>', $outputchild);
endif;
I manage to figure out a solution to this problem! This is tested and produces my desired result! If you have a more elegant solution, please let me know!
<?php
$categories = get_the_terms( $post->ID, 'custom-category' );
// If term is a parent, add to post_parent array.
$post_parent = array();
foreach( $categories as $parent_id ) {
if($parent_id->parent < 1) {
$post_parent[] = $parent_id->term_id;
}
}
// If terms parentId does not exist in post_parent array
// add to array regions as a key => value pair
$regions = array();
foreach( $categories as $category ) {
if (!in_array($category->parent, $post_parent)) {
$regions[$category->term_id] = $category->name;
}
}
// Sort terms based on keys (regions), impolde and print
ksort($regions);
$locations = array();
foreach($regions as $key => $value) {
$locations[] = ' ' . $value . '';
}
echo implode(",", $locations);
?>
I found the following code to display all custom attributes on a product detail page (with a specific bar-style design that I need). The code works like a charm and I have the proper CSS to display horizontal bars of my custom attributes.
Problem I have is that I only want to display specific named
attributes and don't know how to change the loop to do that...
function isa_woocommerce_all_pa(){
global $product;
$attributes = $product->get_attributes();
if ( ! $attributes ) {
return;
}
$out = '<ul class="taste-attributes">';
foreach ( $attributes as $attribute ) {
// skip variations
if ( $attribute->get_variation() ) {
continue;
}
$name = $attribute->get_name();
if ( $attribute->is_taxonomy() ) {
$terms = wp_get_post_terms( $product->get_id(), $name, 'all' );
// get the taxonomy
$tax = $terms[0]->taxonomy;
// get the tax object
$tax_object = get_taxonomy($tax);
// get tax label
if ( isset ( $tax_object->labels->singular_name ) ) {
$tax_label = $tax_object->labels->singular_name;
} elseif ( isset( $tax_object->label ) ) {
$tax_label = $tax_object->label;
// Trim label prefix since WC 3.0
if ( 0 === strpos( $tax_label, 'Product ' ) ) {
$tax_label = substr( $tax_label, 8 );
}
}
$out .= '<li class="' . esc_attr( $name ) . '">';
$out .= '<p class="attribute-label">' . esc_html( $tax_label ) . ': </p> ';
$tax_terms = array();
foreach ( $terms as $term ) {
$single_term = esc_html( $term->name );
// Insert extra code here if you want to show terms as links.
array_push( $tax_terms, $single_term );
}
$out .= '<span class="attribute-value">' . implode(', ', $tax_terms) . '</span><progress value="' . implode(', ', $tax_terms) .
'" max="10"><div class="progress-bar"><span style="width:'
. implode(', ', $tax_terms) . '0%">'
. implode(', ', $tax_terms) . '</span></div></progress></li>';
} else {
$value_string = implode( ', ', $attribute->get_options() );
$out .= '<li class="' . sanitize_title($name) . ' ' . sanitize_title( $value_string ) . '">';
$out .= '<p class="attribute-label">' . $name . ': </p> ';
$out .= '<progress value="' . esc_html( $value_string ) . '" max="10"></progress></li>';
}
}
$out .= '</ul>';
echo $out;
}
add_action('woocommerce_single_product_summary', 'isa_woocommerce_all_pa', 20);
In the following code you will define first the desired product attributes slugs in an array, that will get displayed in single product pages:
add_action( 'woocommerce_single_product_summary', 'display_some_product_attributes', 25 );
function display_some_product_attributes(){
// HERE define the desired product attributes to be displayed
$defined_attributes = array('fyllighet', 'carrier', 'billing-e-number');
global $product;
$attributes = $product->get_attributes();
if ( ! $attributes ) {
return;
}
$out = '<ul class="taste-attributes">';
foreach ( $attributes as $attribute ) {
// Get the product attribute slug from the taxonomy
$attribute_slug = str_replace( 'pa_', '', $attribute->get_name() );
// skip all non desired product attributes
if ( ! in_array($attribute_slug, $defined_attributes) ) {
continue;
}
// skip variations
if ( $attribute->get_variation() ) {
continue;
}
$name = $attribute->get_name();
if ( $attribute->is_taxonomy() ) {
$terms = wp_get_post_terms( $product->get_id(), $name, 'all' );
// get the taxonomy
$tax = $terms[0]->taxonomy;
// get the tax object
$tax_object = get_taxonomy($tax);
// get tax label
if ( isset ( $tax_object->labels->singular_name ) ) {
$tax_label = $tax_object->labels->singular_name;
} elseif ( isset( $tax_object->label ) ) {
$tax_label = $tax_object->label;
// Trim label prefix since WC 3.0
if ( 0 === strpos( $tax_label, 'Product ' ) ) {
$tax_label = substr( $tax_label, 8 );
}
}
$out .= '<li class="' . esc_attr( $name ) . '">';
$out .= '<p class="attribute-label">' . esc_html( $tax_label ) . ': </p> ';
$tax_terms = array();
foreach ( $terms as $term ) {
$single_term = esc_html( $term->name );
// Insert extra code here if you want to show terms as links.
array_push( $tax_terms, $single_term );
}
$out .= '<span class="attribute-value">' . implode(', ', $tax_terms) . '</span><progress value="' . implode(', ', $tax_terms) .
'" max="10"><div class="progress-bar"><span style="width:'
. implode(', ', $tax_terms) . '0%">'
. implode(', ', $tax_terms) . '</span></div></progress></li>';
} else {
$value_string = implode( ', ', $attribute->get_options() );
$out .= '<li class="' . sanitize_title($name) . ' ' . sanitize_title( $value_string ) . '">';
$out .= '<p class="attribute-label">' . $name . ': </p> ';
$out .= '<progress value="' . esc_html( $value_string ) . '" max="10"></progress></li>';
}
}
$out .= '</ul>';
echo $out;
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
I am working on project and I need some group help.
I am using woocommerce product system and on shop archive page product I am showing attribute-label: attribute-value (just like text).
attribute-label:attribute-value (ex. Transmission: Manual)
Is there a way to show attribute-label as image? I can't add html code like <img src..."/> and styling with CSS doesn't help too.
I have searched for plugins and more.. But nothing on web.
To show attributes on product shop page i have used this function:
function isa_woocommerce_all_pa(){
global $product;
$attributes = $product->get_attributes();
if ( ! $attributes ) {
return;
}
$out = '<ul class="custom-attributes">';
foreach ( $attributes as $attribute ) {
// skip variations
if ( $attribute->get_variation() ) {
continue;
}
$name = $attribute->get_name();
if ( $attribute->is_taxonomy() ) {
$terms = wp_get_post_terms( $product->get_id(), $name, 'all' );
// get the taxonomy
$tax = $terms[0]->taxonomy;
// get the tax object
$tax_object = get_taxonomy($tax);
// get tax label
if ( isset ( $tax_object->labels->singular_name ) ) {
$tax_label = $tax_object->labels->singular_name;
} elseif ( isset( $tax_object->label ) ) {
$tax_label = $tax_object->label;
// Trim label prefix since WC 3.0
if ( 0 === strpos( $tax_label, 'Product ' ) ) {
$tax_label = substr( $tax_label, 8 );
}
}
$out .= '<li class="' . esc_attr( $name ) . '">';
$out .= '<span class="attribute-label">' . esc_html( $tax_label ) . ': </span> ';
$out .= '<span class="attribute-value">';
$tax_terms = array();
foreach ( $terms as $term ) {
$single_term = esc_html( $term->name );
// Insert extra code here if you want to show terms as links.
array_push( $tax_terms, $single_term );
}
$out .= implode(', ', $tax_terms);
$out .= '</span></li>';
} else {
$value_string = implode( ', ', $attribute->get_options() );
$out .= '<li class="' . sanitize_title($name) . ' ' . sanitize_title( $value_string ) . '">';
$out .= '<span class="attribute-label">' . $name . ': </span> ';
$out .= '<span class="attribute-value">' . esc_html( $value_string ) . '</span></li>';
}
}
$out .= '</ul>';
echo $out;
}
add_action('woocommerce_single_product_summary', 'isa_woocommerce_all_pa', 25);
Can someone help me with this? How to change attribute-label with image?
Updated since WC 3.2+
As Product attributes dont have images, you should create a in your active theme a folder images (if it doesn't exist) and inside a subfolder attributes.
For each product attribute, you will have to add an image inside this subfolder attributes, which name will be the name of your attribute (the slug). For example for "Color" attribute you will have to add an image named color.jpg.
Then I have make some changes in your code, to get this working. Only the terms set in the product for each attribute will be displayed. For each attribute you will get an image.
Here is the code:
add_action('woocommerce_single_product_summary', 'isa_woocommerce_all_pa', 25);
function isa_woocommerce_all_pa(){
global $product;
$attributes = $product->get_attributes();
if ( ! $attributes ) return;
$out = '<ul class="custom-attributes">';
foreach ( $attributes as $attribute ) {
if ( $attribute->get_variation() ) continue; // skip variations
if ( $attribute->is_taxonomy() ) {
$taxonomy = $attribute->get_name();
$taxo_obj = $attribute->get_taxonomy_object();
$name = $taxo_obj->attribute_name; // <== Corrected
$label = $taxo_obj->attribute_label; // <== Corrected
$out .= '<li class="' . esc_attr( $taxonomy ) . '">';
## ATTRIBUTE IMAGE ##
// For a child theme use get_stylesheet_directory_uri() instead.
$out .= '<img class="attribute-image" src="'.get_template_directory_uri().'/images/attributes/'.$name.'.jpg" alt="Attribute '.$label.'"/> ';
$out .= '<span class="attribute-values">';
$terms = wp_get_post_terms( $product->get_id(), $taxonomy, array('fields' => 'names') );
foreach ( $terms as $term_name )
$term_names['name'] = $term_name;
$out .= implode(', ', $term_names);
$out .= '</span></li>';
} else {
$value_string = implode( ', ', $attribute->get_options() );
$out .= '<li class="' . sanitize_title($taxonomy) . ' ' . sanitize_title( $value_string ) . '">';
$out .= '<span class="attribute-label">' . $taxonomy . ': </span> ';
$out .= '<span class="attribute-value">' . esc_html( $value_string ) . '</span></li>';
}
}
$out .= '</ul>';
echo $out;
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
This code is tested and work.
I don't understand PHP very well but I'm trying to adjust this code below. I want the terms to all have a comma after them except for the last one. Right now the output looks like this:
Audience: Pre-School, High School, Adult,
However I need it to look like this:
Audience: Pre-School, High School, Adult
I realize there are similar questions out there that already answer this question, but since I am clueless when it comes to PHP I don't know how to incorporate those solutions with this code I already have. Can anyone help?
Thanks in advance!
<?php
$terms = get_terms( 'Audience' );
if ( ! empty( $terms ) && ! is_wp_error( $terms ) ){
echo '<p><strong>Audience:</strong> ';
foreach ( $terms as $term ) {
echo '' . $term->name . ', ';
}
echo '</p>';
}
?>
You can do this with the amazingly convenient function implode:
echo implode(", ", $terms);
You can either count during the foreach loop;
$i = 1;
foreach ( $terms as $term ) {
echo '' . $term->name;
if ($i < count($terms)) {
echo ', ';
}
$i++;
}
Or you can simply load it all into a variable and then crop the last comma and space off.
$output = '';
foreach ( $terms as $term ) {
$output .= $term->name . ', ';
}
echo substr($output,0,-2);
Save the line to a variable during the loop and then remove the last character before printing it. Not the most elegant solution but it works
<?php
$terms = get_terms( 'Audience' );
if ( ! empty( $terms ) && ! is_wp_error( $terms ) ){
echo '<p><strong>Audience:</strong> ';
$len = count($terms);
$i = 0;
foreach ( $terms as $term ) {
i++;
echo '' . $term->name . ($i < $len ? ', ' : '');
}
echo '</p>';
}
?>
You can use trim() http://ar2.php.net/trim
$string = '';
$terms = get_terms( 'Audience' );
if ( ! empty( $terms ) && ! is_wp_error( $terms ) ){
$string .= '<p><strong>Audience:</strong> ';
foreach ( $terms as $term ) {
$string .= '' . $term->name . ', ';
}
$string .= "</p>";
echo trim($string, ',');
}
?>
You can use it to remove strings from the start and end of your whole string.