This WordPress-Theme is built from scratch employing Bootstrap 5. Build modern Websites using the state-of-the-art Framework. All basic WordPress components are converted and are fully working. The theme uses Twig for rendering. It is also a good starting point as base theme for complex WordPress websites.
### Features
- [ ] All native WordPress theme files converted to Boostrap 5
- [ ] Works seemlessly on default WordPress installations
- [ ] Installable via WordPress admin
#### Frontend
- [ ] Fully responsive Design
- [ ] Supports darkmode
#### Administration
- [ ] Compatible with the Gutenberg-Editor
- [ ] Customizable with the Design-Editor
### Key Fact: 100% AI-Generated
This project is proudly **"vibe-coded"** using Claude.AI - the entire codebase was created through AI assistance.
## Temporary Roadmap
**Note for AI Assistants:** Clean this section after the specific features are done or new releases are made. Effective changes are tracked in `CHANGELOG.md`. Do not add completed versions here - document them in the Session History section at the end of this file.
- All user inputs are sanitized (integers for quantities/prices)
- Nonce verification on form submissions
- Output escaping in templates (`esc_attr`, `esc_html`, `esc_js`)
- Direct file access prevention via `ABSPATH` check
- XSS-safe DOM construction in JavaScript (no `innerHTML` with user data)
### Translation Ready
All user-facing strings use:
```php
__('Text to translate', 'wp-bootstrap')
_e('Text to translate', 'wp-bootstrap')
```
Text domain: `wp-bootstrap`
#### Translation Template
- Base `.pot` file created: `languages/wp-bootstrap.pot`
- Ready for translation to any locale
- All translatable strings properly marked with text domain
#### Available Translations
-`en_US` - English (United States) [base language - .pot template]
-`de_CH` - German (Switzerland, formal)
There is no need to compile translation to *.mo locally as it will be done in the Gitea CD/CI pipeline
### Create Releases
**Important Git Notes:**
- Default branch while development is `dev`
- Create releases from branch `main` after merging branch `dev`
- Tags should use format `vX.X.X` (e.g., `v1.1.22`), start with v0.1.0
- Use annotated tags (`-a`) not lightweight tags
- **ALWAYS push tags to origin** - CI/CD triggers on tag push
- Commit messages should follow the established format with Claude Code attribution
-`.claude/settings.local.json` changes are typically local-only (stash before rebasing)
**CRITICAL - Release Workflow:**
On every new version, ALWAYS execute this complete workflow:
```bash
# 1. Commit changes to dev branch
git add <files>
git commit -m "Description of changes (vX.X.X)"
# 2. Merge dev to main
git checkout main
git merge dev --no-edit
# 3. Create annotated tag
git tag -a vX.X.X -m "Version X.X.X - Brief description"
# 4. Push everything to origin
git push origin dev main vX.X.X
# 5. Switch back to dev for continued development
git checkout dev
```
Never skip any of these steps. The release is not complete until all branches and the tag are pushed to origin.
---
**For AI Assistants:**
When starting a new session on this project:
1. Read this CLAUDE.md file first
2. Semantic versioning follows the `MAJOR.MINOR.BUGFIX` pattern
3. Check git log for recent changes
4. Verify you're on the `dev` branch before making changes
5. Run `git submodule update --init --recursive` if lib/ is empty (only if submodules present)
6. Run `composer install` if vendor/ is missing
7. Test changes before committing
8. Follow commit message format with Claude Code attribution
9. Update this session history section with learnings
10. Never commit backup files (`*.po~`, `*.bak`, etc.) - check `git status` before committing
11. Follow markdown linting rules (see below)
Always refer to this document when starting work on this project.
### Markdown Linting Rules
When editing CLAUDE.md or other markdown files, follow these rules to avoid linting errors:
1.**MD031 - Blank lines around fenced code blocks**: Always add a blank line before and after fenced code blocks, even when they follow list items. Example of correct format:
- **Item label**:
(blank line here)
\`\`\`php
code example
\`\`\`
(blank line here)
2.**MD056 - Table column count**: Table separators must have matching column counts and proper spacing. Use consistent dash lengths that match column header widths.
3.**MD009 - No trailing spaces**: Remove trailing whitespace from lines
4.**MD012 - No multiple consecutive blank lines**: Use only single blank lines between sections
5.**MD040 - Fenced code blocks should have a language specified**: Always add a language identifier to code blocks (e.g., `txt`, `bash`, `php`). For shortcode examples, use `txt`.
6.**MD032 - Lists should be surrounded by blank lines**: Add a blank line before AND after list blocks, including after bold labels like `**Attributes:**`.
7.**MD034 - Bare URLs**: Wrap URLs in angle brackets (e.g., `<https://example.com>`) or use markdown link syntax `[text](url)`.
8.**Author section formatting**: Use a heading (`### Name`) instead of bold (`**Name**`) for the author name to maintain consistent document structure.
- **Dark mode:** Uses Bootstrap 5.3 `data-bs-theme` attribute on `<html>`. An inline anti-flash script runs synchronously in `<head>` (via `wp_add_inline_script` with `'before'`), while the full `dark-mode.js` is deferred. Preference stored in `localStorage` key `wp-bootstrap-theme`.
- **Block styles:** Registered via `register_block_style()` with `inline_style` parameter in `functions.php`. Dark mode overrides for alert/card styles are in `src/scss/_custom.scss`.
- **Style variations:** JSON files in `styles/` directory. All 15 variations (7 light, 7 dark, plus default) use the same 10 color slug names (base, contrast, primary, secondary, success, danger, warning, info, light, dark) to ensure patterns work across all schemes.
- **Fonts:** Inter (sans-serif) and Lora (serif) variable fonts bundled as `.woff2` in `assets/fonts/`. Declared via `fontFace` in `theme.json` with `font-display: swap`.
- **Patterns:** PHP files in `patterns/` with WordPress block markup and i18n. Hidden patterns (prefixed `hidden-`) are reusable components not shown in the pattern inserter.
- **Twig frontend rendering:** `TemplateController` hooks `template_redirect` to intercept frontend requests and render Bootstrap 5 HTML via Twig, bypassing FSE block markup. FSE templates remain for the Site Editor. WordPress functions that produce output (`wp_head`, `wp_footer`, `body_class`, `language_attributes`) are captured via `ob_start()`/`ob_get_clean()` and passed to Twig as safe HTML strings.
- **Navigation menus:** `NavWalker` converts flat `wp_get_nav_menu_items()` into a nested tree for Bootstrap dropdown rendering. Falls back to listing published pages when no menu is assigned.
- **Docker development:** WordPress runs in Docker container `jobroom-wordpress`. The theme directory must be bind-mounted via `compose.override.yaml` (absolute path) for live changes to be visible.
**Completed:** Added 8 new style variations (4 light, 4 dark) to the Design Editor.
**What was built:**
- 4 new light palettes: Rose (pink/fuchsia), Sand (warm amber/beige), Lavender (soft purple), Mint (fresh teal)
- 4 new dark palettes: Slate (neutral blue-gray), Mocha (coffee/warm brown), Nebula (space teal-cyan), Obsidian (near-black with red)
- All variations follow the established 10-slug color pattern for cross-variation pattern compatibility
**Key learnings:**
- Dark style variations swap base/contrast (dark base, light contrast) and use darker shades for the `light` and `dark` slugs to maintain proper surface hierarchy
- Button and link hover states in dark palettes need explicit `color` and `text` overrides since the default theme.json assumes light base
- CSS logical properties (`border-inline-start`, `padding-inline-start`) are the modern approach to RTL support, replacing physical left/right properties
- Twig `|e('html')` filter must be applied *before* concatenation with `|raw` HTML to prevent XSS -- `search_query|e('html')` inside a `|format()` call
- Font preloading via `wp_head` at priority 1 ensures preload hints appear before render-blocking stylesheets
-`aria-live="polite"` with `role="status"` announces dynamic changes to screen readers without interrupting current reading flow
- Offcanvas navigation Twig partial with Bootstrap offcanvas component
- Twig block inheritance in `base.html.twig` for header/footer variant overrides
- Header/footer variant support via `get_theme_mod()` in `ContextBuilder`
- Custom page template routing via `get_page_template_slug()` in `TemplateController`
- Shadow presets, aspect ratios, custom layout values in `theme.json`
- Transparent header and offcanvas dark mode SCSS styles
- Updated translations (`.pot` and `de_CH.po`) with ~70 new translatable strings
**Key learnings:**
- WordPress `block_categories_all` filter (block inserter categories) and `register_block_pattern_category()` (pattern inserter categories) are separate APIs serving different parts of the editor UI
- FSE template parts (`parts/`) use pattern references (`<!-- wp:pattern {"slug":"..."} /-->`) to keep markup in PHP pattern files for i18n support
- Twig blocks (`{% block header %}`) enable page-level templates to override header/footer without modifying `base.html.twig`
-`get_page_template_slug()` returns the custom template slug assigned in the page editor, used in `TemplateController` for routing to the correct Twig template
- Bootstrap SCSS deprecation warnings (Dart Sass 3.0 migration) are upstream issues, not blocking — the build succeeds
**Completed:** Full Twig-based Bootstrap 5 frontend rendering, replacing FSE block markup on the public-facing site.
**What was built:**
-`TemplateController` class hooking `template_redirect` to render Twig templates for all page types
-`ContextBuilder` class gathering WordPress data (posts, menus, pagination, comments, sidebar, archive info) into structured arrays
-`NavWalker` class converting flat menu items to nested tree for Bootstrap dropdown menus
- 20 Twig templates: base layout, 5 page templates (index, single, page, archive, search, 404), 9 partials (header, footer, pagination, sidebar, comments, search form, dark mode toggle, meta, post navigation), 3 components (post card, grid card, post loop)
- Enhanced `TwigService` with WordPress output-buffering functions, globals, and filters
- Navigation menu locations (primary, footer) with pages fallback
- Comment form Bootstrap styling filter
- README.md project documentation
**Key learnings:**
-`template_redirect` + `exit()` cleanly bypasses FSE rendering on frontend while preserving Site Editor functionality
- WordPress functions that produce output (`wp_head`, `wp_footer`, `body_class`, `language_attributes`) must be captured via `ob_start()`/`ob_get_clean()` for use in Twig, and marked with `is_safe => html`
- With `optimize-autoloader: true` in `composer.json`, new PSR-4 classes require `composer dump-autoload` to regenerate the static classmap
- Post content is rendered via `apply_filters('the_content', get_the_content())` which processes Gutenberg blocks into standard HTML that Bootstrap CSS handles natively
- Bootstrap 5 alert colors are hardcoded (not CSS variables), so explicit dark mode overrides are needed in SCSS
- Anti-flash for dark mode requires a synchronous inline script via `wp_add_inline_script('handle', '...', 'before')` — the deferred JS alone causes a flash
- Variable fonts use `fontWeight: "100 900"` range syntax in `theme.json``fontFace` declarations
- Style variation JSON files must maintain identical color slug names across all variations for patterns to work correctly
- When re-tagging a release, delete the remote tag first (`git push origin :refs/tags/vX.X.X`) then recreate and push
### Session 1 — v0.0.1 Getting Started (2026-02-08)