You've already forked wc-bootstrap
Catalog: page title via woocommerce_page_title(), breadcrumbs, category template rename (underscore), 3-column grid, single chevron on sort. Single product: variable form data attributes + disabled CSS class fix (WC JS only toggles CSS classes, not HTML disabled attribute), dark mode select specificity (0,5,1) to beat WC's (0,4,3) background shorthand, gallery main image in thumbnail strip with empty URL guard, related/ upsells setup_postdata for correct global $product, grouped product loop logic rewrite. Account: downloads via wc_get_customer_available_downloads(). New: product-gallery.js, sanitize_title filter, wc_setup_product_data() and wp_reset_postdata() Twig functions, product-thumbnails.html.twig suppressor. Removed obsolete PLAN.md and SETUP.md. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
12 KiB
12 KiB
Changelog
All notable changes to this project will be documented in this file.
[0.1.5] - 2026-03-01
Fixed
- Empty page title on catalog pages (
header.html.twig): Replacedpage_titlecontext variable (never passed by WC) with directfn('woocommerce_page_title', false)call - Missing breadcrumbs on catalog pages (
archive-product.php): Addedwoocommerce_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'swc_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 conflictingappearance: autorule; setappearance: noneto let Bootstrap'sform-selectclass handle the dropdown arrow exclusively - Variable product add-to-cart button stays disabled (
variable.html.twig,variation-add-to-cart-button.html.twig): Added missingdata-product_idanddata-product_variationsattributes to form; replaced HTMLdisabledattribute on button with CSS classesdisabled 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 selectat(0,4,3)which usesbackgroundshorthand; also overridesbackground-imagefor 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): Addedwc_setup_product_data()call before each product render andwp_reset_postdata()after loop to set global$productcorrectly for WC hooks - Grouped product add-to-cart button/pricing broken (
grouped.html.twig): Rewrote template to computequantites_requiredandshow_add_to_cart_buttonin loop (matching WC PHP logic); moved hiddenadd-to-cartinput outside conditional; addedhas_options()andis_sold_individually()checks - Downloads page empty (
downloads.html.twig): Replaced fragilefn('WC').customer.get_downloadable_products()chain with directfn('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 callssetup_postdata()for correct product context in Twig loopswp_reset_postdataTwig function (WooCommerceExtension.php): Restores global post state after product loopssanitize_titleTwig 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): Addedwoocommerce_page_titleandwc_get_customer_available_downloadstoALLOWED_FUNCTIONS - Removed obsolete files: Deleted
PLAN.mdandSETUP.md(superseded by CLAUDE.md)
[0.1.4] - 2026-03-01
Security
- fn() function whitelist (
WooCommerceExtension): ThecallFunction()method (exposed asfn()in Twig templates) now restricts callable functions to an explicitALLOWED_FUNCTIONSwhitelist. 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_attrfilter toget_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 redundantContextBuilder::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 fromwc_bootstrap_render_page(),wc_bootstrap_render_product_archive(), andwc_bootstrap_render_single_product(). - Removed unused constants: Removed
WC_BOOTSTRAP_VERSIONandWC_BOOTSTRAP_URLconstants 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(specificity0,3,1) overriding theme's checkout form rules withvar(--wc-form-color-background, #fff)fallback - Dark mode:
table-lightclass 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-backgroundfalling back to#fff - Dark mode: SelectWoo/Select2 dropdowns (country/state pickers) rendering with hardcoded
#fffbackgrounds, 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-*at0,2,0) - WooCommerce notice
border-top: 3px solidandbackground-color: #f6f5f8overriding Bootstrap alert colors - Double icons on WooCommerce notices (WooCommerce icon font
::beforeconflicting with Bootstrap Icons) - Product card images overlapping top rounded corners on catalog page (added
overflow-hiddento 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-lgresponsive 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
$productinjection 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-widthreset
Fixed
- Rename
base.html.twig→wc-base.html.twigto prevent shadowing the parent theme's page shell via TwigFilesystemLoaderpath priority - CSS dependency handle from unregistered
woocommercetowoocommerce-generalforwc-bootstrap-overridesstylesheet - 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_htmlfilter order in order details (was escaping<br>tags)- HTML entity double-encoding (
…) in up-sells, cross-sells, and related product headings - Wrong
function() is definedguards in cart totals, review order, checkout login, and terms templates - Duplicate deprecated hook fires in dashboard template
- Missing
|rawon brand description HTML filter chain - Missing
role="alert"on variation add-to-cart for accessibility - Missing
|esc_attron notification type class attribute - Missing
is definedguard onhiddenvariable in global form-login - Pagination URLs using
?page=instead ofget_pagenum_link()for archives - Double-escaped
–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_pagefilter - Theme wrapping signal via
woocommerce_is_theme_wrappedfilter - CI/CD release workflow (Gitea Actions)
- Translation support (
.pottemplate ready) - Docker development environment (multistage Dockerfile, Compose, auto-setup entrypoint)
Fixed
- Rename
base.html.twig→wc-base.html.twigto prevent shadowing the parent theme's page shell via TwigFilesystemLoaderpath priority - Correct CSS dependency handle from
woocommercetowoocommerce-generalforwc-bootstrap-overridesstylesheet
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.