I have created a shortcode to display products of a specific product category (combined with a few ACF fields). All works great so use the code below for you own benefit.
The shortcode looks like this: [yl_get_products cat_id='51' order='ASC' template='1'] As you can see I've added template='1' so you can add a new layout later if you prefer.
Oke, so what's my problem: When I want to add the ADD-TO-CART button (together with my product add-ons) I need something like:
do_action( 'woocommerce_' . $product->get_type() . '_add_to_cart' ); within my shortcode.
or
do_action( 'woocommerce_single_product_summary' ); (and then remove all the not needed actions)
The result is that it indeed shows the whole add-to-cart output with add-on options etc. but it always displays on top of the page (in stead of the modal) and also any page styling is completely ignored.
I believe I have had this before and I thought it had to do something with echo return return = return .= but I can't get it right.
So my actual question is:
How can I add one to the actions above in my product loop shortcode without messing up the layout?
Here's my code:
// Get a dish category via shortcode
function yl_get_products_shortcode( $atts ) {
$atts = shortcode_atts( array(
'cat_id' => '',
'orderby' => '',
'order' => '',
'template' => '',
), $atts );
$products = new WP_Query(array(
'post_type' => 'product',
'tax_query' => array( array(
'taxonomy' => 'product_cat',
'field' => 'term_id',
'terms' => $atts['cat_id'],
// 'include_children' => false // or true (optional)
)),
'orderby' => $atts['orderby'],
'order' => $atts['order'],
'post_status' => 'publish',
'posts_per_page' => -1
));
if ( $products->have_posts() ) {
while ( $products->have_posts() ) {
$products->the_post();
if ($atts['template'] == '1') {
global $product;
$id = get_the_ID();
$product = wc_get_product( $id );
$name = $product->get_title();
$short_description = $product->get_short_description();
$description = $product->get_description();
$rating_count = $product->get_rating_count();
$rating_average = number_format($product->get_average_rating() * 20, 0) . '%';
$review_count = $product->get_review_count();
$price = $product->get_price();
$image_url = wp_get_attachment_url( $product->get_image_id() );
$description_nl = get_field('description_nl');
$title_en = get_field('title_en');
$description_en = get_field('description_en');
$allergens = get_field('allergens');
$specifics = get_field('specifics');
$output .= '
<li>
<div class="uk-grid-small" uk-grid>';
if ($product->is_in_stock()) {
$output .= '
<div class="uk-width-auto">
<a href="#product-' . $id . '" class="uk-button uk-button-small uk-button-primary" uk-toggle>
<span uk-icon="icon: cart"></span>
</a>
</div>';
}
if (!empty($allergens)) {
$output .= '
<div class="uk-width-auto">
<a href="#allergens-' . $id . '" uk-toggle>
<span uk-icon="icon: info"></span>
</a>
</div>';
}
$output .= '
<div class="uk-width-expand">
<p class="uk-h6 uk-margin-remove">
' . $name;
if (!empty($specifics)) {
foreach ($specifics as $specific) {
$output .= '
<img src="/wp-content/uploads/network/images/food-icons/icon-' . str_replace(' ', '-', $specific) . '.svg" width="16" uk-tooltip="' . $specific . '">';
}
}
$output .= '
</p>
<p class="uk-margin-remove">
' . $description_nl;
if ($short_description) {
$output .= '<br />' . $short_description;
}
$output .= '
</p>
</div>
<div class="uk-width-auto uk-h6">
€ ' . $price . '
</div>
</div>';
if (!empty($allergens) || !empty($specifics)) {
$output .= '
<div id="allergens-' . $id . '" uk-modal="center: true">
<div class="uk-modal-dialog uk-modal-body">
<button class="uk-modal-close-default" type="button" uk-close></button>
<h3 class="uk-modal-title uk-margin-small uk-text-truncate">
' . $name;
if (!empty($specifics)) {
foreach ($specifics as $specific) {
$output .= '
<img src="/wp-content/uploads/network/images/food-icons/icon-' . str_replace(' ', '-', $specific) . '.svg" width="16" uk-tooltip="' . $specific . '">';
}
}
$output .= '
</h3>
<p class="uk-margin-small">' . __( 'Below you will find an overview of the allergens that are in this dish. For more information you can always contact our service staff.', 'yorlinq' ) . '</p>
<div uk-alert>
<div class="uk-grid-small uk-child-width-1-2@s" uk-grid>';
foreach ($allergens as $allergen) {
$output .= '
<div>
<div class="uk-grid-small uk-flex-middle" uk-grid>
<div class="uk-width-1-4">
<img src="/wp-content/uploads/network/images/food-icons/icon-' . str_replace(' ', '-', $allergen) . '.svg">
</div>
<div class="uk-width-3-4">
' . $allergen . '
</div>
</div>
</div>';
}
$output .= '
</div>
</div>
</div>
</div>';
}
if ($product->is_in_stock()) {
$output .= '
<div id="product-' . $id . '" uk-modal="center: true">
<div class="uk-modal-dialog uk-modal-body">
<button class="uk-modal-close-default" type="button" uk-close></button>
<h3 class="uk-modal-title uk-margin-small uk-text-truncate">
' . $name;
if (!empty($specifics)) {
foreach ($specifics as $specific) {
$output .= '
<img src="/wp-content/uploads/network/images/food-icons/icon-' . str_replace(' ', '-', $specific) . '.svg" width="16" uk-tooltip="' . $specific . '">';
}
}
$output .= '
</h3>
' . $description;
// Here is where the action sould appear
$output .= '
</div>
</div>';
}
$output .= '
</li>';
}
};
return '<ul class="uk-list uk-list-divider">' . $output . '</ul>';
}
}
add_shortcode('yl_get_products','yl_get_products_shortcode');