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>
WooCommerce Bootstrap
A WordPress child theme of WP Bootstrap that overrides all WooCommerce plugin templates with Bootstrap 5 structures and styling.
Requirements
- WordPress 6.7+
- PHP 8.3+
- WP Bootstrap theme (parent)
- WooCommerce plugin
- Composer
Installation
- Install and activate the parent theme
wp-bootstrap - Install and activate the
woocommerceplugin - Upload
wc-bootstraptowp-content/themes/ - Run
composer installin the theme directory - Activate the theme in WordPress Admin > Appearance > Themes
How It Works
WooCommerce renders its pages using PHP templates loaded via wc_get_template(). This child theme intercepts that process with a Twig rendering bridge that replaces the PHP output with Bootstrap 5 styled Twig templates.
The bridge hooks into WooCommerce's woocommerce_before_template_part and woocommerce_after_template_part actions. When a matching .html.twig template exists, it is rendered via the parent theme's TwigService and the original PHP output is discarded. If no Twig override exists, the default PHP template renders normally.
Key Features
- 99 Twig template overrides covering all customer-facing WooCommerce pages
- Rendering bridge (
WooCommerceExtension+TemplateOverride) that intercepts WooCommerce's PHP template pipeline - ~50 Twig functions and 8 Twig filters exposing WooCommerce and WordPress APIs to templates
- Bootstrap 5 responsive markup with dark mode support
- PHPUnit test suite with Brain\Monkey for isolated unit testing (no WordPress/WooCommerce required)
- HPOS compatible (uses
WC_Ordermethods only, no$postglobal) - 8 reusable Twig components (card, pagination, price, rating, address-card, status-badge, quantity-input, form-field)
- Translation-ready
Template Coverage
| Area | Templates | Status |
|---|---|---|
| Global & Notices | 9 | Done |
| Product Archive & Loop | 15 | Done |
| Single Product | 21 | Done |
| Cart | 9 | Done |
| Checkout | 12 | Done |
| My Account | 15 | Done |
| Order Details | 5 | Done |
| Supplementary (Brands, Auth, Back-in-Stock) | 7 | Done |
| Reusable Components | 8 | Done |
| Emails | -- | Skipped (incompatible pipeline) |
Development
Directory Structure
wc-bootstrap/
├── assets/
│ ├── css/wc-bootstrap.css # Bootstrap override styles
│ └── js/
│ ├── product-gallery.js # Thumbnail click-to-swap gallery handler
│ └── quantity.js # Quantity +/- button handler
├── inc/
│ ├── TemplateOverride.php # WC template interception (before/after hooks)
│ └── Twig/
│ └── WooCommerceExtension.php # WC/WP Twig functions & filters
├── languages/ # Translation files
├── templates/ # Bootstrap 5 Twig template overrides
│ ├── wc-base.html.twig # Base layout (extends parent's base.html.twig)
│ ├── layouts/ # Page-type layouts (account, archive, form, page, single)
│ ├── archive-product.html.twig
│ ├── content-product.html.twig
│ ├── content-product_cat.html.twig
│ ├── product-searchform.html.twig
│ ├── auth/
│ ├── brands/
│ ├── cart/
│ ├── checkout/
│ ├── components/
│ ├── global/
│ ├── loop/
│ ├── myaccount/
│ ├── notices/
│ ├── order/
│ └── single-product/
├── tests/
│ ├── bootstrap.php # PHPUnit bootstrap (autoloader + stubs)
│ ├── Stubs/ # WordPress/WooCommerce class stubs
│ └── Unit/ # Unit tests (TemplateOverride, WooCommerceExtension)
├── docker/
│ ├── Dockerfile # Multistage build (WC download, npm, composer, WP)
│ ├── entrypoint.sh # Auto-setup wrapper entrypoint
│ └── setup.sh # First-run WP install + plugin/theme activation
├── phpunit.xml.dist # PHPUnit 11 configuration
├── .env-dist # Environment variable template
├── compose.yaml # WordPress + MariaDB services
├── compose.override.yaml # Dev overrides (bind mounts, debug flags)
├── composer.json
├── functions.php
└── style.css
Architecture
WooCommerce wc_get_template("cart/cart.php")
→ woocommerce_before_template_part hook
→ TemplateOverride checks for cart/cart.html.twig
→ Found → renders via TwigService (with WooCommerceExtension functions)
→ Starts output buffer
→ PHP include (captured in buffer)
→ woocommerce_after_template_part hook
→ TemplateOverride discards buffered PHP output
→ Result: Bootstrap 5 Twig output only
Docker Environment
# Copy and adjust environment variables (optional)
cp .env-dist .env
# Build and start
docker compose build
docker compose up -d
# WordPress installs automatically on first boot (admin/admin)
# → http://localhost:8080
# → http://localhost:8080/wp-admin/
# Manual setup (if WP_AUTO_SETUP=0)
docker compose exec wordpress setup.sh
# Tear down
docker compose down -v
The image preinstalls WooCommerce and wp-bootstrap. The override bind-mounts both themes for live development.
Building Translations
for po in languages/wc-bootstrap-*.po; do msgfmt -o "${po%.po}.mo" "$po"; done
Releases
Releases are automated via Gitea Actions. Push a tag matching vX.X.X to trigger a release build.
git tag -a v0.1.6 -m "Version 0.1.6 - Add PHPUnit test suite"
git push origin v0.1.6
License
GPL-2.0-or-later
Author
Marco Grätsch - https://src.bundespruefstelle.ch/magdev