-
+ {% for notice in notices %}
+
- + {{ notice.notice|raw }} + + {% endfor %} +
diff --git a/PLAN.md b/PLAN.md index 7b6c4bb..e1f3bbe 100644 --- a/PLAN.md +++ b/PLAN.md @@ -519,15 +519,15 @@ Track completion per file. Mark with `[x]` when done. ### Phase 1 -- Global & Notices -- [ ] `global/wrapper-start.html.twig` -- [ ] `global/wrapper-end.html.twig` -- [ ] `global/breadcrumb.html.twig` -- [ ] `global/sidebar.html.twig` -- [ ] `global/quantity-input.html.twig` -- [ ] `global/form-login.html.twig` -- [ ] `notices/notice.html.twig` -- [ ] `notices/error.html.twig` -- [ ] `notices/success.html.twig` +- [x] `global/wrapper-start.html.twig` +- [x] `global/wrapper-end.html.twig` +- [x] `global/breadcrumb.html.twig` +- [x] `global/sidebar.html.twig` +- [x] `global/quantity-input.html.twig` +- [x] `global/form-login.html.twig` +- [x] `notices/notice.html.twig` +- [x] `notices/error.html.twig` +- [x] `notices/success.html.twig` ### Phase 2 -- Archive & Loop diff --git a/assets/css/wc-bootstrap.css b/assets/css/wc-bootstrap.css index b1b736c..c212373 100644 --- a/assets/css/wc-bootstrap.css +++ b/assets/css/wc-bootstrap.css @@ -37,19 +37,56 @@ */ /* ========================================================================== - Notification Overrides - Map plugin notification classes to Bootstrap alert styles. + WooCommerce Notice Overrides + Map WooCommerce notice classes to Bootstrap alert styles as fallback + when notices are rendered outside our Twig templates. ========================================================================== */ -/* Example: Map plugin .my-notification to Bootstrap alert -.my-notification { +.woocommerce-info, +.woocommerce-message, +.woocommerce-error { position: relative; - padding: 1rem 1rem; + padding: 1rem 3rem 1rem 1rem; margin-bottom: 1rem; border: 1px solid transparent; border-radius: var(--bs-border-radius); } -*/ + +.woocommerce-info { + color: var(--bs-info-text-emphasis); + background-color: var(--bs-info-bg-subtle); + border-color: var(--bs-info-border-subtle); +} + +.woocommerce-message { + color: var(--bs-success-text-emphasis); + background-color: var(--bs-success-bg-subtle); + border-color: var(--bs-success-border-subtle); +} + +.woocommerce-error { + color: var(--bs-danger-text-emphasis); + background-color: var(--bs-danger-bg-subtle); + border-color: var(--bs-danger-border-subtle); + list-style: none; + padding-left: 1rem; +} + +/* ========================================================================== + Quantity Input + Sizing for the Bootstrap input-group quantity widget. + ========================================================================== */ + +.quantity.input-group .form-control { + /* Remove number input spinners (browser default) */ + -moz-appearance: textfield; +} + +.quantity.input-group .form-control::-webkit-outer-spin-button, +.quantity.input-group .form-control::-webkit-inner-spin-button { + -webkit-appearance: none; + margin: 0; +} /* ========================================================================== Dark Mode Overrides diff --git a/assets/js/quantity.js b/assets/js/quantity.js new file mode 100644 index 0000000..e0c3378 --- /dev/null +++ b/assets/js/quantity.js @@ -0,0 +1,39 @@ +/** + * Quantity Input +/- Button Handler + * + * Handles increment/decrement for Bootstrap 5 quantity input groups. + * Respects min, max, and step attributes on the input element. + * Triggers 'change' event so WooCommerce JS picks up the new value. + * + * @package WcBootstrap + * @since 0.1.0 + */ +(function () { + 'use strict'; + + function handleQuantityClick(e) { + var button = e.target.closest('.wc-qty-minus, .wc-qty-plus'); + if (!button) return; + + var target = button.getAttribute('data-target'); + var input = target ? document.querySelector(target) : button.closest('.quantity').querySelector('input'); + if (!input) return; + + var currentVal = parseFloat(input.value) || 0; + var min = parseFloat(input.getAttribute('min')) || 0; + var max = parseFloat(input.getAttribute('max')) || Infinity; + var step = parseFloat(input.getAttribute('step')) || 1; + + if (button.classList.contains('wc-qty-minus')) { + var newVal = currentVal - step; + input.value = newVal >= min ? newVal : min; + } else { + var newVal = currentVal + step; + input.value = max !== Infinity && newVal > max ? max : newVal; + } + + input.dispatchEvent(new Event('change', { bubbles: true })); + } + + document.addEventListener('click', handleQuantityClick); +})(); diff --git a/functions.php b/functions.php index 0bcd880..51ef884 100644 --- a/functions.php +++ b/functions.php @@ -94,6 +94,25 @@ function wc_bootstrap_enqueue_styles(): void { } add_action( 'wp_enqueue_scripts', 'wc_bootstrap_enqueue_styles' ); +/** + * Enqueue child theme scripts. + * + * @since 0.1.0 + */ +function wc_bootstrap_enqueue_scripts(): void { + $theme_version = wp_get_theme()->get( 'Version' ); + + // Quantity +/- button handler for Bootstrap input-group widget. + wp_enqueue_script( + 'wc-bootstrap-quantity', + get_stylesheet_directory_uri() . '/assets/js/quantity.js', + array(), + $theme_version, + true + ); +} +add_action( 'wp_enqueue_scripts', 'wc_bootstrap_enqueue_scripts' ); + /** * Handle plugin page rendering via plugin render filter. * diff --git a/style.css b/style.css index 066caac..c1d1b9d 100644 --- a/style.css +++ b/style.css @@ -1,6 +1,6 @@ /* Theme Name: WooCommerce Bootstrap -Theme URI: ssh://git@src.bundespruefstelle.ch:2022/magdev/wc-bootstrap.git +Theme URI: https://src.bundespruefstelle.ch:2022/magdev/wc-bootstrap Author: Marco Grätsch Author URI: https://src.bundespruefstelle.ch/magdev Description: A Bootstrap 5 child theme for WP Bootstrap that overrides all WooCommerce plugin templates with modern, responsive Bootstrap 5 markup and styling. diff --git a/templates/global/breadcrumb.html.twig b/templates/global/breadcrumb.html.twig new file mode 100644 index 0000000..56d004f --- /dev/null +++ b/templates/global/breadcrumb.html.twig @@ -0,0 +1,37 @@ +{# + # Shop Breadcrumb (Bootstrap 5 Override) + # + # Replaces WooCommerce's breadcrumb with Bootstrap 5 breadcrumb component. + # Skipped when parent theme is wrapping (base.html.twig handles breadcrumbs). + # + # Expected context (from WooCommerce woocommerce_breadcrumb()): + # breadcrumb - Array of [label, url] tuples + # wrap_before - Opening HTML (ignored, we use Bootstrap markup) + # wrap_after - Closing HTML (ignored) + # before - Before each item (ignored) + # after - After each item (ignored) + # delimiter - Between items (ignored, Bootstrap uses CSS) + # + # WooCommerce PHP equivalent: global/breadcrumb.php + # + # @package WcBootstrap + # @since 0.1.0 + #} + +{% if breadcrumb is defined and breadcrumb|length > 0 %} + +{% endif %} diff --git a/templates/global/form-login.html.twig b/templates/global/form-login.html.twig new file mode 100644 index 0000000..159f533 --- /dev/null +++ b/templates/global/form-login.html.twig @@ -0,0 +1,89 @@ +{# + # Global Login Form (Bootstrap 5 Override) + # + # Inline login form used on checkout and other pages (not the My Account login). + # Can be initially hidden and toggled via a link. + # + # Expected context (from WooCommerce wc_get_template('global/form-login.php')): + # hidden - Whether form is initially hidden (boolean) + # message - Optional message to display above the form + # redirect - URL to redirect after login + # + # WooCommerce PHP equivalent: global/form-login.php + # + # @package WcBootstrap + # @since 0.1.0 + #} + +{% if not is_user_logged_in() %} +
+{% endif %} diff --git a/templates/global/quantity-input.html.twig b/templates/global/quantity-input.html.twig new file mode 100644 index 0000000..5f59874 --- /dev/null +++ b/templates/global/quantity-input.html.twig @@ -0,0 +1,74 @@ +{# + # Quantity Input (Bootstrap 5 Override) + # + # Replaces WooCommerce's quantity input with a Bootstrap 5 input-group + # featuring decrement/increment buttons. + # + # Expected context (from WooCommerce woocommerce_quantity_input()): + # input_id - Input element ID + # input_name - Input element name attribute + # input_value - Current quantity value + # min_value - Minimum allowed quantity + # max_value - Maximum allowed quantity (0 = no max) + # step - Step increment + # placeholder - Placeholder text + # inputmode - Input mode (e.g., 'numeric') + # classes - CSS class(es) for the input + # readonly - Whether input is read-only + # type - Input type attribute + # args - Additional args (product_name for accessible label) + # autocomplete - Autocomplete attribute value + # + # WooCommerce PHP equivalent: global/quantity-input.php + # + # @package WcBootstrap + # @since 0.1.0 + #} + +{% set label = args.product_name is defined and args.product_name + ? __('%s quantity')|format(args.product_name) + : __('Quantity') +%} + +