Remove first word from the WooCommerce product title - php

Is it possible to remove the first word from the product title in WooCommerce? I've found some php code but I can't figure it out at the moment.
echo substr(strstr("Remove First Word"," "), 1);
That should echo "First Word". How would I do that for the WooCommerce product title? I appreciate all the help!

For product title in single product pages and archives pages:
add_filter( 'the_title', 'custom_the_title', 10, 2 );
function custom_the_title( $title, $post_id ){
$post_type = get_post_field( 'post_type', $post_id, true );
if( $post_type == 'product' || $post_type == 'product_variation' )
$title = substr( strstr( $title, ' ' ), 1 );
return $title;
}
Code goes in function.php file of your active child theme (or active theme).
Tested and works.
The product title uses WordPress function get_the_title() or the_title() to be displayed (as woocommerce product is a custom post type)… so the correct filter hook to be used is "the_title".
But it will not really handle html tags (as this are something else in the templates).
For cart and checkout pages:
add_filter( 'woocommerce_cart_item_name', 'customizing_cart_item_name', 10, 3);
function customizing_cart_item_name( $item_name, $cart_item, $cart_item_key ) {
$product = $cart_item['data'];
$product_permalink = $product->is_visible() ? $product->get_permalink( $cart_item ) : '';
$product_name = $product->get_name();
$product_name = substr( strstr( $product_name, ' ' ), 1 );
if ( $product_permalink && is_cart() ) {
return sprintf( '%s', esc_url( $product_permalink ), $product_name );
} elseif ( ! $product_permalink && is_cart() ) {
return $product_name . ' ';
} else {
return $product_name;
}
}
Code goes in function.php file of your active child theme (or active theme).
Tested and works.

use this:
$str = "Remove First Word";
$words = explode(' ', $str);
unset($words[0]);
echo join(' ', $words);
The explode function returns an array with each words.
The unset function remove the first word contained in the array $words.
Finally, join print all $words joined by space .
demo

Could you try using this?
if ( ! function_exists( 'woocommerce_template_loop_product_title' ) ) {
/**
* Removes first word in WooCommerce product_title
* #var $tag
*/
function woocommerce_template_loop_product_title() {
$tag = is_product_taxonomy() || is_shop() ? 'h2' : 'h3';
echo apply_filters( 'woocommerce_template_loop_product_title', '<' . $tag . ' class="woocommerce-loop-product__title">' . substr(strstr(get_the_title()," "), 1) . '</' . $tag . '>');
}
/**
* Removes first word in WooCommerce product page product_title
* #var $tag
*/
function woocommerce_single_product_summary() {
$tag = 'h1';
echo apply_filters(woocommerce_single_product_summary, '<' . $tag . ' class="product_title entry-title">' . substr(strstr(get_the_title()," "), 1) . '</' . $tag . '>');
}
}
Hopefully this works out for you, haven't tested it.

Related

Display product attributes values for specific categories in WooCommerce product loops

I'm building a shop in WP + WooCommerce. I have different types of product categories like discs and bags. For discs products I have some specific attributes like Speed, Glide, Turn and Fade that don't have any other product categories. I want to display these product attribute values only on shop pages under the product picture.
I have found one code for that and I added myself a separation symbol "|", but this separation symbol is now displayed under all the products that are variable.
Is it possible to change the code not to variables but only for specific product categories and sub-categories?
Code:
add_action( 'woocommerce_before_shop_loop_item_title', 'display_size_attribute', 5 );
function display_size_attribute() {
global $product;
if ( $product->is_type('variable') ) {
$taxonomy = 'pa_speed';
echo '<span class="attribute-speed">' . $product->get_attribute($taxonomy) . '</span>' ;
echo ' | ';
$taxonomy = 'pa_Glide';
echo '<span class="attribute-Glide">' . $product->get_attribute($taxonomy) . '</span>';
echo ' | ';
$taxonomy = 'pa_Turn';
echo '<span class="attribute-Turn">' . $product->get_attribute($taxonomy) . '</span>';
echo ' | ';
$taxonomy = 'pa_Fade';
echo '<span class="attribute-Fade">' . $product->get_attribute($taxonomy) . '</span>';
}
}
Use the following revisited code instead to get separated attribute values only if they exist on your variable products:
add_action( 'woocommerce_before_shop_loop_item_title', 'display_some_attributes', 5 );
function display_some_attributes() {
global $product;
if ( $product->is_type('variable') ) {
$attributes = array('speed', 'Glide', 'Turn', 'Fade'); // here you defined attribute slugs
$output = array(); // Initializing
// Loop through product attributes
foreach ( $attributes as $attribute ) {
$taxonomy = 'pa_' . $attribute;
$values = $product->get_attribute($taxonomy);
// If not empty add it to the array
if ( ! empty($values) ) {
$output[] = '<span class="attribute-' . $attribute . '">' . $values . '</span>';
}
}
// Convert array to a separated string by pipes
echo implode(' | ', $output);
}
}
To target specific product categories only, replace in the code the block:
global $product;
if ( $product->is_type('variable') ) {
with (where you will define your product categories terms):
global $product;
$categories = array( 'cats', dogs' ); // Here your category terms ids, slugs or names
if ( $product->is_type('variable') && has_term( $categories, 'product_cat', $product->get_id() ) ) {
Code goes in functions.php file of the active child theme (or active theme). Tested and works.

Display In stock available variations in WooCommerce single product short description

I have variable products with many variations where only a few items are actually In Stock while the majority of other variations are ''available on backorder''
I would like to be able to display a quick list of ONLY the items that are IN STOCK in the short product description of each product page so the customer doesn't have to try all variations one-by-one to finally find out which ones are in stock.
I've searched for plugins or code that can do this but did not find anything.
The closest code I found is:
add_action( 'woocommerce_after_shop_loop_item', 'bb_echo_stock_variations_loop' );
function bb_echo_stock_variations_loop(){
global $product;
if ( $product->get_type() == 'variable' ) {
foreach ( $product->get_available_variations() as $key ) {
$attr_string = array();
foreach ( $key['attributes'] as $attr_name => $attr_value ) {
$attr_string[] = $attr_value;
}
if ( $key['max_qty'] > 0 ) {
echo '<br/>' . implode( ', ', $attr_string ) . ': ' . $key['max_qty'] . ' in stock';
} else {
echo '<br/>' . implode(', ', $attr_string ) . ': out of stock';
}
}
}
}
But it displays "In stock" available variations on the SHOP page and I want it to be displayed on the single product short description.
How can I display "In stock" available variations in single product short description?
To display in stock variations list in product single pages on short description, use the following:
add_filter( 'woocommerce_short_description', 'display_in_stock_variations_to_short_description' );
function display_in_stock_variations_to_short_description( $excerpt ){
global $product;
if ( ! is_product() || empty($product) || ! is_a( $product, 'WC_Product' ) )
return $excerpt;
if( $product->is_type('variable') ) {
// Loop through visible children
foreach( $product->get_children() as $variation_id ) {
$variation = wc_get_product( $variation_id );
// Hide out of stock variations if 'Hide out of stock items from the catalog' is checked.
if ( ! $variation || ! $variation->exists() || ( 'yes' === get_option( 'woocommerce_hide_out_of_stock_items' ) && ! $variation->is_in_stock() ) ) {
continue;
}
// Filter 'woocommerce_hide_invisible_variations' to optionally hide invisible variations (disabled variations and variations with empty price).
if ( apply_filters( 'woocommerce_hide_invisible_variations', true, $product->get_id(), $variation ) && ! $variation->variation_is_visible() ) {
continue;
}
$max_qty = 0 < $variation->get_max_purchase_quantity() ? $variation->get_max_purchase_quantity() : $variation->get_stock_quantity();
$term_names = []; // Initializing
// Loop through variation attributes for current varation
foreach ( $variation->get_variation_attributes() as $attribute => $term_slug ) {
// Set the term name in an array
$term_names[] = ucfirst( str_replace( ['-', '_'],[' ', ' '], $term_slug ) );
}
if ( $max_qty > 0 ) {
$excerpt .= sprintf( '<br/>%s: %s %s',
implode(', ', $term_names),
$max_qty,
__('in stock', 'woocommerce')
);
}
}
}
return $excerpt;
}
// Avoid additional content from product short description to be displayed in variation description
add_filter( 'woocommerce_available_variation', 'filter_wc_available_variation_desscription', 10, 3);
function filter_wc_available_variation_desscription( $data, $product, $variation ) {
$max_qty = 0 < $variation->get_max_purchase_quantity() ? $variation->get_max_purchase_quantity() : $variation->get_stock_quantity();
if( $max_qty > 0 )
$data['variation_description'] = get_post_meta( $variation->get_id(), '_variation_description', true );
return $data;
}
Code goes in functions.php file of your active child theme (or active theme). Tested and works.

Display Woocommerce product attribute on archive page

I have set up an attribute for my products for a delivery time. And I am using the following functions to display it on product archives, on single product pages, on Orders and emails notifications:
add_action( 'woocommerce_single_product_summary', 'product_attribute_delivery', 27 );
function product_attribute_delivery(){
global $product;
$taxonomy = 'pa_delivery';
$value = $product->get_attribute( $taxonomy );
if ( $value && $product->is_in_stock() ) {
$label = get_taxonomy( $taxonomy )->labels->singular_name;
echo '<small>' . $label . ': ' . $value . '</small>';
}
}
add_action('woocommerce_order_item_meta_end', 'custom_item_meta', 10, 4 );
function custom_item_meta($item_id, $item, $order, $plain_text)
{ $productId = $item->get_product_id();
$product = wc_get_product($productId);
$taxonomy = 'pa_delivery';
$value = $product->get_attribute($taxonomy);
if ($value) {
$label = get_taxonomy($taxonomy)->labels->singular_name;
echo '<small>' . $label . ': ' . $value . '</small>';
}
}
add_action( 'woocommerce_after_shop_loop_item', 'product_attribute_delivery_shop', 1 );
function product_attribute_delivery_shop(){
global $product;
$taxonomy = 'pa_delivery';
$value = $product->get_attribute( $taxonomy );
if ( $value && $product->is_in_stock() ) {
$label = get_taxonomy( $taxonomy )->labels->singular_name;
echo '<small>' . $label . ': ' . $value . '</small>';
}
}
I have two questions:
Is there a way o combine these functions to optimize and clean up the code?
For the archive page (but not the single product page!) I want the text to change when the product is not on stock. Instead of not being displayed at all, I would like it to be "Sold Out".
Note that the rule on StackOverFlow is one question at the time. You can use a custom function that you will call on each hooked function like:
// Custom function that handle the code to display a product attribute
function custom_display_attribute( $product, $taxonomy = 'pa_delivery') {
$value = $product->get_attribute( $taxonomy );
if ( ! empty($value) && $product->is_in_stock() ) {
$label = wc_attribute_label( $taxonomy );
echo '<small>' . $label . ': ' . $value . '</small>';
}
}
// On product archive pages
add_action( 'woocommerce_after_shop_loop_item', 'product_attribute_delivery_archives', 1 );
function product_attribute_delivery_archives() {
global $product;
custom_display_attribute( $product );
// When product is out of stock displays "Sold Out"
if ( ! $product->is_in_stock() ) {
echo __("Sold Out", "woocommerce");
}
}
// On product single pages
add_action( 'woocommerce_single_product_summary', 'product_attribute_delivery_single', 27 );
function product_attribute_delivery_single() {
global $product;
custom_display_attribute( $product );
}
// On orders and email notifications
add_action('woocommerce_order_item_meta_end', 'custom_item_meta', 10, 4 );
function custom_item_meta( $item_id, $item, $order, $plain_text ) {
custom_display_attribute( wc_get_product( $item->get_product_id() ) );
}
It should works.
On archive pages only when product is not in stock, it will displays "Sold Out".

Display Woocommerce best-sellers by Current Category

I would like to make a shortcode, that can be placed on category pages, for example on the sidebar.
It should display the category's best selling products.
The only solution that I find is if I specify the category, with slug or id, like below:
[best_selling_products category=”KITCHEN-ACCESSORIES” columns="1" per_page="5"]
How can I transform the shortcode to something like this?
[best_selling_products category=”CURRENT-CATEGORY” columns="1" per_page="5"]
Add this to your functions.php
function custom_best_selling_products( $attr = array() ){
$string = '[best_selling_products ';
$string .= ' category="' . get_query_var( 'term' ) . '" ';
if( $attr ){
foreach ( $attr as $key => $value ) {
$string .= ' ' . $key . '="' . $value . '" ';
}
}
$string .= ']';
return do_shortcode( $string );
}
add_shortcode( 'custom_best_selling_products', 'custom_best_selling_products' );
This will create a custom shortcode and you can use it like this: [custom_best_selling_products columns="1" per_page="5"]
This shortcode will automatically get the category
Add the follows code snippet in your active theme's functions.php to get best selling products from current $term or category page -
function modify_woocommerce_shortcode_products_query( $query_args, $attributes, $type ) {
if( $type != 'best_selling_products' ) return $query_args;
$term = get_queried_object();
if( $term ) {
if( !isset($query_args['category'] ) ){
$query_args['category'] = $term->slug;
}
}
return $query_args;
}
add_filter( 'woocommerce_shortcode_products_query', 'modify_woocommerce_shortcode_products_query', 99, 3 );
Add just use woocommerce default shortcode [best_selling_products columns="1" per_page="5"] to get the data.

WooCommerce: Display also product variation description on cart items

I'm trying to display my product variation description in my Cart. I have tried inserting this code in the cart.php template:
if ( $_product->is_type( 'variation' ) ) {echo $_product->get_variation_description();}
By following this documentation https://docs.woocommerce.com/document/template-structure/
But it's still not showing up.
Not sure what I'm doing wrong here.
Can anyone help on this?
Updated for WooCommerce version 3 and above
Since WooCommerce 3, get_variation_description() is now deprecated and replaced by get_description() WC_Product method.
To get your product item variation description (filtering variation product type condition), you can use the following hooked function instead:
// Cart page (and mini cart)
add_filter( 'woocommerce_cart_item_name', 'cart_item_product_description', 20, 3);
function cart_item_product_description( $item_name, $cart_item, $cart_item_key ) {
if ( ! is_checkout() ) {
if( $cart_item['variation_id'] > 0 ) {
$description = $cart_item['data']->get_description(); // variation description
} else {
$description = $cart_item['data']->get_short_description(); // product short description (for others)
}
if ( ! empty($description) ) {
return $item_name . '<br><div class="description">
<strong>' . __( 'Description', 'woocommerce' ) . '</strong>: '. $description . '
</div>';
}
}
return $item_name;
}
// Checkout page
add_filter( 'woocommerce_checkout_cart_item_quantity', 'cart_item_checkout_product_description', 20, 3);
function cart_item_checkout_product_description( $item_quantity, $cart_item, $cart_item_key ) {
if( $cart_item['variation_id'] > 0 ) {
$description = $cart_item['data']->get_description(); // variation description
} else {
$description = $cart_item['data']->get_short_description(); // product short description (for others)
}
if ( ! empty($description) ) {
return $item_quantity . '<br><div class="description">
<strong>' . __( 'Description', 'woocommerce' ) . '</strong>: '. $description . '
</div>';
}
return $item_quantity;
}
Now the description is just displayed between the title and the variation attributes values (if there is any).
Code goes in functions.php file of the active child theme (or active theme). Tested and works.
This will work for WC 3.0
add_filter( 'woocommerce_cart_item_name', 'cart_variation_description', 20, 3);
function cart_variation_description( $title, $cart_item, $cart_item_key ) {
$item = $cart_item['data'];
if(!empty($item) && $item->is_type( 'variation' ) ) {
return $item->get_name();
} else
return $title;
}
You can get it via global variable $woocommerce also-
global $woocommerce;
$cart_data = $woocommerce->cart->get_cart();
foreach ($cart_data as $value) {
$_product = $value['data'];
if( $_product->is_type( 'variation' ) ){
echo $_product->id . '<br>';
}
}
I already check it.

Categories