3,
'columns' => 3,
);
$args = wp_parse_args( $defaults, $args );
return $args;
}
add_filter( 'woocommerce_output_related_products_args', 'accepta_woocommerce_related_products_args' );
/**
* Product loop – Add to cart button over the image.
* Uses hooks to wrap the image area and move the button inside it for overlay positioning.
*/
remove_action( 'woocommerce_after_shop_loop_item', 'woocommerce_template_loop_product_link_close', 5 );
remove_action( 'woocommerce_after_shop_loop_item', 'woocommerce_template_loop_add_to_cart', 10 );
add_action( 'woocommerce_before_shop_loop_item', 'accepta_woocommerce_loop_image_wrap_open', 5 );
add_action( 'woocommerce_before_shop_loop_item_title', 'accepta_woocommerce_loop_image_wrap_close_and_add_to_cart', 15 );
remove_action( 'woocommerce_shop_loop_item_title', 'woocommerce_template_loop_product_title', 10 );
add_action( 'woocommerce_shop_loop_item_title', 'accepta_woocommerce_template_loop_product_title', 10 );
add_filter( 'woocommerce_loop_add_to_cart_args', 'accepta_woocommerce_loop_add_to_cart_args_overlay', 10, 2 );
if ( ! function_exists( 'accepta_woocommerce_loop_add_to_cart_args_overlay' ) ) {
/**
* Add class for overlay Add to cart (green background styling).
*
* @param array $args Button args.
* @param WC_Product $product Product object.
* @return array
*/
function accepta_woocommerce_loop_add_to_cart_args_overlay( $args, $product ) {
$args['class'] = ( isset( $args['class'] ) ? $args['class'] . ' ' : '' ) . 'add-to-cart-overlay';
return $args;
}
}
if ( ! function_exists( 'accepta_woocommerce_loop_image_wrap_open' ) ) {
/**
* Open wrapper around product image for Add to cart overlay.
*/
function accepta_woocommerce_loop_image_wrap_open() {
echo '
';
}
}
if ( ! function_exists( 'accepta_woocommerce_loop_image_wrap_close_and_add_to_cart' ) ) {
/**
* Close product link, output Add to cart inside image wrap, close wrapper.
*/
function accepta_woocommerce_loop_image_wrap_close_and_add_to_cart() {
woocommerce_template_loop_product_link_close();
woocommerce_template_loop_add_to_cart();
echo '
';
}
}
if ( ! function_exists( 'accepta_woocommerce_template_loop_product_title' ) ) {
/**
* Product title with link (needed because we close the product link early).
*/
function accepta_woocommerce_template_loop_product_title() {
$classes = apply_filters( 'woocommerce_product_loop_title_classes', 'woocommerce-loop-product__title' );
echo '';
echo '' . get_the_title() . ''; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
echo '
';
}
}
/**
* Remove default WooCommerce wrapper.
*/
remove_action( 'woocommerce_before_main_content', 'woocommerce_output_content_wrapper', 10 );
remove_action( 'woocommerce_after_main_content', 'woocommerce_output_content_wrapper_end', 10 );
if ( ! function_exists( 'accepta_woocommerce_wrapper_before' ) ) {
/**
* Before Content.
*
* Wraps all WooCommerce content in wrappers which match the theme markup.
*
* @return void
*/
function accepta_woocommerce_wrapper_before() {
?>
*/
if ( ! function_exists( 'accepta_woocommerce_cart_link_fragment' ) ) {
/**
* Cart Fragments.
*
* Ensure cart contents update when products are added to the cart via AJAX.
* Use a unique selector (a.header-cart-link) so only our header icon is updated;
* otherwise another callback can overwrite 'a.cart-contents' with text-style HTML
* and our icon is replaced and loses order/position (appears before logo then hidden).
*
* @param array $fragments Fragments to refresh via AJAX.
* @return array Fragments to refresh via AJAX.
*/
function accepta_woocommerce_cart_link_fragment( $fragments ) {
ob_start();
accepta_woocommerce_cart_link( true );
$html = ob_get_clean();
$fragments['a.header-cart-link.cart-contents'] = $html;
return $fragments;
}
}
add_filter( 'woocommerce_add_to_cart_fragments', 'accepta_woocommerce_cart_link_fragment', 20 );
if ( ! function_exists( 'accepta_woocommerce_cart_link' ) ) {
/**
* Cart Link.
*
* Display a link to the cart. When $icon_style is true, outputs icon + count to match header search/social style.
*
* @param bool $icon_style Whether to output the header icon style (circle, SVG, count).
* @return void
*/
function accepta_woocommerce_cart_link( $icon_style = false ) {
$cart_available = ( function_exists( 'WC' ) && WC() ) ? WC()->cart : null;
if ( ! $cart_available ) {
if ( $icon_style ) {
/* Always show icon in header (e.g. customizer or when cart not initialized). Opens offcanvas minicart. */
$title = __( 'View your shopping cart', 'accepta' );
?>
cart->get_cart_contents_count();
$title = __( 'View your shopping cart', 'accepta' );
if ( $icon_style ) {
/* Always show icon and count (0 when empty) so the cart is visible even with no products. */
?>
cart->get_cart_subtotal() ); ?>