Skip to content

Instantly share code, notes, and snippets.

@helgatheviking
Last active October 11, 2022 21:46
Show Gist options
  • Star 9 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save helgatheviking/5e3bdca9f6dc9d33a7248b2aacb1d6c3 to your computer and use it in GitHub Desktop.
Save helgatheviking/5e3bdca9f6dc9d33a7248b2aacb1d6c3 to your computer and use it in GitHub Desktop.
WooCommerce display a single product add to cart form with [add_to_cart_form]
/**
* NB: updated version available here: https://github.com/helgatheviking/add-to-cart-form-shortcode
*/
/**
* Add [add_to_cart_form] shortcode that display a single product add to cart form
* Supports id and sku attributes [add_to_cart_form id=99] or [add_to_cart_form sku=123ABC]
* Essentially a duplicate of the [product_page]
* but replacing wc_get_template_part( 'content', 'single-product' ); with woocommerce_template_single_add_to_cart()
*
* @param array $atts Attributes.
* @return string
*/
function kia_add_to_cart_form_shortcode( $atts ) {
if ( empty( $atts ) ) {
return '';
}
if ( ! isset( $atts['id'] ) && ! isset( $atts['sku'] ) ) {
return '';
}
$args = array(
'posts_per_page' => 1,
'post_type' => 'product',
'post_status' => 'publish',
'ignore_sticky_posts' => 1,
'no_found_rows' => 1,
);
if ( isset( $atts['sku'] ) ) {
$args['meta_query'][] = array(
'key' => '_sku',
'value' => sanitize_text_field( $atts['sku'] ),
'compare' => '=',
);
$args['post_type'] = array( 'product', 'product_variation' );
}
if ( isset( $atts['id'] ) ) {
$args['p'] = absint( $atts['id'] );
}
$single_product = new WP_Query( $args );
$preselected_id = '0';
// Check if sku is a variation.
if ( isset( $atts['sku'] ) && $single_product->have_posts() && 'product_variation' === $single_product->post->post_type ) {
$variation = new WC_Product_Variation( $single_product->post->ID );
$attributes = $variation->get_attributes();
// Set preselected id to be used by JS to provide context.
$preselected_id = $single_product->post->ID;
// Get the parent product object.
$args = array(
'posts_per_page' => 1,
'post_type' => 'product',
'post_status' => 'publish',
'ignore_sticky_posts' => 1,
'no_found_rows' => 1,
'p' => $single_product->post->post_parent,
);
$single_product = new WP_Query( $args );
?>
<script type="text/javascript">
jQuery( document ).ready( function( $ ) {
var $variations_form = $( '[data-product-page-preselected-id="<?php echo esc_attr( $preselected_id ); ?>"]' ).find( 'form.variations_form' );
<?php foreach ( $attributes as $attr => $value ) { ?>
$variations_form.find( 'select[name="<?php echo esc_attr( $attr ); ?>"]' ).val( '<?php echo esc_js( $value ); ?>' );
<?php } ?>
});
</script>
<?php
}
// For "is_single" to always make load comments_template() for reviews.
$single_product->is_single = true;
ob_start();
global $wp_query;
// Backup query object so following loops think this is a product page.
$previous_wp_query = $wp_query;
// @codingStandardsIgnoreStart
$wp_query = $single_product;
// @codingStandardsIgnoreEnd
wp_enqueue_script( 'wc-single-product' );
while ( $single_product->have_posts() ) {
$single_product->the_post()
?>
<div class="single-product" data-product-page-preselected-id="<?php echo esc_attr( $preselected_id ); ?>">
<?php woocommerce_template_single_add_to_cart(); ?>
</div>
<?php
}
// Restore $previous_wp_query and reset post data.
// @codingStandardsIgnoreStart
$wp_query = $previous_wp_query;
// @codingStandardsIgnoreEnd
wp_reset_postdata();
return '<div class="woocommerce">' . ob_get_clean() . '</div>';
}
add_shortcode( 'add_to_cart_form', 'kia_add_to_cart_form_shortcode' );
@helgatheviking
Copy link
Author

helgatheviking commented Apr 14, 2022

@jfheath better to use this version: https://github.com/helgatheviking/add-to-cart-form-shortcode
it's specifically this line: https://github.com/helgatheviking/add-to-cart-form-shortcode/blob/master/wc-add-to-cart-form-shortcode.php#L78 that is undoing the redirect. Perhaps we could make a shortcode attribute that will control that. I can be persuaded with pizza. :)

@jfheath
Copy link

jfheath commented Oct 11, 2022 via email

@helgatheviking
Copy link
Author

@jfheath I have added a parameter for that in the plugin. See version 3.0.2.

It would be used as [add_to_cart_form id="99" allow_form_action="true"]

If that has been helpful to you, please consider a donation to my sports team.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment