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