I have one problem with my Woo Store that cant resolve myself. I want to move add to cart button and variation selector just bellow product price. I tryed almost all codes that found into stackoverflow (new and oldest ones) but dont make change nothing of that. When insert this code:
add_action( 'woocommerce_before_variations_form',
'second_button_single_variation', 30 );
function second_button_single_variation() {
global $product;
echo '<br>
<button type="submit" class="single_add_to_cart_button button alt">'.
esc_html( $product->single_add_to_cart_text() ).'</button>';}
It add Just Add to Cart button, but not on place that i wanted. I followed BBlomer manual for single product page, but dont make change any of that codes / hooks i found there. Any help here? To show just where want to put add to cart.
EDIT: I found this code that print button where i need:
echo apply_filters( 'woocommerce_loop_add_to_cart_link',
sprintf( '<a href="%s" rel="nofollow" data-product_id="%s" data-
product_sku="%s" class="button %s product_type_%s">%s</a>',
esc_url( $product->add_to_cart_url() ),
esc_attr( $product->id ),
esc_attr( $product->get_sku() ),
$product->is_purchasable() ? 'add_to_cart_button' : '',
esc_attr( $product->product_type ),
esc_html( $product->add_to_cart_text() )
),
$product );
?>
but print me button for Variation Options, but wihtout dropdown selector.
Check this action hook in a WooCommerce core
add_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_price', 10 );
To get your requirement, You need to remove this hook and add hook again somewhat like this in your functions.php .
remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_price', 10 );
add_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_price_callback', 10 );
function woocommerce_template_single_price_callback(){
/*Play with Woocommerce Data Here*/
echo 'PRice';
echo 'Button';
}
My working code:
<?php
/**
* Custom Loop Add to Cart.
*
* Template with quantity and ajax.
*/
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly.
global $product;
?>
<?php if ( ! $product->is_in_stock() ) : ?>
<?php echo apply_filters( 'out_of_stock_add_to_cart_text', __( 'Read More', 'woocommerce' ) ); ?>
<?php else : ?>
<?php
$link = array(
'url' => '',
'label' => '',
'class' => ''
);
switch ( $product->product_type ) {
case "variable" :
$link = apply_filters( 'variable_add_to_cart_url', get_permalink( $product->id ) );
$label = woocommerce_variable_add_to_cart();
break;
case "grouped" :
$link['url'] = apply_filters( 'grouped_add_to_cart_url', get_permalink( $product->id ) );
$link['label'] = apply_filters( 'grouped_add_to_cart_text', __( 'View options', 'woocommerce' ) );
break;
case "external" :
$link['url'] = apply_filters( 'external_add_to_cart_url', get_permalink( $product->id ) );
$link['label'] = apply_filters( 'external_add_to_cart_text', __( 'Read More', 'woocommerce' ) );
break;
default :
if ( $product->is_purchasable() ) {
$link['url'] = apply_filters( 'add_to_cart_url', esc_url( $product->add_to_cart_url() ) );
$link['label'] = apply_filters( 'add_to_cart_text', __( 'Add to cart', 'woocommerce' ) );
$link['class'] = apply_filters( 'add_to_cart_class', 'add_to_cart_button' );
} else {
$link['url'] = apply_filters( 'not_purchasable_url', get_permalink( $product->id ) );
$link['label'] = apply_filters( 'not_purchasable_text', __( 'Read More', 'woocommerce' ) );
}
break;
}
?>
<?php endif; ?>
<!--end code -->
Many Thanks for all that tryed to help. :)
Related
In Woocommerce, I Would like co create add to cart link on a simple page of WordPress website (not product page).
So I have tried this code (Where 123 is the product ID):
Buy
I have enabled AJAX add to cart on archives pages Woocommerce option setting.
But It doesn't work and Ajax functionality is not enabled on my custom Add-to-cart link.
How to enable ajax add-to-cart on a custom link (in other pages than woocommerce ones)?
To enable ajax in a custom add to cart button, there is 3 ways at least:
A simple HTML Ajax add to cart link:
<a rel="nofollow" href="/?add-to-cart=37" data-quantity="1" data-product_id="123" data-product_sku="" class="add_to_cart_button ajax_add_to_cart">Add to cart</a>
Using Woocommerce existing [add_to_cart id='123'] shortcode (same usage than above)
The most customizable: A custom shortcode without price included (customizable button text, additional classes, quantity and many others possibilities)
if( ! function_exists('custom_ajax_add_to_cart_button') && class_exists('WooCommerce') ) {
function custom_ajax_add_to_cart_button( $atts ) {
// Shortcode attributes
$atts = shortcode_atts( array(
'id' => '0', // Product ID
'qty' => '1', // Product quantity
'text' => '', // Text of the button
'class' => '', // Additional classes
), $atts, 'ajax_add_to_cart' );
if( esc_attr( $atts['id'] ) == 0 ) return; // Exit when no Product ID
if( get_post_type( esc_attr( $atts['id'] ) ) != 'product' ) return; // Exit if not a Product
$product = wc_get_product( esc_attr( $atts['id'] ) );
if ( ! $product ) return; // Exit when if not a valid Product
$classes = implode( ' ', array_filter( array(
'button',
'product_type_' . $product->get_type(),
$product->is_purchasable() && $product->is_in_stock() ? 'add_to_cart_button' : '',
$product->supports( 'ajax_add_to_cart' ) ? 'ajax_add_to_cart' : '',
) ) ).' '.$atts['class'];
$add_to_cart_button = sprintf( '<a rel="nofollow" href="%s" %s %s %s class="%s">%s</a>',
esc_url( $product->add_to_cart_url() ),
'data-quantity="' . esc_attr( $atts['qty'] ) .'"',
'data-product_id="' . esc_attr( $atts['id'] ) .'"',
'data-product_sku="' . esc_attr( $product->get_sku() ) .'"',
esc_attr( isset( $classes ) ? $classes : 'button' ),
esc_html( empty( esc_attr( $atts['text'] ) ) ? $product->add_to_cart_text() : esc_attr( $atts['text'] ) )
);
return $add_to_cart_button;
}
add_shortcode('ajax_add_to_cart', 'custom_ajax_add_to_cart_button');
}
This code goes on function.php file of your active child theme (or theme). Tested and works.
USAGE:
In posts and pages text editor:
[ajax_add_to_cart id='123' text='Buy']
In PHP files or templates:
echo do_shortcode( "[ajax_add_to_cart id='123' text='Buy']" );
Inserted in HTML code on a php page:
<?php echo do_shortcode( "[ajax_add_to_cart id='123' text='Buy']" ); ?>
Hide Ajax "view cart"
For custom shortcode, to hide the Ajax "view cart" behavior, you can add in the code, before return $add_to_cart_button; the following:
$style = '<style>a.added_to_cart.wc-forward { display:none !important; }</style>';
$add_to_cart_button = $style . $add_to_cart_button ;
I suggest you to use the [add_to_cart] Shortcode.
Simplest usage with the default parameters:
[add_to_cart id="123" /]
Disables the default style and hides the price:
[add_to_cart id="123" style="" show_price="false" /]
See some sample output
I used this for my plugin and it is working fine:
function wsb_add_to_cart_button( ) {
global $product;
$classes = implode( ' ', array(
'button',
'product_type_' . $product->get_type(),
$product->is_purchasable() && $product->is_in_stock() ? 'add_to_cart_button' : '',
$product->supports( 'ajax_add_to_cart' ) ? 'ajax_add_to_cart' : '',
) );
return apply_filters( 'woocommerce_loop_add_to_cart_link',
sprintf( '%s',
esc_url( $product->add_to_cart_url() ),
esc_attr( $product->get_id() ),
esc_attr( $product->get_sku() ),
esc_attr( isset( $quantity ) ? $quantity : 1 ),
esc_attr( isset( $classes ) ? $classes : 'button' ),
esc_attr( $product->get_type() ),
esc_html( $product->add_to_cart_text() )
),
$product );
}
for showing button:
<?php echo wsb_add_to_cart_button(); ?>
I am using woocommerce and I would like to remove the hyperlinks to single product pages as i use a quickview feature instead, making content pop up in a lightbox and making single product pages unneeded.
However, the links that are generated in the cart and mini-cart link to the default product page so I would like to remove them.
What I want to do for the cart page: Remove the hyperlink to the single product page from the product thumbnail I am not a php expert per se, but made some progress following this post. It worked on my product title but it didn't work on my product thumbnail in the cart page.
Here is the snippet from my cart.php:
<td class="product-thumbnail">
<?php
$thumbnail = apply_filters( 'woocommerce_cart_item_thumbnail', $_product->get_image(), $cart_item, $cart_item_key );
if ( ! $product_permalink ) {
echo $thumbnail;
} else {
printf( '%s', $thumbnail );
}
?>
</td>
<td class="product-name" data-title="<?php _e( 'Product', 'woocommerce' ); ?>">
<?php
if ( ! $product_permalink ) {
echo apply_filters( 'woocommerce_cart_item_name', $_product->get_title(), $cart_item, $cart_item_key ) . ' ';
} else {
echo apply_filters( 'woocommerce_cart_item_name', sprintf( '%s', $_product->get_title() ) );
}
// Meta data
echo WC()->cart->get_item_data( $cart_item );
// Backorder notification
if ( $_product->backorders_require_notification() && $_product->is_on_backorder( $cart_item['quantity'] ) ) {
echo '<p class="backorder_notification">' . esc_html__( 'Available on backorder', 'woocommerce' ) . '</p>';
}
?>
</td>
What I want to do for the mini-cart: Remove the hyperlink to the single product page from the product thumbnail and product title
and the snippet from my mini-cart.php: (Full mini-cart.php code here)
<?php
foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
$_product = apply_filters( 'woocommerce_cart_item_product', $cart_item['data'], $cart_item, $cart_item_key );
$product_id = apply_filters( 'woocommerce_cart_item_product_id', $cart_item['product_id'], $cart_item, $cart_item_key );
if ( $_product && $_product->exists() && $cart_item['quantity'] > 0 && apply_filters( 'woocommerce_widget_cart_item_visible', true, $cart_item, $cart_item_key ) ) {
$product_name = apply_filters( 'woocommerce_cart_item_name', $_product->get_title(), $cart_item, $cart_item_key );
$thumbnail = apply_filters( 'woocommerce_cart_item_thumbnail', $_product->get_image(), $cart_item, $cart_item_key );
$product_price = apply_filters( 'woocommerce_cart_item_price', WC()->cart->get_product_price( $_product ), $cart_item, $cart_item_key );
?>
<li class="<?php echo esc_attr( apply_filters( 'woocommerce_mini_cart_item_class', 'mini_cart_item', $cart_item, $cart_item_key ) ); ?>">
<?php
echo apply_filters( 'woocommerce_cart_item_remove_link', sprintf(
'×',
esc_url( WC()->cart->get_remove_url( $cart_item_key ) ),
__( 'Remove this item', 'woocommerce' ),
esc_attr( $product_id ),
esc_attr( $_product->get_sku() )
), $cart_item_key );
?>
<?php if ( ! $_product->is_visible() ) : ?>
<?php echo str_replace( array( 'http:', 'https:' ), '', $thumbnail ) . $product_name . ' '; ?>
<?php else : ?>
<?php echo str_replace( array( 'http:', 'https:' ), '', $thumbnail ) . $product_name . ' '; ?>
</a>
<?php endif; ?>
<?php echo WC()->cart->get_item_data( $cart_item ); ?>
<?php echo apply_filters( 'woocommerce_widget_cart_item_quantity', '<span class="quantity">' . sprintf( '%s × %s', $cart_item['quantity'], $product_price ) . '</span>', $cart_item, $cart_item_key ); ?>
</li>
<?php
}
}
?>
Both product thumbnail and product title is still hyperlinked despite removing the <a href> tag.
Please help!!
screenshot of hyperlinked product title and thumbnail
For cart.php
You can change these two lines
replace
printf( '%s', esc_url( $product_permalink ), $thumbnail );
with
printf( '%s', $thumbnail );
and
echo apply_filters( 'woocommerce_cart_item_name', sprintf( '%s', esc_url( $product_permalink ), $_product->get_title() ), $cart_item, $cart_item_key );
with
echo apply_filters( 'woocommerce_cart_item_name', sprintf( '%s', $_product->get_title() ), $cart_item, $cart_item_key );
or you can use the filters to get the job done, if you are using a child theme in your child-theme/woocommerce/cart/cart.php make the changes .
In mini-cart.php
replace
<a href="<?php echo esc_url( $product_permalink ); ?>">
<?php echo str_replace( array( 'http:', 'https:' ), '', $thumbnail ) . $product_name . ' '; ?>
</a>
with
<?php echo str_replace( array( 'http:', 'https:' ), '', $thumbnail ) . $product_name . ' '; ?>
page should be at chil-theme/woocommerce/cart/mini-cart.php
The page link you have provided me is the order page, for which the page should be used is order-details-item.php
here you should replace
echo apply_filters( 'woocommerce_order_item_name', $product_permalink ? sprintf( '%s', $product_permalink, $item['name'] ) : $item['name'], $item, $is_visible );
with
echo apply_filters( 'woocommerce_order_item_name', $product_permalink ? sprintf( '%s', $item['name'] ) : $item['name'], $item, $is_visible );
let me know if you can share a screenshot of the page, that will be better if it wont work for you or you can allow me to create a fake order , so that I can check it.
if you are facing problem let me know.
I would like to know how can I add a simple quantity button to my WooCommerce shop products.
Here is how i modified my loop/add-to-cart.php to achieve this:
<?php
/**
* Loop Add to Cart
*
* #author WooThemes
* #package WooCommerce/Templates
* #version 1.6.4
*/
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
global $product;
?>
<?php if ( ! $product->is_in_stock() ) : ?>
<?php echo apply_filters( 'out_of_stock_add_to_cart_text', __( 'Read More', 'woocommerce' ) ); ?>
<?php else : ?>
<?php
$link = array(
'url' => '',
'label' => '',
'class' => ''
);
$handler = apply_filters( 'woocommerce_add_to_cart_handler', $product->product_type, $product );
switch ( $handler ) {
case "variable" :
$link['url'] = apply_filters( 'variable_add_to_cart_url', get_permalink( $product->id ) );
$link['label'] = apply_filters( 'variable_add_to_cart_text', __( 'Select options', 'woocommerce' ) );
break;
case "grouped" :
$link['url'] = apply_filters( 'grouped_add_to_cart_url', get_permalink( $product->id ) );
$link['label'] = apply_filters( 'grouped_add_to_cart_text', __( 'View options', 'woocommerce' ) );
break;
case "external" :
$link['url'] = apply_filters( 'external_add_to_cart_url', get_permalink( $product->id ) );
$link['label'] = apply_filters( 'external_add_to_cart_text', __( 'Read More', 'woocommerce' ) );
break;
default :
if ( $product->is_purchasable() ) {
$link['url'] = apply_filters( 'add_to_cart_url', esc_url( $product->add_to_cart_url() ) );
$link['label'] = apply_filters( 'add_to_cart_text', __( 'Add to cart', 'woocommerce' ) );
$link['class'] = apply_filters( 'add_to_cart_class', 'add_to_cart_button' );
} else {
$link['url'] = apply_filters( 'not_purchasable_url', get_permalink( $product->id ) );
$link['label'] = apply_filters( 'not_purchasable_text', __( 'Read More', 'woocommerce' ) );
}
break;
}
if ( $product->product_type == 'simple' ) {
?>
<form action="<?php echo esc_url( $product->add_to_cart_url() ); ?>" class="cart" method="post" enctype='multipart/form-data'>
<?php woocommerce_quantity_input(); ?>
<button type="submit" class="button alt"><?php echo $label; ?></button>
</form>
<?php
} else {
echo apply_filters( 'woocommerce_loop_add_to_cart_link', sprintf('%s', esc_url( $link['url'] ), esc_attr( $product->id ), esc_attr( $product->get_sku() ), esc_attr( $link['class'] ), esc_attr( $product->product_type ), esc_html( $link['label'] ) ), $product, $link );
}
?>
<?php endif; ?>
I'm trying to add the price to the add to cart button in the loop.
[100$ Add to cart] instead of [Add to cart]
add_to_cart.php template:
echo apply_filters( 'woocommerce_loop_add_to_cart_link',
sprintf( '%s',
esc_url( $product->add_to_cart_url() ),
esc_attr( $product->id ),
esc_attr( $product->get_sku() ),
$product->is_purchasable() && $product->is_in_stock() ? 'add_to_cart_button' : '',
esc_attr( $product->product_type ),
esc_html( $product->add_to_cart_text() )
),
$product );
price.php template:
<?php if ( $price_html = $product->get_price_html() ) : ?>
<span class="price"><?php echo $price_html; ?></span>
<?php endif; ?>
How do I combine these two? Couldn't find anything on the web.
This should work: modify the add_to_cart.php file to
echo apply_filters( 'woocommerce_loop_add_to_cart_link',
sprintf( '%s %s',
esc_url( $product->add_to_cart_url() ),
esc_attr( $product->id ),
esc_attr( $product->get_sku() ),
$product->is_purchasable() ? 'add_to_cart_button' : '',
esc_attr( $product->product_type ),
$product->get_price_html(),
esc_html( $product->add_to_cart_text() )
),
$product );
and the price will display in front of the "Add to cart" text.
EDIT: You should note that updating the woocommerce plugin will undo that and any other modification you have made to any of the files.
WooCommerce 3.1.0 updated the Functions for Add to Cart Button
apply_filters( 'woocommerce_loop_add_to_cart_link',
sprintf( '<li><a href="%s" rel="nofollow" data-product_id="%s"
data-product_sku="%s" class="btn-filled cart add-to-cart %s
product_type_%s"><i class="fa fa-shopping-cart" ></i></a></li>',
esc_url( $product->add_to_cart_url() ),
esc_attr( isset( $quantity ) ? $quantity : 1 ),
esc_attr( $product->get_id() ),
esc_attr( $product->get_sku() ),
esc_attr( isset( $class ) ? $class : 'button' ),
esc_html( $product->add_to_cart_text() )
),
$product );
If you want to be (somewhat) safe from a future Woocommerce upgrade, follow the official safe way to do it (thank you Felix).
Copy add-to-cart.php into a directory within your theme named /woocommerce keeping the same file structure but removing the /templates/ subdirectory.
Example: To override the admin order notification, copy: wp-content/plugins/woocommerce/templates/emails/admin-new-order.php to wp-content/themes/yourtheme/woocommerce/emails/admin-new-order.php
Here is the file updated for Woocommerce 3.3.0 :
<?php
/**
* Loop Add to Cart
*
* This template can be overridden by copying it to yourtheme/woocommerce/loop/add-to-cart.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* #see https://docs.woocommerce.com/document/template-structure/
* #author WooThemes
* #package WooCommerce/Templates
* #version 3.3.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
global $product;
echo apply_filters( 'woocommerce_loop_add_to_cart_link', // WPCS: XSS ok.
sprintf( '%s</span> <span style="color:#999;">|</span> %s',
esc_url( $product->add_to_cart_url() ),
esc_attr( isset( $args['quantity'] ) ? $args['quantity'] : 1 ),
esc_attr( isset( $args['class'] ) ? $args['class'] : 'button' ),
isset( $args['attributes'] ) ? wc_implode_html_attributes( $args['attributes'] ) : '',
$product->get_price_html(),
esc_html( $product->add_to_cart_text() )
),
$product, $args );
?>
Of course, styling the button or modificating its content is entirely up to you and isn't limited to show the product price.
I was having a problem with WooCommerce where the Ajax Add to Cart was only adding 1 despite multiple quantities being selected on Shop Archive Page.
I turned the Ajax off in the settings, and used this solution found on here. I replaced the wp-content/themes/your-theme/templates/loop/add-to-cart.php content with:
<?php
/**
* Custom Loop Add to Cart.
*
* Template with quantity and ajax.
*/
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly.
global $product;
?>
<?php if ( ! $product->is_in_stock() ) : ?>
<?php echo apply_filters( 'out_of_stock_add_to_cart_text', __( 'Read More', 'woocommerce' ) ); ?>
<?php else : ?>
<?php
$link = array(
'url' => '',
'label' => '',
'class' => ''
);
switch ( $product->product_type ) {
case "variable" :
$link['url'] = apply_filters( 'variable_add_to_cart_url', get_permalink( $product->id ) );
$link['label'] = apply_filters( 'variable_add_to_cart_text', __( 'Select options', 'woocommerce' ) );
break;
case "grouped" :
$link['url'] = apply_filters( 'grouped_add_to_cart_url', get_permalink( $product->id ) );
$link['label'] = apply_filters( 'grouped_add_to_cart_text', __( 'View options', 'woocommerce' ) );
break;
case "external" :
$link['url'] = apply_filters( 'external_add_to_cart_url', get_permalink( $product->id ) );
$link['label'] = apply_filters( 'external_add_to_cart_text', __( 'Read More', 'woocommerce' ) );
break;
default :
if ( $product->is_purchasable() ) {
$link['url'] = apply_filters( 'add_to_cart_url', esc_url( $product->add_to_cart_url() ) );
$link['label'] = apply_filters( 'add_to_cart_text', __( 'Add to cart', 'woocommerce' ) );
$link['class'] = apply_filters( 'add_to_cart_class', 'add_to_cart_button' );
} else {
$link['url'] = apply_filters( 'not_purchasable_url', get_permalink( $product->id ) );
$link['label'] = apply_filters( 'not_purchasable_text', __( 'Read More', 'woocommerce' ) );
}
break;
}
// If there is a simple product.
if ( $product->product_type == 'simple' ) {
?>
<form action="<?php echo esc_url( $product->add_to_cart_url() ); ?>" class="cart" method="post" enctype="multipart/form-data">
<?php
// Displays the quantity box.
woocommerce_quantity_input();
// Display the submit button.
echo sprintf( '<button type="submit" data-product_id="%s" data-product_sku="%s" data-quantity="1" class="%s button product_type_simple">%s</button>', esc_attr( $product->id ), esc_attr( $product->get_sku() ), esc_attr( $link['class'] ), esc_html( $link['label'] ) );
?>
</form>
<?php
} else {
echo apply_filters( 'woocommerce_loop_add_to_cart_link', sprintf('%s', esc_url( $link['url'] ), esc_attr( $product->id ), esc_attr( $product->get_sku() ), esc_attr( $link['class'] ), esc_attr( $product->product_type ), esc_html( $link['label'] ) ), $product, $link );
}
?>
<?php endif; ?>
And added this code to functions.php
function cs_wc_loop_add_to_cart_scripts() {
if ( is_shop() || is_product_category() || is_product_tag() || is_product() ) : ?>
<script>
jQuery(document).ready(function($) {
$(document).on( 'change', '.quantity .qty', function() {
$(this).parent('.quantity').next('.add_to_cart_button').attr('data-quantity', $(this).val());
});
});
</script>
<?php endif;
}
add_action( 'wp_footer', 'cs_wc_loop_add_to_cart_scripts' );
That fixes the issue with multiples being added, but now the shop returns to the top of the page to display the add to cart message when you add something to the basket. How can I keep it so that the navigation stays in the current location so the customer does not have to scroll down again?