WooCommerce display price on add to cart button - php

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.

Related

Woo-commerce - Add To Cart loop - How to add html to button

The Woocommerce template add-to-cart.php contains this code:
echo apply_filters( 'woocommerce_loop_add_to_cart_link', // WPCS: XSS ok.
sprintf( '<a href="%s" data-quantity="%s" class="%s" %s>%s</a>',
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'] ) : '',
esc_html( $product->add_to_cart_text() )
),
$product, $args );
I need to add this markup to the tag
<div class="icw"><i class="a3"></i></div>
I tried adding it directly but the new element was added after the actual link.
This is what I tried;
sprintf( '<i class="a3"></i></div>%s',
Can anyone explain to me how I go about adding this element?
Many thanks.
Read this before you continue
Is putting a div inside an anchor ever correct?
https://github.com/woocommerce/woocommerce/blob/3.8.0/templates/loop/add-to-cart.php
This template can be overridden by copying it to
yourtheme/woocommerce/loop/add-to-cart.php.
This seems to work without problems
echo apply_filters(
'woocommerce_loop_add_to_cart_link', // WPCS: XSS ok.
sprintf(
'</i>%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'] ) : '',
esc_html( $product->add_to_cart_text() )
),
$product,
$args
);

Move "Add to Cart" button and variation dropdown bellow price

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. :)

How does woocommerce_loop_add_to_cart_link filter hook work in depth?

I have some basic Woocommerce questions and cannot find anywhere online.
from the code below, where are $args come from?
how $product and $args assign to %s ?
thanks!
global $product;
echo apply_filters( 'woocommerce_loop_add_to_cart_link', // WPCS: XSS ok.
sprintf( '<a href="%s" data-quantity="%s" class="%s" %s>%s</a>',
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'] ) : '',
esc_html( $product->add_to_cart_text() )
),
$product, $args );
1) Explanations for $args variable in template file loop/add_to_cart.php:
The code in your question come from the template file loop/add_to_cart.php.
It is called by content-product.php template file on woocommerce_after_shop_loop_item hook:
/**
* Hook: woocommerce_after_shop_loop_item.
*
* #hooked woocommerce_template_loop_product_link_close - 5
* #hooked woocommerce_template_loop_add_to_cart - 10
*/
do_action( 'woocommerce_after_shop_loop_item' );
As you can see the template function woocommerce_template_loop_add_to_cart() does this job and it is located in WooCommerce plugin under includes/wc-template-functions.php.
So the default arguments are:
$defaults = array(
'quantity' => 1,
'class' => 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' ) && $product->is_purchasable() && $product->is_in_stock() ? 'ajax_add_to_cart' : '',
)
)
),
'attributes' => array(
'data-product_id' => $product->get_id(),
'data-product_sku' => $product->get_sku(),
'aria-label' => $product->add_to_cart_description(),
'rel' => 'nofollow',
),
);
They are parsed through the filter hook woocommerce_loop_add_to_cart_args:
$args = apply_filters( 'woocommerce_loop_add_to_cart_args', wp_parse_args( $args, $defaults ), $product );
… allowing to make changes on this arguments.
The $args variable in woocommerce_loop_add_to_cart_link is made of that.
2) How $product and $args are assigned to %s:
This is specific to PHP printf() and sprintf() function where each %s are a placeholder.
In '<a href="%s" data-quantity="%s" class="%s" %s>%s</a>':
the 1st placeholder %s will be replaced by esc_url( $product->add_to_cart_url() )
the 2nd placeholder %s by esc_attr( isset( $args['quantity'] ) ? $args['quantity'] : 1 )
and so on…
Documentation for printf() and sprintf() php functions.
Here is my way of actually changing the $args:
add_filter( 'woocommerce_loop_add_to_cart_args', 'filter_woocommerce_loop_add_to_cart_args', 10, 2 );
function filter_woocommerce_loop_add_to_cart_args( $args, $product ) {
$args['quantity'] = 6;
return $args;
}

Woocommerce Add to cart link Ajax enabled in other post or pages

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(); ?>

Woocommerce: Stop Add to Cart jumping to top when quantity added

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?

Categories