Files
wc-bootstrap/CHANGELOG.md
magdev 4031a1c8aa
All checks were successful
Create Release Package / PHP Lint (push) Successful in 1m2s
Create Release Package / PHPUnit Tests (push) Successful in 46s
Create Release Package / Build Release (push) Successful in 50s
Add PHPUnit test suite with Brain\Monkey (v0.1.6)
Add test infrastructure for isolated unit testing without WordPress/WooCommerce:
- 27 tests (54 assertions) covering TemplateOverride and WooCommerceExtension
- Brain\Monkey for WordPress function mocking, class stubs for TwigService and WC_Product
- PHPUnit test job added to Gitea CI pipeline between lint and build-release
- Test artifacts excluded from release packages

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 03:48:19 +01:00

13 KiB

Changelog

All notable changes to this project will be documented in this file.

[0.1.6] - 2026-03-01

Added

  • PHPUnit test suite with Brain\Monkey for WordPress function mocking (27 tests, 54 assertions)
  • TemplateOverrideTest: Tests for hook registration, Twig template resolution, output buffer stack (including nesting), context passing, global $product injection, and exception fallback
  • WooCommerceExtensionTest: Tests for function/filter registration, callFunction() whitelist enforcement, doAction/applyFilters/callUserFunc output capture, setupProductData, and all output-capture wrappers
  • CI/CD test job: PHPUnit runs between lint and build-release in Gitea pipeline; test artifacts excluded from release packages
  • Class stubs for WPBootstrap\Twig\TwigService and WC_Product enabling isolated unit testing without WordPress/WooCommerce

[0.1.5] - 2026-03-01

Fixed

  • Empty page title on catalog pages (header.html.twig): Replaced page_title context variable (never passed by WC) with direct fn('woocommerce_page_title', false) call
  • Missing breadcrumbs on catalog pages (archive-product.php): Added woocommerce_breadcrumb() call before shop loop header
  • Missing product categories on catalog pages (content-product-cat.html.twig): Renamed template from hyphen (content-product-cat) to underscore (content-product_cat) to match WC's wc_get_template() filename convention
  • Product grid 4 columns instead of 3 (functions.php, loop-start.html.twig): Changed default columns from 4 to 3 for better card proportions with sidebar
  • Double chevron on sort dropdown (wc-bootstrap.css): Removed conflicting appearance: auto rule; set appearance: none to let Bootstrap's form-select class handle the dropdown arrow exclusively
  • Variable product add-to-cart button stays disabled (variable.html.twig, variation-add-to-cart-button.html.twig): Added missing data-product_id and data-product_variations attributes to form; replaced HTML disabled attribute on button with CSS classes disabled wc-variation-selection-needed (WC JS only toggles CSS classes, never removes the HTML attribute)
  • Variable product select white background in dark mode (wc-bootstrap.css): Increased dark mode override specificity to (0,5,1) to beat WC's .woocommerce div.product form.cart .variations select at (0,4,3) which uses background shorthand; also overrides background-image for Bootstrap's dark-mode-aware chevron SVG
  • Product gallery missing main image in thumbnail strip (product-image.html.twig): Prepend main image ID to gallery IDs using [post_thumbnail_id]|merge(gallery_image_ids) with active state on first thumbnail; added {% if thumb_url %} guard to skip invalid attachment IDs
  • Related/upsells products show same product repeated (related.html.twig, up-sells.html.twig): Added wc_setup_product_data() call before each product render and wp_reset_postdata() after loop to set global $product correctly for WC hooks
  • Grouped product add-to-cart button/pricing broken (grouped.html.twig): Rewrote template to compute quantites_required and show_add_to_cart_button in loop (matching WC PHP logic); moved hidden add-to-cart input outside conditional; added has_options() and is_sold_individually() checks
  • Downloads page empty (downloads.html.twig): Replaced fragile fn('WC').customer.get_downloadable_products() chain with direct fn('wc_get_customer_available_downloads', get_current_user_id()) call

Added

  • Product gallery JS (product-gallery.js): Vanilla JS click handler for thumbnail-to-main-image swap with active state highlighting and gallery fade-in
  • wc_setup_product_data() Twig function (WooCommerceExtension.php): Sets $GLOBALS['product'] and calls setup_postdata() for correct product context in Twig loops
  • wp_reset_postdata Twig function (WooCommerceExtension.php): Restores global post state after product loops
  • sanitize_title Twig filter (WooCommerceExtension.php): Matches WC PHP's lowercase attribute name handling for variation form data attributes
  • Product thumbnails suppressor (product-thumbnails.html.twig): Empty template override to prevent WC's default full-size gallery images rendering below custom thumbnail row

Changed

  • Whitelisted functions (WooCommerceExtension.php): Added woocommerce_page_title and wc_get_customer_available_downloads to ALLOWED_FUNCTIONS
  • Removed obsolete files: Deleted PLAN.md and SETUP.md (superseded by CLAUDE.md)

[0.1.4] - 2026-03-01

Security

  • fn() function whitelist (WooCommerceExtension): The callFunction() method (exposed as fn() in Twig templates) now restricts callable functions to an explicit ALLOWED_FUNCTIONS whitelist. Previously any PHP function could be called, risking arbitrary code execution if template context were compromised. Only the 6 functions actually used in templates are permitted.
  • Notice data attribute escaping: Changed {{ notice.data|raw }} to {{ notice.data|wp_kses_post }} in success, error, and notice Twig templates. Defense-in-depth against potential XSS via data attributes.
  • Search query escaping (product-searchform.html.twig): Added |esc_attr filter to get_search_query() output in the search input value attribute.

Performance

  • Per-request ContextBuilder caching: New wc_bootstrap_get_theme_context() function with static variable caching eliminates redundant ContextBuilder::build() calls (10-20 DB queries each) when multiple WooCommerce render functions fire in the same request.

Changed

  • Shared page shell helper: New wc_bootstrap_render_in_page_shell() function extracts the duplicated context-injection-and-render pattern from wc_bootstrap_render_page(), wc_bootstrap_render_product_archive(), and wc_bootstrap_render_single_product().
  • Removed unused constants: Removed WC_BOOTSTRAP_VERSION and WC_BOOTSTRAP_URL constants that were defined but never referenced.

[0.1.3] - 2026-02-28

Added

  • Theme screenshot showing dark mode product archive with Bootstrap 5 card grid

[0.1.2] - 2026-02-28

Fixed

  • Dark mode: text inputs and textareas showing white background due to WooCommerce's .woocommerce form .form-row .input-text (specificity 0,3,1) overriding theme's checkout form rules with var(--wc-form-color-background, #fff) fallback
  • Dark mode: table-light class on <thead> forcing white table headers in cart, checkout review, orders, and payment methods pages
  • Dark mode: WooCommerce notice focus ring appearing white when focus_populate_live_region() JS programmatically focuses alerts for screen reader accessibility
  • WooCommerce notice overrides not matching alerts rendered by Twig templates (added .alert.woocommerce-* compound selectors alongside .woocommerce .woocommerce-* descendant selectors)
  • Order details table on thank-you page not wrapped in a card like other sections
  • Thank-you page success message line-wrapping after icon due to block-level <p> inside inline alert context

[0.1.1] - 2026-02-28

Fixed

  • Dark mode: native <select> elements showing white background due to WooCommerce's --wc-form-color-background falling back to #fff
  • Dark mode: SelectWoo/Select2 dropdowns (country/state pickers) rendering with hardcoded #fff backgrounds, text colors, and borders
  • Dark mode: checkout form focus ring color for inputs, textareas, and selects
  • WooCommerce notice borders not matching Bootstrap alert styles due to insufficient CSS specificity (bumped to .woocommerce .woocommerce-* at 0,2,0)
  • WooCommerce notice border-top: 3px solid and background-color: #f6f5f8 overriding Bootstrap alert colors
  • Double icons on WooCommerce notices (WooCommerce icon font ::before conflicting with Bootstrap Icons)
  • Product card images overlapping top rounded corners on catalog page (added overflow-hidden to card)

[0.1.0] - 2026-02-28

Added

  • Docker development environment: multistage Dockerfile (WooCommerce download, wp-bootstrap npm build, Composer deps, WordPress runtime), Compose stack with MariaDB, auto-setup entrypoint
  • Private registry image name and restart policies for Docker stack
  • My Account polish: endpoint icon map, offcanvas-lg responsive navigation with sticky sidebar, card-based dashboard with avatar welcome greeting and quick-action grid, card-wrapped forms with icon headers, view-order summary card with status badge
  • Product archive: Bootstrap 5 card grid with responsive columns, sale badges, star ratings, offcanvas sidebar for mobile filters, shop-sidebar widget area
  • Single product layout: two-column responsive grid (image gallery + product summary), bridge for wc_get_template_part() interception, disabled WooCommerce block compatibility layer
  • Global $product injection into Twig context for loop sub-templates
  • CSS overrides: WooCommerce float/width layout reset, sale badge repositioning, shop_table border reset, gallery opacity fallback, My Account max-width reset

Fixed

  • Rename base.html.twigwc-base.html.twig to prevent shadowing the parent theme's page shell via Twig FilesystemLoader path priority
  • CSS dependency handle from unregistered woocommerce to woocommerce-general for wc-bootstrap-overrides stylesheet
  • WooCommerce float-based two-column layout (width: 48% + float) fighting Bootstrap grid on single product pages
  • Nested content wrapper doubling parent theme's .container
  • Sale badge escaping image column and blocking breadcrumb clicks
  • |nl2br|esc_html filter order in order details (was escaping <br> tags)
  • HTML entity double-encoding (&hellip;) in up-sells, cross-sells, and related product headings
  • Wrong function() is defined guards in cart totals, review order, checkout login, and terms templates
  • Duplicate deprecated hook fires in dashboard template
  • Missing |raw on brand description HTML filter chain
  • Missing role="alert" on variation add-to-cart for accessibility
  • Missing |esc_attr on notification type class attribute
  • Missing is defined guard on hidden variable in global form-login
  • Pagination URLs using ?page= instead of get_pagenum_link() for archives
  • Double-escaped &ndash; in result count
  • Underscore.js triple-brace syntax conflict in variation template (wrapped in {% verbatim %})

[0.0.1] - 2026-02-28

Added

  • Initial theme scaffold (style.css, functions.php, Composer autoload)
  • Comprehensive template conversion plan (PLAN.md)
  • Phase 1: Global templates (wrapper, breadcrumb, sidebar, quantity-input, form-login) and notices (success, error, info)
  • Phase 2: Product archive and shop loop templates (archive-product, content-product, loop components, pagination, orderby, sale-flash)
  • Phase 3: Single product page templates (image gallery, title, price, meta, stock, tabs, add-to-cart forms for simple/variable/grouped/external)
  • Phase 4: Cart templates (cart table, empty cart, cart totals, shipping calculator, mini-cart, cross-sells)
  • Phase 5: Checkout templates (form-checkout, billing/shipping forms, coupon, order review, payment methods, terms, thank-you)
  • Phase 6: My Account templates (dashboard, navigation, orders, view-order, addresses, edit-address, edit-account, downloads, payment methods, login/register, password reset)
  • Phase 7: Order details templates (order-details, order-details-item, order-details-customer, form-tracking, order-again)
  • Phase 9: Supplementary templates (brands, OAuth auth, back-in-stock form)
  • Reusable Twig components (card, pagination, price, rating, address-card, status-badge, quantity-input, form-field)
  • WooCommerce-to-Twig rendering bridge (TemplateOverride + WooCommerceExtension)
  • ~50 WooCommerce/WordPress Twig functions and 7 Twig filters
  • Stack-based output buffering for nested template interception
  • Bootstrap 5 override stylesheet (wc-bootstrap.css)
  • Quantity +/- button JavaScript handler
  • Sticky header scroll shadow behavior
  • Parent theme rendering delegation via woocommerce_render_page filter
  • Theme wrapping signal via woocommerce_is_theme_wrapped filter
  • CI/CD release workflow (Gitea Actions)
  • Translation support (.pot template ready)
  • Docker development environment (multistage Dockerfile, Compose, auto-setup entrypoint)

Fixed

  • Rename base.html.twigwc-base.html.twig to prevent shadowing the parent theme's page shell via Twig FilesystemLoader path priority
  • Correct CSS dependency handle from woocommerce to woocommerce-general for wc-bootstrap-overrides stylesheet

Skipped

  • Phase 8 (Email templates): WooCommerce emails use wc_get_template_html() which bypasses the Twig rendering pipeline. Default email templates are sufficient; customization can be handled via dedicated email plugins.