I'm trying to add the product title and some taxonomy terms to the image alt and image title text on the front end. I can add the product title with the function below but I'd like to append the taxonomy terms from the default woocommerce product_cat and also some custom taxonomies outlined below:
add_filter('wp_get_attachment_image_attributes', 'change_attachement_image_attributes', 20, 2);
function change_attachement_image_attributes( $attr, $attachment ){
// Get post parent
$parent = get_post_field( 'post_parent', $attachment);
// Bail if it's not a product or if admin
$type = get_post_field( 'post_type', $parent);
if( is_admin() || $type != 'product' ){
return $attr;
}
// Get title
$title = get_post_field( 'post_title', $parent);
// Get Product Category
$product_cat = get_the_terms($post->ID,'product_cat');
// Get Artwork Category
$artwork_cat = get_the_terms($post->ID,'artwork-category');
// Get Artwork Materials
$artwork_material = get_the_terms($post->ID,'artwork-materials');
$attr['alt'] = $title;
$attr['title'] = $title;
return $attr;
}
Ideally, I'd like to output something like:
"$title, a $artwork_cat by $product_cat. $artwork_material" (E.g. The Mona Lisa, a painting by Leonardo Da Vinci. Oil on board.)
Any help would be great!
You have to pass the product id to the get_the_terms function which is you already getting in $parent. Try the below code.
function change_attachement_image_attributes( $attr, $attachment ){
// Get post parent
$parent = get_post_field( 'post_parent', $attachment);
// Bail if it's not a product or if admin
$type = get_post_field( 'post_type', $parent);
if( is_admin() || $type != 'product' ){
return $attr;
}
// Get title
$title = get_post_field( 'post_title', $parent);
// Get Product Category
$product_cat = get_the_terms($parent,'product_cat');
// Get Artwork Category
$artwork_cat = get_the_terms($parent,'artwork-category');
// Get Artwork Materials
$artwork_material = get_the_terms($parent,'artwork-materials');
$title = $title.', a'.$artwork_cat.' by '.$product_cat[0]->name.'. '.$artwork_material.'.';
$attr['alt'] = $title;
$attr['title'] = $title;
return $attr;
}
add_filter( 'wp_get_attachment_image_attributes', 'change_attachement_image_attributes', 20, 2 );
Related
I display the breadcrumbs inside my product pages. I am trying to manually replace the category link of "Horlogerie" with a custom link '/test'.
Here is my code using this answer :
add_filter( 'woocommerce_get_breadcrumb', 'custom_breadcrumb', 10, 2 );
function custom_breadcrumb( $crumbs, $object_class ){
// Loop through all $crumb
var_dump($crumbs);
foreach( $crumbs as $key => $crumb ){
$taxonomy = 'product_cat'; // The product category taxonomy
// Check if it is a product category term
$term_array = term_exists( $crumb[0], $taxonomy );
// if it is a product category term
if ( $term_array !== 0 && $term_array !== null ) {
// Get the WP_Term instance object
$term = get_term( $term_array['term_id'], $taxonomy );
// HERE set your new link with a custom one
$crumbs[$key][1] = 'test';
}
}
return $crumbs;
}
But the link doesn't get changed. I tried using the "Twenty Twenty-one" theme, but the problem persists.
Thank you for your help.
You have simply just added one condition. try the below code.
function custom_breadcrumb( $crumbs, $object_class ){
// Loop through all $crumb
var_dump($crumbs);
foreach( $crumbs as $key => $crumb ){
$taxonomy = 'product_cat'; // The product category taxonomy
// Check if it is a product category term
$term_array = term_exists( $crumb[0], $taxonomy );
// if it is a product category term
if ( $term_array !== 0 && $term_array !== null ) {
// Get the WP_Term instance object
$term = get_term( $term_array['term_id'], $taxonomy );
if( $term->name == 'your specific term name' ){
// HERE set your new link with a custom one
$crumbs[$key][1] = 'test';
}
}
}
return $crumbs;
}
add_filter( 'woocommerce_get_breadcrumb', 'custom_breadcrumb', 10, 2 );
I want to change the WooCommerce product description tab button and title "Description" into "Tracklist" when the page has a body class of "parent-product_cat-vinyl".
Here is my code so far:
<?php
if ( is_singular() ) {
$classes = get_body_class();
if (in_array('parent-product_cat-vinyl',$classes)) {
add_filter( 'woocommerce_product_description_tab_title','ps_rename_description_product_tab_label');
function ps_rename_description_product_tab_label() {
return 'Tracklist';
}
}
}
But it doesn't seem to work.
You can use the following composite filter hooks (where $tab_key is in your case description):
woocommerce_product_{$tab_key}_tab_title
woocommerce_product_{$tab_key}_heading
It can be done in 2 ways:
Conditionally with a defined body class:
add_filter( 'woocommerce_product_description_tab_title', 'change_product_description_tab_text' );
add_filter( 'woocommerce_product_description_heading', 'change_product_description_tab_text' );
function change_product_description_tab_text( $title ) {
global $product;
if( in_array( 'parent-product_cat-vinyl', get_body_class() ) ) {
return __('Tracklist', 'woocommerce');
}
return $title;
}
Or conditionally for a product category (including parent product categories):
// Custom conditional function that handle parent product categories too
function has_product_categories( $categories, $product_id = 0 ) {
$parent_term_ids = $categories_ids = array(); // Initializing
$taxonomy = 'product_cat';
$product_id = $product_id == 0 ? get_the_id() : $product_id;
if( is_string( $categories ) ) {
$categories = (array) $categories; // Convert string to array
}
// Convert categories term names and slugs to categories term ids
foreach ( $categories as $category ){
$result = (array) term_exists( $category, $taxonomy );
if ( ! empty( $result ) ) {
$categories_ids[] = reset($result);
}
}
// Loop through the current product category terms to get only parent main category term
foreach( get_the_terms( $product_id, $taxonomy ) as $term ){
if( $term->parent > 0 ){
$parent_term_ids[] = $term->parent; // Set the parent product category
$parent_term_ids[] = $term->term_id; // (and the child)
} else {
$parent_term_ids[] = $term->term_id; // It is the Main category term and we set it.
}
}
return array_intersect( $categories_ids, array_unique($parent_term_ids) ) ? true : false;
}
add_filter( 'woocommerce_product_description_tab_title', 'change_product_description_tab_text' );
add_filter( 'woocommerce_product_description_heading', 'change_product_description_tab_text' );
function change_product_description_tab_text( $title ) {
global $product;
// Here set in the array the targeted product categories
$categories = array('Vinyl');
if ( has_product_categories( $categories, $product->get_id() ) ) {
return __('Tracklist', 'woocommerce');
}
return $title;
}
Code goes in functions.php file of your active child theme (or active theme) . Tested and works.
I would like to Hide "remove item" from cart for a specific product category in WooCommerce, just like in "Hide "remove item" from cart for a specific product in WooCommerce" answer thread, but for a specific product category.
Any help would be appreciated.
The following code will hide "remove item" from cart for a specific product category (that you will define in the 2nd function):
// Custom conditional function that handle parent product categories too
function has_product_categories( $categories, $product_id = 0 ) {
$parent_term_ids = $categories_ids = array(); // Initializing
$taxonomy = 'product_cat';
$product_id = $product_id == 0 ? get_the_id() : $product_id;
if( is_string( $categories ) ) {
$categories = (array) $categories; // Convert string to array
}
// Convert categories term names and slugs to categories term ids
foreach ( $categories as $category ){
$result = (array) term_exists( $category, $taxonomy );
if ( ! empty( $result ) ) {
$categories_ids[] = reset($result);
}
}
// Loop through the current product category terms to get only parent main category term
foreach( get_the_terms( $product_id, $taxonomy ) as $term ){
if( $term->parent > 0 ){
$parent_term_ids[] = $term->parent; // Set the parent product category
$parent_term_ids[] = $term->term_id; // (and the child)
} else {
$parent_term_ids[] = $term->term_id; // It is the Main category term and we set it.
}
}
return array_intersect( $categories_ids, array_unique($parent_term_ids) ) ? true : false;
}
// Hiding "remove item" for specific product category
add_filter('woocommerce_cart_item_remove_link', 'filter_cart_item_remove_link', 20, 2 );
function filter_cart_item_remove_link( $button_link, $cart_item_key ){
// HERE your specific products categories
$categories = array( 'clothing' );
// Get the current cart item
$cart_item = WC()->cart->get_cart()[$cart_item_key];
// If the targeted product is in cart we remove the button link
if( has_product_categories( $cart_item['product_id'], $categories ) )
$button_link = '';
return $button_link;
}
Code goes in functions.php file of your active child theme (or active theme). Tested and works.
The below code will work as you want it : just change the category id in if clause:
function tristup_woocommerce_cart_item_remove_link($link){
preg_match('/data-product_id=\"(.*?)\"/', $link, $matches);
$flag=0;
if($matches)
{
$product_id=$matches[1];
$terms = get_the_terms ( $product_id, 'product_cat' );
foreach ( $terms as $term )
{
if($term->term_id=='210') // change with your category id or add more with in proper syntaxes
{
return '';
}
}
}
return $link;
}
add_filter('woocommerce_cart_item_remove_link', 'tristup_woocommerce_cart_item_remove_link');
By default in Woocommerce for alt used image file's name.
Does anyone know how to change thumbnail meta (alt and title) to show Product name?
Try this :
add_filter('wp_get_attachment_image_attributes', 'change_attachement_image_attributes', 20, 2);
function change_attachement_image_attributes( $attr, $attachment ){
// Get post parent
$parent = get_post_field( 'post_parent', $attachment);
// Get post type to check if it's product
$type = get_post_field( 'post_type', $parent);
if( $type != 'product' ){
return $attr;
}
/// Get title
$title = get_post_field( 'post_title', $parent);
$attr['alt'] = $title;
$attr['title'] = $title;
return $attr;
}
I've updated XciD's answer to a much cleaner version:
add_filter('wp_get_attachment_image_attributes', 'change_attachement_image_attributes', 20, 2);
function change_attachement_image_attributes($attr, $attachment) {
global $post;
if ($post->post_type == 'product') {
$title = $post->post_title;
$attr['alt'] = $title;
$attr['title'] = $title;
}
return $attr;
}
Unfortunately on the main image the script doesn't work for me (XciD's neither), but on the small thumbs it is. Interesting :)
Update: If I turn off the main image, then the script starts working from the second thumb!
Update 2: Ok. It was an "Oh God Please No!" situation as some bad words JS code changed the alt tag. OMG...
Good morning, I'm trying to change the header depending on the category of the single product. i am using Wordpress & WooCommerce
My product categories look like this
- the-lawn-store
- - turf
- - grass-seed
- - wildflower-turf
- the-oak-store
- - railway-sleepers
- - pergolas
Basically when viewing an item which falls under the parent category of the-lawn-store I need the header to be <?php get_header('lawn'); ?> and when the parent category is the-oak-store I need the header to be <?php get_header('oak'); ?>, the difference between headers is the styling of the over all page! what is the best way to go about this?
Well, what you need is the category parent. In order to do that, first of all you can get the parent ID with this:
global $wp_query;
$cat_obj = $wp_query->get_queried_object();
if($cat_obj) {
//print_r($cat_obj);
$category_ID = $cat_obj->term_id;
$category_parent = $cat_obj->parent;
$category_taxonomy = $cat_obj->taxonomy;
$category_parent_term = get_term_by( 'id', absint( $category_ID ), $category_taxonomy );
$category_parent_slug = $category_parent_term->slug;
get_header( $category_parent_slug );
}else{
get_header();
}
Uncomment the print_r to see the rest of available vars. Tested on my local woo and works.
You can't filter the get_header() function so you will have to override WooCommerce's single-product.php template. From there you can modify the beginning of the file:
get_header( 'shop' ); ?>
I created the following function to get the top-level product category for any product:
function kia_get_the_top_level_product_category( $post_id = null ){
$product_cat_parent = null;
if( ! $post_id ){
global $post;
$post_id = $post->ID;
}
// get the product's categories
$product_categories = get_the_terms( $product_id, 'product_cat' );
if( is_array( $product_categories ) ) {
// gets complicated if multiple categories, so limit to one
// on the backend you can restrict to a single category with my Radio Buttons for Taxonomies plugin
$product_cat = array_shift( $product_categories);
$product_cat_id = $product_cat->term_id;
while ($product_cat_id) {
$cat = get_term($product_cat_id, 'product_cat'); // get the object for the product_cat_id
$product_cat_id = $cat->parent; // assign parent ID (if exists) to $product_cat_id
// the while loop will continue whilst there is a $product_cat_id
// when there is no longer a parent $product_cat_id will be NULL so we can assign our $product_cat_parent
$product_cat_parent = $cat->slug;
}
}
return $product_cat_parent;
}
Then in your theme's single-product.php you could do:
$parent = kia_get_the_top_level_product_category();
if( $parent == 'oak' ){
get_header('oak');
} elseif( $parent == 'lawn' ){
get_header('lawn');
} else {
get_header('shop');
}
If you don't have a specific header-shop.php then you could technically also do:
$parent = kia_get_the_top_level_product_category();
get_header( $parent );
Overriding this template might put you at risk when WooCommerce upgrades. As an alternative I would suggest filtering the body class.
function wpa_22066003_body_class($c){
if( function_exists('is_product') && is_product() && $parent = kia_get_the_top_level_product_category() ){
$c[] = $parent . '-product-category';
}
return $c;
}
add_filter( 'body_class', 'wpa_22066003_body_class' );