Implement Phase 2: product archive and shop loop templates (Bootstrap 5)

Add 15 Twig template overrides for the product archive and shop loop:
- archive-product: 3+9 grid layout with optional filter sidebar
- content-product: card component with hook-based content injection
- content-product-cat: category card with thumbnail
- product-searchform: input-group with search icon button
- loop/loop-start, loop-end: responsive row-cols grid
- loop/header: archive title with description hook
- loop/result-count: showing X-Y of Z with aria-relevant
- loop/orderby: form-select-sm sort dropdown
- loop/pagination: delegates to components/pagination.html.twig
- loop/no-products-found: alert-info empty state
- loop/add-to-cart: btn-primary-sm with AJAX data attributes
- loop/price: fw-semibold with sale/regular markup
- loop/rating: Bootstrap Icon stars (full, half, empty)
- loop/sale-flash: badge bg-danger positioned overlay

CSS additions: product card hover, sale badge z-index, star rating sizing,
price del/ins styling, WooCommerce grid reset.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-28 10:23:09 +01:00
parent 01b807a769
commit c9c99a6b88
17 changed files with 551 additions and 15 deletions

View File

@@ -0,0 +1,47 @@
{#
# Loop Add to Cart Button (Bootstrap 5 Override)
#
# Renders the add-to-cart button within the product loop.
#
# Expected context:
# product - WC_Product object with:
# .add_to_cart_url() - Add to cart URL
# .add_to_cart_text() - Button label
# .is_purchasable() - Whether product can be purchased
# .is_in_stock() - Whether product is in stock
# .supports('ajax_add_to_cart') - Whether AJAX add to cart is supported
# .get_id() - Product ID
# args - Array with:
# .quantity - Quantity (default: 1)
# .class - CSS classes
# .attributes - Additional HTML attributes
# .aria-describedby_text - Accessibility description
#
# WooCommerce PHP equivalent: loop/add-to-cart.php
#
# @package WcBootstrap
# @since 0.1.0
#}
{% set quantity = args.quantity|default(1) %}
{% set btn_class = 'btn btn-primary btn-sm w-100' %}
<a href="{{ product.add_to_cart_url()|esc_url }}"
class="{{ btn_class }} {{ args.class|default('') }}"
data-quantity="{{ quantity }}"
data-product_id="{{ product.get_id() }}"
{% if args.attributes is defined %}
{% for attr, value in args.attributes %}
{{ attr }}="{{ value|esc_attr }}"
{% endfor %}
{% endif %}
aria-label="{{ product.add_to_cart_text()|esc_attr }}"
rel="nofollow">
{{ product.add_to_cart_text() }}
</a>
{% if args['aria-describedby_text'] is defined and args['aria-describedby_text'] %}
<span id="woocommerce_loop_add_to_cart_link_describedby_{{ product.get_id() }}" class="visually-hidden">
{{ args['aria-describedby_text'] }}
</span>
{% endif %}