5th OWASP Top-10 pass: added |esc_url filter to all unescaped URL outputs across 8 Twig template partials (headers, footers, search, comments). Registered esc_html, esc_attr, esc_url as Twig filters with is_safe option. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
WP Bootstrap
A modern WordPress Block Theme built from scratch with Bootstrap 5. Features responsive design, dark mode support, Twig template rendering, and full compatibility with the WordPress Site Editor.
Features
- Bootstrap 5 Frontend -- Proper Bootstrap 5 HTML (navbar, cards, pagination, grid) rendered via Twig templates
- Dark Mode -- Toggle with localStorage persistence and
prefers-color-schemesupport - Full Site Editing -- Compatible with the WordPress Site Editor for admin editing
- Style Variations -- 15 color schemes (7 light, 7 dark, plus default) with live Design Editor customization
- Block Patterns -- 41 patterns across 11 categories (hero, features, CTA, testimonials, pricing, contact, text, layout, components, navigation, pages)
- Bootstrap Icons -- 2,000+ icons available via CSS classes (
bi bi-*) - Block Renderer -- Automatic Bootstrap 5 class injection on 8 core block types (table, button, image, search, quote, pullquote, list) via
render_blockfilters - Widget Renderer -- Sidebar widgets wrapped in Bootstrap cards with proper heading hierarchy
- Block Styles -- 18 custom styles mapping Bootstrap components to WordPress blocks (including List Group)
- Custom Templates -- Landing (no header/footer), full-width, hero, sidebar page templates; blog posts default to sidebar layout
- Header/Footer Variations -- Default, centered, transparent headers; default, minimal, multi-column footers
- Navigation Styles -- Dark navbar, offcanvas mobile navigation
- Widget Area -- Sidebar widget area manageable via WordPress admin, with built-in fallback
- Accessibility -- Skip-to-content link, ARIA labels,
aria-currenton active items, screen reader announcements - RTL Support -- Right-to-left language support with logical CSS properties
- Translation Ready -- Full i18n support with 14 locales (en_US, de_CH, de_CH_informal, de_DE, de_DE_informal, en_GB, es_ES, fr_CH, fr_FR, it_CH, it_IT, nl_NL, pl_PL, pt_PT)
- Responsive -- Mobile-first design with Bootstrap's responsive grid
Requirements
- WordPress 6.7 or higher
- PHP 8.3 or higher
- Composer
- Node.js 20+
Installation
From Release Package
- Download the latest
.zipfrom Releases - Go to WordPress Admin > Appearance > Themes > Add New > Upload Theme
- Upload the ZIP file and activate
From Source
git clone ssh://git@src.bundespruefstelle.ch:2022/magdev/wp-bootstrap.git
cd wp-bootstrap
composer install
npm install
npm run build
Activate the theme in Appearance > Themes in the WordPress admin.
Development
Prerequisites
- Node.js 20+
- npm
- Composer
- PHP 8.3+
Build Commands
| Command | Description |
|---|---|
npm run build |
Full production build (runs tests, copies JS, compiles SCSS, minifies CSS) |
npm run test |
Run PHPUnit test suite |
npm run dev |
Watch SCSS files and recompile on changes |
npm run scss |
Compile SCSS only |
npm run postcss |
Minify CSS with Autoprefixer and cssnano |
composer install |
Install PHP dependencies (Twig) |
Testing
The theme includes a PHPUnit test suite with 64 unit tests and 107 assertions covering the core PHP classes:
- BlockRenderer -- All 8 render methods (table, button, buttons, image, search, quote, pullquote, list)
- WidgetRenderer -- Card wrapping, heading downgrade, class extraction
- NavWalker -- Tree building, active item detection, orphan handling
- TemplateController -- Template resolution for all page types
Tests use Brain\Monkey for WordPress function mocking and a functional WP_HTML_Tag_Processor stub.
# Run tests
composer exec -- phpunit
# Tests also run automatically before every build
npm run build
Build Pipeline
test-- Run PHPUnit test suite (automatic viaprebuildhook)copy:js-- Copy Bootstrap JS bundle fromnode_modulestoassets/js/copy:theme-js-- Copy theme JS (dark-mode.js) fromsrc/js/toassets/js/copy:icons-- Copy Bootstrap Icons font files (.woff,.woff2) toassets/fonts/scss-- Compile SCSS (src/scss/) to CSS (assets/css/)scss:rtl-- Compile RTL stylesheet (assets/css/rtl.css)postcss-- Autoprefixer + cssnano minification toassets/css/style.min.css
Architecture
Frontend Rendering
The theme uses a dual-rendering approach:
- Site Editor (admin): FSE block templates in
templates/andparts/for visual editing - Frontend (public): Twig templates in
views/render Bootstrap 5 HTML via thetemplate_redirecthook
The TemplateController intercepts frontend requests and renders the appropriate Twig template with data gathered by ContextBuilder. Plugins can hook into the wp_bootstrap_should_render_template filter to prevent rendering for specific requests (e.g., when a plugin handles its own custom post types). FSE templates remain untouched for the WordPress admin editor.
Style Variation Bridge
WordPress style variation colors are bridged to Bootstrap CSS custom properties at runtime. When a variation is selected in the Design Editor, the theme reads the active palette via wp_get_global_settings() and outputs inline CSS that overrides Bootstrap's compiled defaults. This works for both light and dark mode.
Key PHP Classes
| Class | Purpose |
|---|---|
TwigService |
Singleton Twig environment with WordPress functions and globals |
TemplateController |
Hooks template_redirect, resolves and renders Twig templates |
ContextBuilder |
Gathers WordPress data (posts, menus, pagination, comments, sidebar) |
NavWalker |
Converts flat menu items to nested tree for Bootstrap dropdowns |
BlockRenderer |
Injects Bootstrap 5 classes into core block HTML via render_block filters |
WidgetRenderer |
Wraps sidebar widgets in Bootstrap card components |
Navigation Menus
Register menus in Appearance > Menus:
- Primary Navigation -- Displayed in the Bootstrap navbar with dropdown support
- Footer Navigation -- Displayed in the footer
If no menu is assigned, the primary location falls back to listing published pages.
Widget Areas
The theme registers a Sidebar widget area. When widgets are assigned via Appearance > Widgets, they replace the default sidebar content. When no widgets are assigned, the sidebar displays recent posts, a search form, and a tag cloud. All sidebar widgets are automatically wrapped in Bootstrap card components with consistent heading styles.
Block Renderer
The BlockRenderer class hooks per-block render_block_{$name} filters (more performant than a single render_block filter) and uses WordPress's WP_HTML_Tag_Processor for safe, idempotent class injection. Only active on the frontend — admin, REST API, and AJAX requests are skipped. Child themes can modify the block-to-handler map via the wp_bootstrap_block_renderer_blocks filter.
Widget Renderer
The WidgetRenderer class transforms sidebar widget output into Bootstrap card components. It hooks dynamic_sidebar_params for wrapper HTML and widget_block_content for inner content adjustments (heading level downgrade from <h2> to <h4>). The card structure uses card-body with card-title inside, ensuring valid HTML whether or not a widget outputs a title.
Project Structure
wp-bootstrap/
+-- assets/ Compiled CSS, JS, fonts
+-- inc/
| +-- Block/ BlockRenderer, WidgetRenderer
| +-- Template/ TemplateController, ContextBuilder, NavWalker
| +-- Twig/ TwigService singleton
+-- languages/ Translation files (.pot, .po)
+-- patterns/ Block patterns (PHP)
+-- parts/ FSE template parts (header, footer, sidebar, variants)
+-- src/
| +-- js/ Source JavaScript
| +-- scss/ Source SCSS
+-- styles/ Style variations (JSON)
+-- tests/
| +-- Stubs/ WordPress class stubs for testing
| +-- Unit/ PHPUnit test cases
+-- templates/ FSE templates (HTML)
+-- views/ Twig templates (Bootstrap 5 HTML)
| +-- base.html.twig
| +-- pages/ Page templates (index, single, page, archive, search, 404)
| +-- partials/ Reusable parts (header, footer, pagination, sidebar, etc.)
| +-- components/ UI components (post card, post loop)
+-- functions.php Theme bootstrap
+-- style.css Theme metadata
+-- theme.json Design tokens and settings
Technology Stack
- PHP 8.3+ with PSR-4 autoloading
- Twig 3.0 via Composer
- Bootstrap 5.3+ CSS & JS (served locally)
- Dart Sass for SCSS compilation
- PostCSS with Autoprefixer and cssnano
- PHPUnit 11 with Brain\Monkey for WordPress function mocking
License
GPL-2.0-or-later. See http://www.gnu.org/licenses/gpl-2.0.html.
Author
Marco Graetsch - https://src.bundespruefstelle.ch/magdev