You've already forked wc-bootstrap
Implement Phase 1: global templates and notices (Bootstrap 5)
Add 9 Twig template overrides for WooCommerce's global and notice templates: - global/wrapper-start, wrapper-end: conditional container with _theme_wrapped - global/breadcrumb: Bootstrap breadcrumb component with aria-current - global/sidebar: offcanvas-lg for mobile, standard aside for desktop - global/quantity-input: input-group with +/- buttons - global/form-login: responsive form with form-control, form-check - notices/notice, error, success: Bootstrap alert-dismissible with icons Supporting changes: - assets/js/quantity.js: +/- button handler respecting min/max/step - assets/css/wc-bootstrap.css: WooCommerce notice fallback styles, spinner removal - functions.php: register quantity.js script Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
18
PLAN.md
18
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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
39
assets/js/quantity.js
Normal file
39
assets/js/quantity.js
Normal file
@@ -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);
|
||||
})();
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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.
|
||||
|
||||
37
templates/global/breadcrumb.html.twig
Normal file
37
templates/global/breadcrumb.html.twig
Normal file
@@ -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 %}
|
||||
<nav aria-label="{{ __('Breadcrumb') }}">
|
||||
<ol class="breadcrumb">
|
||||
{% for crumb in breadcrumb %}
|
||||
{% if not loop.last and crumb[1] is defined and crumb[1] %}
|
||||
<li class="breadcrumb-item">
|
||||
<a href="{{ crumb[1]|esc_url }}">{{ crumb[0]|esc_html }}</a>
|
||||
</li>
|
||||
{% else %}
|
||||
<li class="breadcrumb-item active" aria-current="page">
|
||||
{{ crumb[0]|esc_html }}
|
||||
</li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</ol>
|
||||
</nav>
|
||||
{% endif %}
|
||||
89
templates/global/form-login.html.twig
Normal file
89
templates/global/form-login.html.twig
Normal file
@@ -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() %}
|
||||
<form class="woocommerce-form woocommerce-form-login login{% if hidden %} d-none{% endif %}" method="post">
|
||||
|
||||
{{ do_action('woocommerce_login_form_start') }}
|
||||
|
||||
{% if message %}
|
||||
<div class="mb-3">
|
||||
{{ message|wpautop }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="row g-3 mb-3">
|
||||
<div class="col-sm-6">
|
||||
<label for="username" class="form-label">
|
||||
{{ __('Username or email') }} <span class="text-danger" aria-hidden="true">*</span>
|
||||
<span class="visually-hidden">{{ __('Required') }}</span>
|
||||
</label>
|
||||
<input type="text"
|
||||
class="form-control"
|
||||
name="username"
|
||||
id="username"
|
||||
autocomplete="username"
|
||||
required
|
||||
aria-required="true" />
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<label for="password" class="form-label">
|
||||
{{ __('Password') }} <span class="text-danger" aria-hidden="true">*</span>
|
||||
<span class="visually-hidden">{{ __('Required') }}</span>
|
||||
</label>
|
||||
<input type="password"
|
||||
class="form-control"
|
||||
name="password"
|
||||
id="password"
|
||||
autocomplete="current-password"
|
||||
required
|
||||
aria-required="true" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{ do_action('woocommerce_login_form') }}
|
||||
|
||||
<div class="d-flex align-items-center justify-content-between flex-wrap gap-2">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input"
|
||||
type="checkbox"
|
||||
name="rememberme"
|
||||
id="rememberme"
|
||||
value="forever" />
|
||||
<label class="form-check-label" for="rememberme">
|
||||
{{ __('Remember me') }}
|
||||
</label>
|
||||
</div>
|
||||
|
||||
{{ wp_nonce_field('woocommerce-login', 'woocommerce-login-nonce') }}
|
||||
<input type="hidden" name="redirect" value="{{ redirect|esc_url }}" />
|
||||
|
||||
<button type="submit"
|
||||
class="btn btn-primary"
|
||||
name="login"
|
||||
value="{{ __('Login') }}">
|
||||
{{ __('Login') }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<p class="mt-3 mb-0">
|
||||
<a href="{{ wp_lostpassword_url()|esc_url }}">{{ __('Lost your password?') }}</a>
|
||||
</p>
|
||||
|
||||
{{ do_action('woocommerce_login_form_end') }}
|
||||
</form>
|
||||
{% endif %}
|
||||
74
templates/global/quantity-input.html.twig
Normal file
74
templates/global/quantity-input.html.twig
Normal file
@@ -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')
|
||||
%}
|
||||
|
||||
<div class="quantity input-group input-group-sm" style="max-width: 140px;">
|
||||
{{ do_action('woocommerce_before_quantity_input_field') }}
|
||||
|
||||
<label class="visually-hidden" for="{{ input_id|esc_attr }}">{{ label|esc_attr }}</label>
|
||||
|
||||
{% if not readonly %}
|
||||
<button type="button"
|
||||
class="btn btn-outline-secondary wc-qty-minus"
|
||||
aria-label="{{ __('Decrease quantity') }}"
|
||||
data-target="#{{ input_id|esc_attr }}">
|
||||
<i class="bi bi-dash" aria-hidden="true"></i>
|
||||
</button>
|
||||
{% endif %}
|
||||
|
||||
<input type="{{ type|default('number')|esc_attr }}"
|
||||
{% if readonly %}readonly="readonly"{% endif %}
|
||||
id="{{ input_id|esc_attr }}"
|
||||
class="form-control text-center {{ classes is iterable ? classes|join(' ')|esc_attr : classes|default('')|esc_attr }}"
|
||||
name="{{ input_name|esc_attr }}"
|
||||
value="{{ input_value|esc_attr }}"
|
||||
aria-label="{{ __('Product quantity')|esc_attr }}"
|
||||
min="{{ min_value|esc_attr }}"
|
||||
{% if max_value is defined and max_value > 0 %}max="{{ max_value|esc_attr }}"{% endif %}
|
||||
{% if not readonly %}
|
||||
step="{{ step|esc_attr }}"
|
||||
placeholder="{{ placeholder|esc_attr }}"
|
||||
inputmode="{{ inputmode|default('numeric')|esc_attr }}"
|
||||
autocomplete="{{ autocomplete|default('on')|esc_attr }}"
|
||||
{% endif %}
|
||||
/>
|
||||
|
||||
{% if not readonly %}
|
||||
<button type="button"
|
||||
class="btn btn-outline-secondary wc-qty-plus"
|
||||
aria-label="{{ __('Increase quantity') }}"
|
||||
data-target="#{{ input_id|esc_attr }}">
|
||||
<i class="bi bi-plus" aria-hidden="true"></i>
|
||||
</button>
|
||||
{% endif %}
|
||||
|
||||
{{ do_action('woocommerce_after_quantity_input_field') }}
|
||||
</div>
|
||||
40
templates/global/sidebar.html.twig
Normal file
40
templates/global/sidebar.html.twig
Normal file
@@ -0,0 +1,40 @@
|
||||
{#
|
||||
# Shop Sidebar (Bootstrap 5 Override)
|
||||
#
|
||||
# Renders the WooCommerce shop sidebar using Bootstrap 5 offcanvas for mobile
|
||||
# and a standard aside column for desktop.
|
||||
#
|
||||
# Expected context:
|
||||
# sidebar_content - Pre-rendered sidebar widget HTML (from get_sidebar('shop'))
|
||||
#
|
||||
# WooCommerce PHP equivalent: global/sidebar.php
|
||||
#
|
||||
# @package WcBootstrap
|
||||
# @since 0.1.0
|
||||
#}
|
||||
|
||||
{% if sidebar_content is defined and sidebar_content %}
|
||||
{# Mobile: offcanvas trigger button (visible below lg breakpoint) #}
|
||||
<button class="btn btn-outline-secondary d-lg-none mb-3"
|
||||
type="button"
|
||||
data-bs-toggle="offcanvas"
|
||||
data-bs-target="#shopSidebar"
|
||||
aria-controls="shopSidebar">
|
||||
<i class="bi bi-funnel" aria-hidden="true"></i>
|
||||
{{ __('Filters') }}
|
||||
</button>
|
||||
|
||||
{# Mobile: offcanvas panel #}
|
||||
<div class="offcanvas offcanvas-start offcanvas-lg"
|
||||
tabindex="-1"
|
||||
id="shopSidebar"
|
||||
aria-labelledby="shopSidebarLabel">
|
||||
<div class="offcanvas-header">
|
||||
<h5 class="offcanvas-title" id="shopSidebarLabel">{{ __('Filters') }}</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="{{ __('Close') }}"></button>
|
||||
</div>
|
||||
<div class="offcanvas-body">
|
||||
{{ sidebar_content|raw }}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
18
templates/global/wrapper-end.html.twig
Normal file
18
templates/global/wrapper-end.html.twig
Normal file
@@ -0,0 +1,18 @@
|
||||
{#
|
||||
# Content Wrapper End (Bootstrap 5 Override)
|
||||
#
|
||||
# Closes the wrapper divs opened by wrapper-start.html.twig.
|
||||
#
|
||||
# WooCommerce PHP equivalent: global/wrapper-end.php
|
||||
#
|
||||
# @package WcBootstrap
|
||||
# @since 0.1.0
|
||||
#}
|
||||
|
||||
{% set _wrapped = _theme_wrapped is defined and _theme_wrapped %}
|
||||
|
||||
{% if not _wrapped %}
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
20
templates/global/wrapper-start.html.twig
Normal file
20
templates/global/wrapper-start.html.twig
Normal file
@@ -0,0 +1,20 @@
|
||||
{#
|
||||
# Content Wrapper Start (Bootstrap 5 Override)
|
||||
#
|
||||
# Replaces WooCommerce's theme-specific wrapper divs with Bootstrap 5 layout.
|
||||
# When the parent theme wraps the page (_theme_wrapped), this outputs nothing
|
||||
# since base.html.twig already provides the container.
|
||||
#
|
||||
# WooCommerce PHP equivalent: global/wrapper-start.php
|
||||
#
|
||||
# @package WcBootstrap
|
||||
# @since 0.1.0
|
||||
#}
|
||||
|
||||
{% set _wrapped = _theme_wrapped is defined and _theme_wrapped %}
|
||||
|
||||
{% if not _wrapped %}
|
||||
<div class="container my-4">
|
||||
<div id="primary" class="content-area">
|
||||
<main id="main" class="site-main" role="main">
|
||||
{% endif %}
|
||||
34
templates/notices/error.html.twig
Normal file
34
templates/notices/error.html.twig
Normal file
@@ -0,0 +1,34 @@
|
||||
{#
|
||||
# Error Notice (Bootstrap 5 Override)
|
||||
#
|
||||
# Displays WooCommerce error notices as a Bootstrap 5 danger alert.
|
||||
# Multiple errors are shown as a list within a single alert.
|
||||
#
|
||||
# Expected context:
|
||||
# notices - Array of notice objects, each with:
|
||||
# notice - Notice HTML content (pre-sanitized via wc_kses_notice)
|
||||
# data - Optional data attributes string
|
||||
#
|
||||
# WooCommerce PHP equivalent: notices/error.php
|
||||
#
|
||||
# @package WcBootstrap
|
||||
# @since 0.1.0
|
||||
#}
|
||||
|
||||
{% if notices is defined and notices|length > 0 %}
|
||||
<div class="alert alert-danger alert-dismissible fade show woocommerce-error" role="alert">
|
||||
<i class="bi bi-exclamation-triangle me-2" aria-hidden="true"></i>
|
||||
{% if notices|length == 1 %}
|
||||
{{ notices[0].notice|raw }}
|
||||
{% else %}
|
||||
<ul class="mb-0 ps-3">
|
||||
{% for notice in notices %}
|
||||
<li {{ notice.data|default('')|raw }}>
|
||||
{{ notice.notice|raw }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="{{ __('Close') }}"></button>
|
||||
</div>
|
||||
{% endif %}
|
||||
27
templates/notices/notice.html.twig
Normal file
27
templates/notices/notice.html.twig
Normal file
@@ -0,0 +1,27 @@
|
||||
{#
|
||||
# Info Notice (Bootstrap 5 Override)
|
||||
#
|
||||
# Displays WooCommerce info/neutral notices as Bootstrap 5 alerts.
|
||||
#
|
||||
# Expected context:
|
||||
# notices - Array of notice objects, each with:
|
||||
# notice - Notice HTML content (pre-sanitized via wc_kses_notice)
|
||||
# data - Optional data attributes string
|
||||
#
|
||||
# WooCommerce PHP equivalent: notices/notice.php
|
||||
#
|
||||
# @package WcBootstrap
|
||||
# @since 0.1.0
|
||||
#}
|
||||
|
||||
{% if notices is defined and notices|length > 0 %}
|
||||
{% for notice in notices %}
|
||||
<div class="alert alert-info alert-dismissible fade show woocommerce-info"
|
||||
{{ notice.data|default('')|raw }}
|
||||
role="status">
|
||||
<i class="bi bi-info-circle me-2" aria-hidden="true"></i>
|
||||
{{ notice.notice|raw }}
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="{{ __('Close') }}"></button>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
27
templates/notices/success.html.twig
Normal file
27
templates/notices/success.html.twig
Normal file
@@ -0,0 +1,27 @@
|
||||
{#
|
||||
# Success Notice (Bootstrap 5 Override)
|
||||
#
|
||||
# Displays WooCommerce success notices as Bootstrap 5 success alerts.
|
||||
#
|
||||
# Expected context:
|
||||
# notices - Array of notice objects, each with:
|
||||
# notice - Notice HTML content (pre-sanitized via wc_kses_notice)
|
||||
# data - Optional data attributes string
|
||||
#
|
||||
# WooCommerce PHP equivalent: notices/success.php
|
||||
#
|
||||
# @package WcBootstrap
|
||||
# @since 0.1.0
|
||||
#}
|
||||
|
||||
{% if notices is defined and notices|length > 0 %}
|
||||
{% for notice in notices %}
|
||||
<div class="alert alert-success alert-dismissible fade show woocommerce-message"
|
||||
{{ notice.data|default('')|raw }}
|
||||
role="alert">
|
||||
<i class="bi bi-check-circle me-2" aria-hidden="true"></i>
|
||||
{{ notice.notice|raw }}
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="{{ __('Close') }}"></button>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
Reference in New Issue
Block a user