You've already forked wp-bootstrap
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| edf053d7ea | |||
| eb5ac6f7ad | |||
| cc8dc9d357 | |||
| cb288d6e74 | |||
| d069a203b4 | |||
| 0847f5a2d0 |
@@ -113,7 +113,6 @@ jobs:
|
||||
-x "${THEME_NAME}/src/*" \
|
||||
-x "${THEME_NAME}/package.json" \
|
||||
-x "${THEME_NAME}/package-lock.json" \
|
||||
-x "${THEME_NAME}/yarn.lock" \
|
||||
-x "${THEME_NAME}/composer.json" \
|
||||
-x "${THEME_NAME}/composer.lock" \
|
||||
-x "${THEME_NAME}/.gitignore" \
|
||||
|
||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -15,8 +15,8 @@ vendor/
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# Yarn
|
||||
yarn-error.log
|
||||
# npm
|
||||
npm-debug.log
|
||||
|
||||
# Backup files
|
||||
*.bak
|
||||
|
||||
96
CHANGELOG.md
96
CHANGELOG.md
@@ -2,6 +2,100 @@
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
## [0.3.1] - 2026-02-08
|
||||
|
||||
### Added
|
||||
|
||||
- 4 new light style variations: Rose, Sand, Lavender, Mint
|
||||
- 4 new dark style variations: Slate, Mocha, Nebula, Obsidian
|
||||
- Total of 15 color palettes available in the Design Editor (7 light, 7 dark, plus default)
|
||||
|
||||
## [0.3.0] - 2026-02-08
|
||||
|
||||
### Added
|
||||
|
||||
- Skip-to-content link for keyboard navigation accessibility
|
||||
- ARIA labels on all navigation landmarks (`<nav>`, `<aside>`)
|
||||
- `aria-current="page"` on active dropdown menu items across all header variants
|
||||
- Lazy loading (`loading="lazy"`) on all below-fold images (post thumbnails, cards, avatars)
|
||||
- Screen reader announcement for dark mode toggle via `aria-live` status region
|
||||
- Font preload hints for Inter and Lora variable fonts
|
||||
- RTL language support: conditional RTL stylesheet, logical CSS properties for blockquote and list styles
|
||||
- French (fr_FR) translation with all ~216 strings translated
|
||||
- CSS classes for post thumbnails, card thumbnails, sidebar headings, and hero overlays (replacing inline styles)
|
||||
|
||||
### Fixed
|
||||
|
||||
- XSS vulnerability in search results template (`search_query` now escaped with `|e('html')`)
|
||||
- Comment author URLs now explicitly escaped with `esc_url()` in Twig templates
|
||||
|
||||
### Changed
|
||||
|
||||
- Block style `blockquote-accent` uses `border-inline-start` instead of `border-left` for RTL compatibility
|
||||
- Block style `list-unstyled` uses `padding-inline-start` instead of `padding-left` for RTL compatibility
|
||||
- Inline styles in Twig templates replaced with CSS classes for maintainability
|
||||
- Updated translation files (`.pot` and `de_CH.po`) with new accessibility strings
|
||||
- Build pipeline includes RTL SCSS compilation step
|
||||
|
||||
## [0.2.0] - 2026-02-08
|
||||
|
||||
### Added
|
||||
|
||||
- Full Design Editor compatibility: Bootstrap JS in block editor, full Bootstrap SCSS in editor stylesheet
|
||||
- 3 custom block categories: Bootstrap Layout, Bootstrap Components, Bootstrap Navigation
|
||||
- 3 custom pattern categories: Layout, Components, Navigation
|
||||
- 4 layout patterns: container, 2-column, 3-column, full-width section
|
||||
- 2 component patterns: card group, accordion
|
||||
- 3 full-page patterns: about, services, contact
|
||||
- 4 custom page templates (FSE + Twig): landing (no header/footer), full-width, hero, sidebar
|
||||
- 2 header variations (FSE + Twig): centered, transparent
|
||||
- 2 footer variations (FSE + Twig): minimal, multi-column
|
||||
- 2 navigation patterns: dark navbar, offcanvas mobile navigation
|
||||
- Offcanvas navigation Twig partial with Bootstrap offcanvas component
|
||||
- Editor SCSS overrides for alignment and spacing consistency
|
||||
- Shadow presets (sm, md, lg), aspect ratio presets, and custom layout values in `theme.json`
|
||||
- Header/footer variant support via `get_theme_mod()` in `ContextBuilder`
|
||||
- Twig block inheritance in `base.html.twig` for header/footer variant overrides
|
||||
- Custom page template routing via `get_page_template_slug()` in `TemplateController`
|
||||
- Transparent header and offcanvas dark mode SCSS styles
|
||||
|
||||
### Changed
|
||||
|
||||
- Enhanced `editor-style.scss` to import full Bootstrap for WYSIWYG editor fidelity
|
||||
- Enhanced `theme.json` with custom templates and template parts registration
|
||||
- Enhanced `functions.php` with block editor assets, block categories, and pattern categories
|
||||
- Enhanced `ContextBuilder` with header/footer variant methods
|
||||
- Enhanced `TemplateController` with custom page template slug routing
|
||||
- Updated translation files (`.pot` and `de_CH.po`) with all new translatable strings
|
||||
|
||||
## [0.1.1] - 2026-02-08
|
||||
|
||||
### Added
|
||||
|
||||
- Twig-based frontend rendering via `template_redirect` hook, bypassing FSE block markup on the frontend while preserving Site Editor functionality
|
||||
- `TemplateController` class: resolves and renders Twig templates for all page types (home, single, page, archive, search, 404)
|
||||
- `ContextBuilder` class: gathers WordPress data (posts, menus, pagination, comments, sidebar, archive info) into structured arrays for Twig
|
||||
- `NavWalker` class: converts flat `wp_get_nav_menu_items()` into nested tree for Bootstrap dropdown menus
|
||||
- 20 Twig templates with proper Bootstrap 5 HTML: base layout, 5 page templates, 9 partials (header, footer, pagination, sidebar, comments, search form, dark mode toggle, meta, post navigation), 3 components (post card, post grid card, post loop)
|
||||
- Bootstrap 5 navbar with responsive collapse, brand, dropdown support, and dark mode toggle
|
||||
- Bootstrap 5 card components for post listings
|
||||
- Bootstrap 5 pagination component
|
||||
- Bootstrap 5 comment section with threaded replies and Bootstrap-styled form fields
|
||||
- Bootstrap 5 sidebar with recent posts, search, and tag cloud (badges)
|
||||
- Previous/next post navigation and "More posts" grid on single posts
|
||||
- WordPress functions in Twig: `wp_head`, `wp_footer`, `wp_body_open`, `language_attributes`, `body_class`, `home_url`, `get_bloginfo`, `get_search_query`, `wp_kses_post`, `number_format_i18n`, `_n`
|
||||
- Twig globals: `site_name`, `site_description`, `site_url`, `theme_uri`, `charset`, `current_year`
|
||||
- Twig filters: `wpautop`, `wp_kses_post`
|
||||
- `primary` and `footer` navigation menu locations
|
||||
- Comment form fields filter for Bootstrap classes (`form-control`, `form-label`, `form-check`, `btn`)
|
||||
- Fallback menu from published pages when no menu is assigned
|
||||
- Sidebar layout detection for "Blog with Sidebar" template
|
||||
- README.md with project documentation
|
||||
|
||||
### Changed
|
||||
|
||||
- Enhanced `TwigService` with WordPress output-buffering functions, globals, and filters
|
||||
|
||||
## [0.1.0] - 2026-02-08
|
||||
|
||||
### Added
|
||||
@@ -27,7 +121,7 @@ All notable changes to this project will be documented in this file.
|
||||
### Added
|
||||
|
||||
- Initial theme scaffolding
|
||||
- Bootstrap 5 CSS and JS integration (served locally via Yarn)
|
||||
- Bootstrap 5 CSS and JS integration (served locally via npm)
|
||||
- SASS build pipeline with Dart Sass, PostCSS, Autoprefixer, cssnano
|
||||
- Twig 3.0 template engine integration via Composer
|
||||
- FSE templates: index, home, single, page, archive, search, 404
|
||||
|
||||
176
CLAUDE.md
176
CLAUDE.md
@@ -34,19 +34,7 @@ This project is proudly **"vibe-coded"** using Claude.AI - the entire codebase w
|
||||
|
||||
**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.
|
||||
|
||||
### Getting started (v0.0.1)
|
||||
|
||||
- [ ] Create a new Theme, use `wp-core/wp-content/themes/twentytwentyfive/` as blueprint (but not as base-theme, we're building from scratch!).
|
||||
- [ ] Include Bootstrap 5 (CSS/JS) (serve locally, not from CDN, use Yarn for install).
|
||||
- [ ] Use SASS as Stylesheet language, use node-sass for compilation.
|
||||
- [ ] Integrate custom stylesheets using SASS.
|
||||
- [ ] Add Gitea CI/CD workflow to create WordPress compatible release packages. Perform as much as possible build tasks in the workflow.
|
||||
- [ ] Create `PLAN.md` with a comprhensive plan to create the custom theme.
|
||||
- [ ] Create `README.md` with current information.
|
||||
- [ ] Create `CHANGELOG.md` with initial information
|
||||
- [ ] Commit to `main` and `dev`, but don't tag yet. Push to `origin`.
|
||||
|
||||
Planning is moved to `PLAN.md`
|
||||
Current version is **v0.3.1** - Style Variations. Next milestone is **v1.0.0 - Release**. See `PLAN.md` for details.
|
||||
|
||||
## Technical Stack
|
||||
|
||||
@@ -56,7 +44,7 @@ Planning is moved to `PLAN.md`
|
||||
- **Template Engine:** Twig 3.0 (via Composer)
|
||||
- **Frontend:** Bootstrap 5 Javascript & Vanilla JavaScript
|
||||
- **Styling:** Bootstrap 5 & Custom CSS (if necessary)
|
||||
- **Dependency Management:** Composer (PHP), Yarn (JS/CSS)
|
||||
- **Dependency Management:** Composer (PHP), npm (JS/CSS)
|
||||
- **Internationalization:** WordPress i18n (.pot/.po/.mo files)
|
||||
- **Canonical Plugin Name:** `wp-bootstrap`
|
||||
|
||||
@@ -170,3 +158,163 @@ When editing CLAUDE.md or other markdown files, follow these rules to avoid lint
|
||||
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.
|
||||
|
||||
### Build Pipeline
|
||||
|
||||
The build uses npm scripts defined in `package.json`:
|
||||
|
||||
```bash
|
||||
# Full build (CI and local)
|
||||
npm run build
|
||||
|
||||
# Development watch mode
|
||||
npm run dev
|
||||
```
|
||||
|
||||
Build steps (in order):
|
||||
|
||||
1. `copy:js` — Copy Bootstrap JS bundle from `node_modules` to `assets/js/`
|
||||
2. `copy:theme-js` — Copy theme JS (e.g., `dark-mode.js`) from `src/js/` to `assets/js/`
|
||||
3. `scss` — Compile SCSS (`src/scss/`) to CSS (`assets/css/`)
|
||||
4. `postcss` — Autoprefixer + cssnano minification → `assets/css/style.min.css`
|
||||
|
||||
**CI/CD note:** The Gitea workflow uses `npm install` and `npm run build`.
|
||||
|
||||
### Architecture Notes
|
||||
|
||||
- **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.
|
||||
|
||||
## Session History
|
||||
|
||||
### Session 6 — v0.3.1 Style Variations (2026-02-08)
|
||||
|
||||
**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
|
||||
|
||||
### Session 5 — v0.3.0 Polish (2026-02-08)
|
||||
|
||||
**Completed:** Accessibility audit and fixes, security hardening, performance optimization, RTL language support, French translation, inline style cleanup.
|
||||
|
||||
**What was built:**
|
||||
|
||||
- Skip-to-content link in `base.html.twig` with visually-hidden CSS class (visible on focus)
|
||||
- ARIA labels on all `<nav>` elements across 4 header variants, 2 footer variants, and sidebar
|
||||
- `aria-current="page"` on active dropdown items in all header variants
|
||||
- `loading="lazy"` on post thumbnails, card images, and comment avatars
|
||||
- Screen reader announcement (`aria-live="polite"`) in `dark-mode.js` for theme toggle
|
||||
- Font preload `<link>` tags for Inter and Lora `.woff2` files via `wp_head` priority 1
|
||||
- RTL stylesheet (`src/scss/rtl.scss`) conditionally loaded when `is_rtl()` is true
|
||||
- Logical CSS properties (`border-inline-start`, `padding-inline-start`) replacing physical directions in block styles
|
||||
- French translation (`fr_FR.po`) covering all ~216 translatable strings
|
||||
- CSS classes replacing inline styles: `.post-thumbnail`, `.card-thumbnail`, `.sidebar-heading`, `.hero-overlay`
|
||||
- XSS fix in search template: `search_query|e('html')` before `|raw` output
|
||||
- Explicit `esc_url()` on comment author URLs in Twig
|
||||
- Updated `.pot` and `de_CH.po` with 4 new accessibility strings
|
||||
- RTL build step added to npm scripts
|
||||
|
||||
**Key learnings:**
|
||||
|
||||
- WordPress `is_rtl()` detects RTL locales, allowing conditional stylesheet loading without doubling CSS bundle size
|
||||
- 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
|
||||
|
||||
### Session 4 — v0.2.0 Design Editor (2026-02-08)
|
||||
|
||||
**Completed:** Full Design Editor compatibility, custom block categories, page templates, header/footer/navigation variations.
|
||||
|
||||
**What was built:**
|
||||
|
||||
- Enhanced editor stylesheet importing full Bootstrap SCSS for WYSIWYG fidelity
|
||||
- Editor overrides SCSS (`_editor-overrides.scss`) for alignment and spacing
|
||||
- Bootstrap JS loaded in block editor via `enqueue_block_editor_assets`
|
||||
- 3 custom block categories (`block_categories_all` filter): Bootstrap Layout, Components, Navigation
|
||||
- 3 custom pattern categories: Layout, Components, Navigation
|
||||
- 6 layout/component patterns: container, 2-col, 3-col, full-width section, card group, accordion
|
||||
- 3 full-page patterns: about, services, contact
|
||||
- 4 custom page templates (FSE + Twig): landing, full-width, hero, sidebar
|
||||
- 2 header variations (FSE parts + patterns + Twig): centered, transparent
|
||||
- 2 footer variations (FSE parts + patterns + Twig): minimal, multi-column
|
||||
- 2 navigation patterns: dark navbar, offcanvas
|
||||
- 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
|
||||
|
||||
### Session 3 — v0.1.1 Bootstrap Frontend Rendering (2026-02-08)
|
||||
|
||||
**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
|
||||
- Docker bind mounts require absolute paths in `compose.override.yaml` -- relative paths create empty directories
|
||||
- Post content is rendered via `apply_filters('the_content', get_the_content())` which processes Gutenberg blocks into standard HTML that Bootstrap CSS handles natively
|
||||
|
||||
### Session 2 — v0.1.0 Core Theme (2026-02-08)
|
||||
|
||||
**Completed:** Full v0.1.0 milestone implementation.
|
||||
|
||||
**What was built:**
|
||||
|
||||
- 16 block patterns across 7 new categories (hero, features, CTA, testimonials, pricing, contact, text)
|
||||
- Dark mode toggle with SVG sun/moon icons, localStorage persistence, `prefers-color-scheme` detection
|
||||
- 17 custom block styles mapping Bootstrap components to WordPress blocks
|
||||
- 4 style variations: Ocean, Forest, Sunset, Midnight
|
||||
- Sidebar template part + "Blog with Sidebar" custom template
|
||||
- Inter + Lora variable web fonts with Display font size
|
||||
|
||||
**Key learnings:**
|
||||
|
||||
- CI uses `npm install` / `npm run build` — `yarn` is not available in the CI runner
|
||||
- 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)
|
||||
|
||||
**Completed:** Initial theme scaffolding, Bootstrap 5 integration, SASS pipeline, Twig setup, CI/CD workflow, basic FSE templates and patterns, i18n support.
|
||||
|
||||
43
PLAN.md
43
PLAN.md
@@ -10,10 +10,12 @@ WP Bootstrap is a modern WordPress Block Theme built from scratch with Bootstrap
|
||||
|
||||
Full Site Editing (FSE) Block Theme following the WordPress 6.x template hierarchy:
|
||||
|
||||
- **Templates** (`templates/`): HTML files with WordPress block markup
|
||||
- **Template Parts** (`parts/`): Reusable header/footer components
|
||||
- **Templates** (`templates/`): HTML files with WordPress block markup (Site Editor)
|
||||
- **Template Parts** (`parts/`): Reusable header/footer components (Site Editor)
|
||||
- **Patterns** (`patterns/`): PHP files with block markup and i18n support
|
||||
- **Design Tokens** (`theme.json`): Colors, typography, spacing mapped to Bootstrap 5
|
||||
- **Twig Templates** (`views/`): Bootstrap 5 HTML rendered on the frontend via `template_redirect`
|
||||
- **Template Engine** (`inc/Template/`): Controller, context builder, and nav walker for Twig rendering
|
||||
|
||||
### Technology Stack
|
||||
|
||||
@@ -52,21 +54,33 @@ node_modules/bootstrap/dist/js/ → copyfiles → assets/js/bootstrap.bundle.min
|
||||
- [x] Sidebar template part
|
||||
- [x] Enhanced typography settings
|
||||
|
||||
### v0.2.0 - Design Editor
|
||||
### v0.1.1 - Bootstrap Frontend Rendering (Complete)
|
||||
|
||||
- [ ] Full Design Editor compatibility
|
||||
- [ ] Custom block categories
|
||||
- [ ] Page-level patterns and templates
|
||||
- [ ] Enhanced header/footer variations
|
||||
- [ ] Custom navigation styles
|
||||
- [x] Twig-based frontend rendering via `template_redirect` hook
|
||||
- [x] `TemplateController`, `ContextBuilder`, `NavWalker` PHP classes
|
||||
- [x] 20 Twig templates (base layout, pages, partials, components)
|
||||
- [x] Bootstrap 5 navbar, cards, pagination, comments, sidebar
|
||||
- [x] Enhanced `TwigService` with WordPress functions and globals
|
||||
- [x] Navigation menu locations (primary, footer)
|
||||
- [x] Comment form Bootstrap styling
|
||||
- [x] README.md project documentation
|
||||
|
||||
### v0.3.0 - Polish
|
||||
### v0.2.0 - Design Editor (Complete)
|
||||
|
||||
- [ ] Performance optimization (selective Bootstrap imports)
|
||||
- [ ] Accessibility audit and fixes
|
||||
- [ ] RTL language support
|
||||
- [ ] Additional translations
|
||||
- [ ] Documentation
|
||||
- [x] Full Design Editor compatibility
|
||||
- [x] Custom block categories
|
||||
- [x] Page-level patterns and templates
|
||||
- [x] Enhanced header/footer variations
|
||||
- [x] Custom navigation styles
|
||||
|
||||
### v0.3.0 - Polish (Complete)
|
||||
|
||||
- [x] Performance optimization
|
||||
- [x] Accessibility audit and fixes
|
||||
- [x] Security audit and fixes
|
||||
- [x] RTL language support
|
||||
- [x] Additional translations
|
||||
- [x] Documentation
|
||||
|
||||
### v1.0.0 - Release
|
||||
|
||||
@@ -74,6 +88,7 @@ node_modules/bootstrap/dist/js/ → copyfiles → assets/js/bootstrap.bundle.min
|
||||
- [ ] WordPress.org theme review compliance
|
||||
- [ ] Comprehensive documentation
|
||||
- [ ] Full test coverage
|
||||
- [ ] Update `README.md`
|
||||
|
||||
## Bootstrap 5 Integration Strategy
|
||||
|
||||
|
||||
120
README.md
120
README.md
@@ -1,21 +1,28 @@
|
||||
# WP Bootstrap
|
||||
|
||||
A modern WordPress Block Theme built from scratch with Bootstrap 5.
|
||||
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
|
||||
|
||||
- Full Site Editing (FSE) support
|
||||
- Bootstrap 5 CSS and JavaScript
|
||||
- Responsive design
|
||||
- Dark mode ready (Bootstrap 5.3 dark mode variables)
|
||||
- Twig 3.0 template engine
|
||||
- WordPress i18n support
|
||||
- Gitea CI/CD automated releases
|
||||
- **Bootstrap 5 Frontend** -- Proper Bootstrap 5 HTML (navbar, cards, pagination, grid) rendered via Twig templates
|
||||
- **Dark Mode** -- Toggle with localStorage persistence and `prefers-color-scheme` support
|
||||
- **Full Site Editing** -- Compatible with the WordPress Site Editor for admin editing
|
||||
- **Block Patterns** -- 30+ patterns across 10 categories (hero, features, CTA, testimonials, pricing, contact, text, layout, components, navigation)
|
||||
- **Block Styles** -- 17 custom styles mapping Bootstrap components to WordPress blocks
|
||||
- **Style Variations** -- 4 color schemes: Ocean, Forest, Sunset, Midnight
|
||||
- **Custom Templates** -- Landing (no header/footer), full-width, hero, sidebar page templates
|
||||
- **Header/Footer Variations** -- Centered, transparent, minimal, multi-column variants
|
||||
- **Navigation Styles** -- Dark navbar, offcanvas mobile navigation
|
||||
- **Design Editor** -- Full compatibility with the WordPress Site Editor
|
||||
- **Responsive** -- Mobile-first design with Bootstrap's responsive grid
|
||||
- **Translation Ready** -- Full i18n support with `en_US` and `de_CH` translations
|
||||
|
||||
## Requirements
|
||||
|
||||
- WordPress 6.7 or higher
|
||||
- PHP 8.3 or higher
|
||||
- Composer
|
||||
- Node.js 20+
|
||||
|
||||
## Installation
|
||||
|
||||
@@ -31,16 +38,18 @@ A modern WordPress Block Theme built from scratch with Bootstrap 5.
|
||||
git clone ssh://git@src.bundespruefstelle.ch:2022/magdev/wp-bootstrap.git
|
||||
cd wp-bootstrap
|
||||
composer install
|
||||
yarn install
|
||||
yarn build
|
||||
npm install
|
||||
npm run build
|
||||
```
|
||||
|
||||
Activate the theme in **Appearance > Themes** in the WordPress admin.
|
||||
|
||||
## Development
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- Node.js 20+
|
||||
- Yarn
|
||||
- npm
|
||||
- Composer
|
||||
- PHP 8.3+
|
||||
|
||||
@@ -48,33 +57,86 @@ yarn build
|
||||
|
||||
| Command | Description |
|
||||
| --- | --- |
|
||||
| `yarn build` | Compile SCSS, minify CSS, copy Bootstrap JS |
|
||||
| `yarn dev` | Watch SCSS files and recompile on changes |
|
||||
| `yarn scss` | Compile SCSS only |
|
||||
| `yarn postcss` | Minify CSS with Autoprefixer |
|
||||
| `composer install` | Install PHP dependencies |
|
||||
| `npm run build` | Full production build (copy JS, compile SCSS, minify CSS) |
|
||||
| `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) |
|
||||
|
||||
### Build Pipeline
|
||||
|
||||
1. `copy:js` -- Copy Bootstrap JS bundle from `node_modules` to `assets/js/`
|
||||
2. `copy:theme-js` -- Copy theme JS (dark-mode.js) from `src/js/` to `assets/js/`
|
||||
3. `scss` -- Compile SCSS (`src/scss/`) to CSS (`assets/css/`)
|
||||
4. `postcss` -- Autoprefixer + cssnano minification to `assets/css/style.min.css`
|
||||
|
||||
## Architecture
|
||||
|
||||
### Frontend Rendering
|
||||
|
||||
The theme uses a dual-rendering approach:
|
||||
|
||||
- **Site Editor (admin):** FSE block templates in `templates/` and `parts/` for visual editing
|
||||
- **Frontend (public):** Twig templates in `views/` render Bootstrap 5 HTML via the `template_redirect` hook
|
||||
|
||||
The `TemplateController` intercepts frontend requests and renders the appropriate Twig template with data gathered by `ContextBuilder`. FSE templates remain untouched for the WordPress admin editor.
|
||||
|
||||
### 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 |
|
||||
|
||||
### 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.
|
||||
|
||||
### Project Structure
|
||||
|
||||
```txt
|
||||
wp-bootstrap/
|
||||
├── assets/ Compiled CSS, JS, and images
|
||||
├── inc/ PHP classes (PSR-4 autoloaded)
|
||||
├── languages/ Translation files (.pot, .po)
|
||||
├── parts/ FSE template parts (header, footer)
|
||||
├── patterns/ Block patterns
|
||||
├── src/scss/ SCSS source files
|
||||
├── templates/ FSE page templates
|
||||
├── views/ Twig templates
|
||||
├── functions.php Theme bootstrap
|
||||
├── style.css Theme metadata
|
||||
└── theme.json Design tokens and settings
|
||||
+-- assets/ Compiled CSS, JS, fonts
|
||||
+-- inc/
|
||||
| +-- 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)
|
||||
+-- 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
|
||||
|
||||
## License
|
||||
|
||||
GPL-2.0-or-later
|
||||
GPL-2.0-or-later. See <http://www.gnu.org/licenses/gpl-2.0.html>.
|
||||
|
||||
## Author
|
||||
|
||||
Marco Graetsch - [src.bundespruefstelle.ch/magdev](https://src.bundespruefstelle.ch/magdev)
|
||||
Marco Graetsch - <https://src.bundespruefstelle.ch/magdev>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
4
assets/css/rtl.css
Normal file
4
assets/css/rtl.css
Normal file
@@ -0,0 +1,4 @@
|
||||
/*!
|
||||
* WP Bootstrap Theme - RTL Overrides
|
||||
* Right-to-left language support
|
||||
*/.is-style-blockquote-accent{border-left:none;border-right:4px solid var(--wp--preset--color--primary);border-radius:.375rem 0 0 .375rem}
|
||||
@@ -11911,6 +11911,19 @@ h1, .h1, h2, .h2, h3, .h3, h4, .h4, h5, .h5, h6, .h6, blockquote, caption, figca
|
||||
border-radius: 0.25rem;
|
||||
}
|
||||
|
||||
.header-transparent {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
z-index: 1030;
|
||||
}
|
||||
.header-transparent .navbar {
|
||||
background: transparent !important;
|
||||
}
|
||||
|
||||
[data-bs-theme=dark] .offcanvas {
|
||||
--bs-offcanvas-bg: var(--bs-body-bg);
|
||||
}
|
||||
|
||||
[data-bs-theme=dark] .is-style-alert-info {
|
||||
background-color: #032830;
|
||||
border-color: #055160;
|
||||
@@ -11937,4 +11950,41 @@ h1, .h1, h2, .h2, h3, .h3, h4, .h4, h5, .h5, h6, .h6, blockquote, caption, figca
|
||||
background: var(--bs-body-bg);
|
||||
}
|
||||
|
||||
.wp-bootstrap-skip-link {
|
||||
position: absolute;
|
||||
top: -100%;
|
||||
left: 0;
|
||||
z-index: 1040;
|
||||
padding: 0.5rem 1rem;
|
||||
background: var(--bs-primary);
|
||||
color: #fff;
|
||||
text-decoration: none;
|
||||
font-weight: 600;
|
||||
}
|
||||
.wp-bootstrap-skip-link:focus {
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.post-thumbnail {
|
||||
aspect-ratio: 16/9;
|
||||
object-fit: cover;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.card-thumbnail {
|
||||
aspect-ratio: 3/2;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.sidebar-heading {
|
||||
letter-spacing: 1.6px;
|
||||
}
|
||||
|
||||
.hero-overlay {
|
||||
background-position: center;
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
/*# sourceMappingURL=style.css.map */
|
||||
|
||||
File diff suppressed because one or more lines are too long
2
assets/css/style.min.css
vendored
2
assets/css/style.min.css
vendored
File diff suppressed because one or more lines are too long
@@ -61,6 +61,7 @@
|
||||
var newTheme = currentTheme === 'dark' ? 'light' : 'dark';
|
||||
localStorage.setItem(STORAGE_KEY, newTheme);
|
||||
setTheme(newTheme);
|
||||
announceTheme(newTheme);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -71,4 +72,23 @@
|
||||
setTheme(e.matches ? 'dark' : 'light');
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Announce theme change to screen readers via a live region.
|
||||
*
|
||||
* @param {string} theme - 'dark' or 'light'
|
||||
*/
|
||||
function announceTheme(theme) {
|
||||
var msg = theme === 'dark' ? 'Dark mode enabled' : 'Light mode enabled';
|
||||
var el = document.getElementById('wp-bootstrap-theme-status');
|
||||
if (!el) {
|
||||
el = document.createElement('div');
|
||||
el.id = 'wp-bootstrap-theme-status';
|
||||
el.setAttribute('role', 'status');
|
||||
el.setAttribute('aria-live', 'polite');
|
||||
el.className = 'visually-hidden';
|
||||
document.body.appendChild(el);
|
||||
}
|
||||
el.textContent = msg;
|
||||
}
|
||||
})();
|
||||
|
||||
190
functions.php
190
functions.php
@@ -34,6 +34,12 @@ if ( ! function_exists( 'wp_bootstrap_setup' ) ) :
|
||||
|
||||
// Add editor styles.
|
||||
add_editor_style( 'assets/css/editor-style.css' );
|
||||
|
||||
// Register navigation menu locations.
|
||||
register_nav_menus( array(
|
||||
'primary' => __( 'Primary Navigation', 'wp-bootstrap' ),
|
||||
'footer' => __( 'Footer Navigation', 'wp-bootstrap' ),
|
||||
) );
|
||||
}
|
||||
endif;
|
||||
add_action( 'after_setup_theme', 'wp_bootstrap_setup' );
|
||||
@@ -85,6 +91,103 @@ if ( ! function_exists( 'wp_bootstrap_enqueue_scripts' ) ) :
|
||||
endif;
|
||||
add_action( 'wp_enqueue_scripts', 'wp_bootstrap_enqueue_scripts' );
|
||||
|
||||
/**
|
||||
* Preload critical fonts for performance.
|
||||
*
|
||||
* @since 0.3.0
|
||||
*/
|
||||
if ( ! function_exists( 'wp_bootstrap_preload_fonts' ) ) :
|
||||
function wp_bootstrap_preload_fonts() {
|
||||
$fonts = array(
|
||||
'inter/InterVariable.woff2',
|
||||
'lora/Lora-VariableFont.woff2',
|
||||
);
|
||||
$base = get_template_directory_uri() . '/assets/fonts/';
|
||||
foreach ( $fonts as $font ) {
|
||||
printf(
|
||||
'<link rel="preload" href="%s" as="font" type="font/woff2" crossorigin>' . "\n",
|
||||
esc_url( $base . $font )
|
||||
);
|
||||
}
|
||||
}
|
||||
endif;
|
||||
add_action( 'wp_head', 'wp_bootstrap_preload_fonts', 1 );
|
||||
|
||||
/**
|
||||
* Enqueue RTL stylesheet for right-to-left languages.
|
||||
*
|
||||
* @since 0.3.0
|
||||
*/
|
||||
if ( ! function_exists( 'wp_bootstrap_rtl_styles' ) ) :
|
||||
function wp_bootstrap_rtl_styles() {
|
||||
if ( ! is_rtl() ) {
|
||||
return;
|
||||
}
|
||||
$theme_version = wp_get_theme()->get( 'Version' );
|
||||
wp_enqueue_style(
|
||||
'wp-bootstrap-rtl',
|
||||
get_template_directory_uri() . '/assets/css/rtl.css',
|
||||
array( 'wp-bootstrap-style' ),
|
||||
$theme_version
|
||||
);
|
||||
}
|
||||
endif;
|
||||
add_action( 'wp_enqueue_scripts', 'wp_bootstrap_rtl_styles', 20 );
|
||||
|
||||
/**
|
||||
* Enqueue Bootstrap JS in the block editor for interactive previews.
|
||||
*
|
||||
* @since 0.2.0
|
||||
*/
|
||||
if ( ! function_exists( 'wp_bootstrap_enqueue_editor_assets' ) ) :
|
||||
function wp_bootstrap_enqueue_editor_assets() {
|
||||
$theme_version = wp_get_theme()->get( 'Version' );
|
||||
|
||||
wp_enqueue_script(
|
||||
'wp-bootstrap-editor-js',
|
||||
get_template_directory_uri() . '/assets/js/bootstrap.bundle.min.js',
|
||||
array(),
|
||||
$theme_version,
|
||||
true
|
||||
);
|
||||
}
|
||||
endif;
|
||||
add_action( 'enqueue_block_editor_assets', 'wp_bootstrap_enqueue_editor_assets' );
|
||||
|
||||
/**
|
||||
* Register custom block categories for Bootstrap components.
|
||||
*
|
||||
* @since 0.2.0
|
||||
*
|
||||
* @param array $categories Existing block categories.
|
||||
* @param WP_Block_Editor_Context $context Block editor context.
|
||||
* @return array Modified categories.
|
||||
*/
|
||||
if ( ! function_exists( 'wp_bootstrap_block_categories' ) ) :
|
||||
function wp_bootstrap_block_categories( array $categories, $context ): array {
|
||||
$bootstrap_categories = array(
|
||||
array(
|
||||
'slug' => 'wp-bootstrap-layout',
|
||||
'title' => __( 'Bootstrap Layout', 'wp-bootstrap' ),
|
||||
'icon' => 'layout',
|
||||
),
|
||||
array(
|
||||
'slug' => 'wp-bootstrap-components',
|
||||
'title' => __( 'Bootstrap Components', 'wp-bootstrap' ),
|
||||
'icon' => 'grid-view',
|
||||
),
|
||||
array(
|
||||
'slug' => 'wp-bootstrap-navigation',
|
||||
'title' => __( 'Bootstrap Navigation', 'wp-bootstrap' ),
|
||||
'icon' => 'menu',
|
||||
),
|
||||
);
|
||||
|
||||
return array_merge( $bootstrap_categories, $categories );
|
||||
}
|
||||
endif;
|
||||
add_filter( 'block_categories_all', 'wp_bootstrap_block_categories', 10, 2 );
|
||||
|
||||
/**
|
||||
* Register block pattern categories.
|
||||
*/
|
||||
@@ -153,6 +256,30 @@ if ( ! function_exists( 'wp_bootstrap_pattern_categories' ) ) :
|
||||
'description' => __( 'Text-focused content sections.', 'wp-bootstrap' ),
|
||||
)
|
||||
);
|
||||
|
||||
register_block_pattern_category(
|
||||
'wp-bootstrap-layout',
|
||||
array(
|
||||
'label' => __( 'Layout', 'wp-bootstrap' ),
|
||||
'description' => __( 'Layout building blocks for page structure.', 'wp-bootstrap' ),
|
||||
)
|
||||
);
|
||||
|
||||
register_block_pattern_category(
|
||||
'wp-bootstrap-components',
|
||||
array(
|
||||
'label' => __( 'Components', 'wp-bootstrap' ),
|
||||
'description' => __( 'Reusable Bootstrap component patterns.', 'wp-bootstrap' ),
|
||||
)
|
||||
);
|
||||
|
||||
register_block_pattern_category(
|
||||
'wp-bootstrap-navigation',
|
||||
array(
|
||||
'label' => __( 'Navigation', 'wp-bootstrap' ),
|
||||
'description' => __( 'Navigation and header patterns.', 'wp-bootstrap' ),
|
||||
)
|
||||
);
|
||||
}
|
||||
endif;
|
||||
add_action( 'init', 'wp_bootstrap_pattern_categories' );
|
||||
@@ -178,7 +305,7 @@ if ( ! function_exists( 'wp_bootstrap_block_styles' ) ) :
|
||||
'name' => 'list-unstyled',
|
||||
'label' => __( 'Unstyled', 'wp-bootstrap' ),
|
||||
'inline_style' => '
|
||||
ul.is-style-list-unstyled, ol.is-style-list-unstyled { list-style: none; padding-left: 0; }',
|
||||
ul.is-style-list-unstyled, ol.is-style-list-unstyled { list-style: none; padding-inline-start: 0; }',
|
||||
) );
|
||||
|
||||
// core/group - Card.
|
||||
@@ -258,7 +385,7 @@ if ( ! function_exists( 'wp_bootstrap_block_styles' ) ) :
|
||||
'name' => 'blockquote-accent',
|
||||
'label' => __( 'Accent Border', 'wp-bootstrap' ),
|
||||
'inline_style' => '
|
||||
.is-style-blockquote-accent { border-left: 4px solid var(--wp--preset--color--primary); background: var(--wp--preset--color--light); padding: var(--wp--preset--spacing--30); border-radius: 0 0.375rem 0.375rem 0; }',
|
||||
.is-style-blockquote-accent { border-inline-start: 4px solid var(--wp--preset--color--primary); background: var(--wp--preset--color--light); padding: var(--wp--preset--spacing--30); border-start-start-radius: 0; border-start-end-radius: 0.375rem; border-end-end-radius: 0.375rem; border-end-start-radius: 0; }',
|
||||
) );
|
||||
|
||||
// core/image - Shadow.
|
||||
@@ -315,3 +442,62 @@ if ( ! function_exists( 'wp_bootstrap_init_twig' ) ) :
|
||||
}
|
||||
endif;
|
||||
add_action( 'after_setup_theme', 'wp_bootstrap_init_twig' );
|
||||
|
||||
/**
|
||||
* Initialize Twig template controller for frontend rendering.
|
||||
*
|
||||
* Hooks into template_redirect to render Bootstrap 5 HTML
|
||||
* via Twig templates instead of FSE block markup on the frontend.
|
||||
*
|
||||
* @since 0.1.1
|
||||
*/
|
||||
if ( ! function_exists( 'wp_bootstrap_init_templates' ) ) :
|
||||
function wp_bootstrap_init_templates() {
|
||||
if ( class_exists( '\\WPBootstrap\\Template\\TemplateController' ) ) {
|
||||
new \WPBootstrap\Template\TemplateController();
|
||||
}
|
||||
}
|
||||
endif;
|
||||
add_action( 'after_setup_theme', 'wp_bootstrap_init_templates' );
|
||||
|
||||
/**
|
||||
* Customize comment form fields with Bootstrap classes.
|
||||
*
|
||||
* @since 0.1.1
|
||||
*
|
||||
* @param array $fields Default comment form fields.
|
||||
* @return array Modified fields with Bootstrap classes.
|
||||
*/
|
||||
if ( ! function_exists( 'wp_bootstrap_comment_form_fields' ) ) :
|
||||
function wp_bootstrap_comment_form_fields( array $fields ): array {
|
||||
$commenter = wp_get_current_commenter();
|
||||
$required = get_option( 'require_name_email' );
|
||||
$req_attr = $required ? ' required' : '';
|
||||
|
||||
$fields['author'] = '<div class="mb-3">'
|
||||
. '<label for="author" class="form-label">' . __( 'Name', 'wp-bootstrap' ) . ( $required ? ' <span class="text-danger">*</span>' : '' ) . '</label>'
|
||||
. '<input id="author" name="author" type="text" class="form-control" value="' . esc_attr( $commenter['comment_author'] ) . '"' . $req_attr . '>'
|
||||
. '</div>';
|
||||
|
||||
$fields['email'] = '<div class="mb-3">'
|
||||
. '<label for="email" class="form-label">' . __( 'Email', 'wp-bootstrap' ) . ( $required ? ' <span class="text-danger">*</span>' : '' ) . '</label>'
|
||||
. '<input id="email" name="email" type="email" class="form-control" value="' . esc_attr( $commenter['comment_author_email'] ) . '"' . $req_attr . '>'
|
||||
. '</div>';
|
||||
|
||||
$fields['url'] = '<div class="mb-3">'
|
||||
. '<label for="url" class="form-label">' . __( 'Website', 'wp-bootstrap' ) . '</label>'
|
||||
. '<input id="url" name="url" type="url" class="form-control" value="' . esc_attr( $commenter['comment_author_url'] ) . '">'
|
||||
. '</div>';
|
||||
|
||||
if ( isset( $fields['cookies'] ) ) {
|
||||
$fields['cookies'] = '<div class="mb-3 form-check">'
|
||||
. '<input id="wp-comment-cookies-consent" name="wp-comment-cookies-consent" type="checkbox" class="form-check-input" value="yes">'
|
||||
. '<label for="wp-comment-cookies-consent" class="form-check-label">'
|
||||
. __( 'Save my name, email, and website in this browser for the next time I comment.', 'wp-bootstrap' )
|
||||
. '</label></div>';
|
||||
}
|
||||
|
||||
return $fields;
|
||||
}
|
||||
endif;
|
||||
add_filter( 'comment_form_default_fields', 'wp_bootstrap_comment_form_fields' );
|
||||
|
||||
493
inc/Template/ContextBuilder.php
Normal file
493
inc/Template/ContextBuilder.php
Normal file
@@ -0,0 +1,493 @@
|
||||
<?php
|
||||
/**
|
||||
* Twig Template Context Builder.
|
||||
*
|
||||
* Gathers WordPress data into structured arrays for Twig templates.
|
||||
*
|
||||
* @package WPBootstrap
|
||||
* @since 0.1.1
|
||||
*/
|
||||
|
||||
namespace WPBootstrap\Template;
|
||||
|
||||
class ContextBuilder
|
||||
{
|
||||
private NavWalker $navWalker;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->navWalker = new NavWalker();
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the complete context for the current request.
|
||||
*/
|
||||
public function build(): array
|
||||
{
|
||||
$context = [
|
||||
'site' => $this->getSiteData(),
|
||||
'menu' => $this->getMenuData('primary'),
|
||||
'footer_menu' => $this->getMenuData('footer'),
|
||||
'dark_mode' => true,
|
||||
'layout' => 'default',
|
||||
'header_variant' => $this->getHeaderVariant(),
|
||||
'footer_variant' => $this->getFooterVariant(),
|
||||
];
|
||||
|
||||
if (is_singular()) {
|
||||
$context['post'] = $this->getPostData();
|
||||
|
||||
if (is_singular('post')) {
|
||||
$context['comments'] = $this->getCommentsData();
|
||||
$context['post_navigation'] = $this->getPostNavigation();
|
||||
$context['more_posts'] = $this->getMorePosts();
|
||||
}
|
||||
}
|
||||
|
||||
if (is_home() || is_archive() || is_search()) {
|
||||
$context['posts'] = $this->getPostsLoop();
|
||||
$context['pagination'] = $this->getPagination();
|
||||
}
|
||||
|
||||
if (is_archive()) {
|
||||
$context['archive'] = $this->getArchiveData();
|
||||
}
|
||||
|
||||
if (is_search()) {
|
||||
$context['search_query'] = get_search_query();
|
||||
}
|
||||
|
||||
// Sidebar layout detection.
|
||||
if (is_home()) {
|
||||
$pageId = (int) get_option('page_for_posts');
|
||||
if ($pageId) {
|
||||
$templateSlug = get_page_template_slug($pageId);
|
||||
if ($templateSlug === 'home-sidebar') {
|
||||
$context['layout'] = 'sidebar';
|
||||
}
|
||||
}
|
||||
$context['sidebar'] = $this->getSidebarData();
|
||||
}
|
||||
|
||||
return $context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get global site information.
|
||||
*/
|
||||
private function getSiteData(): array
|
||||
{
|
||||
return [
|
||||
'name' => get_bloginfo('name'),
|
||||
'description' => get_bloginfo('description'),
|
||||
'url' => home_url('/'),
|
||||
'charset' => get_bloginfo('charset'),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get navigation menu items for a location.
|
||||
*/
|
||||
private function getMenuData(string $location): array
|
||||
{
|
||||
$locations = get_nav_menu_locations();
|
||||
|
||||
if (isset($locations[$location])) {
|
||||
$menu = wp_get_nav_menu_object($locations[$location]);
|
||||
if ($menu) {
|
||||
$items = wp_get_nav_menu_items($menu->term_id);
|
||||
if ($items) {
|
||||
return $this->navWalker->buildTree($items);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback for primary: list top-level pages.
|
||||
if ($location === 'primary') {
|
||||
return $this->getPagesFallback();
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Fallback menu from published pages.
|
||||
*/
|
||||
private function getPagesFallback(): array
|
||||
{
|
||||
$pages = get_pages([
|
||||
'sort_column' => 'menu_order,post_title',
|
||||
'parent' => 0,
|
||||
]);
|
||||
|
||||
$items = [];
|
||||
foreach ($pages as $page) {
|
||||
$items[] = [
|
||||
'id' => $page->ID,
|
||||
'title' => $page->post_title,
|
||||
'url' => get_permalink($page->ID),
|
||||
'target' => '',
|
||||
'classes' => '',
|
||||
'active' => is_page($page->ID),
|
||||
'children' => [],
|
||||
];
|
||||
}
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get single post/page data.
|
||||
*/
|
||||
private function getPostData(): array
|
||||
{
|
||||
global $post;
|
||||
|
||||
return [
|
||||
'id' => $post->ID,
|
||||
'title' => get_the_title(),
|
||||
'url' => get_permalink(),
|
||||
'content' => apply_filters('the_content', get_the_content()),
|
||||
'excerpt' => get_the_excerpt(),
|
||||
'date' => get_the_date(),
|
||||
'date_iso' => get_the_date('c'),
|
||||
'modified' => get_the_modified_date(),
|
||||
'author' => [
|
||||
'name' => get_the_author(),
|
||||
'url' => get_author_posts_url(get_the_author_meta('ID')),
|
||||
],
|
||||
'thumbnail' => get_the_post_thumbnail_url($post->ID, 'large') ?: '',
|
||||
'categories' => $this->getTermsList('category'),
|
||||
'tags' => $this->getTermsList('post_tag'),
|
||||
'type' => get_post_type(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get posts for the main query loop.
|
||||
*/
|
||||
private function getPostsLoop(): array
|
||||
{
|
||||
global $wp_query;
|
||||
$posts = [];
|
||||
|
||||
if ($wp_query->have_posts()) {
|
||||
while ($wp_query->have_posts()) {
|
||||
$wp_query->the_post();
|
||||
$posts[] = [
|
||||
'id' => get_the_ID(),
|
||||
'title' => get_the_title(),
|
||||
'url' => get_permalink(),
|
||||
'excerpt' => get_the_excerpt(),
|
||||
'date' => get_the_date(),
|
||||
'date_iso' => get_the_date('c'),
|
||||
'author' => [
|
||||
'name' => get_the_author(),
|
||||
'url' => get_author_posts_url(get_the_author_meta('ID')),
|
||||
],
|
||||
'thumbnail' => get_the_post_thumbnail_url(null, 'medium_large') ?: '',
|
||||
'categories' => $this->getTermsList('category'),
|
||||
'tags' => $this->getTermsList('post_tag'),
|
||||
'read_more' => __('Read more', 'wp-bootstrap'),
|
||||
];
|
||||
}
|
||||
wp_reset_postdata();
|
||||
}
|
||||
|
||||
return $posts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build pagination data.
|
||||
*/
|
||||
private function getPagination(): array
|
||||
{
|
||||
global $wp_query;
|
||||
|
||||
$totalPages = (int) $wp_query->max_num_pages;
|
||||
$currentPage = max(1, get_query_var('paged'));
|
||||
|
||||
if ($totalPages <= 1) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$pages = [];
|
||||
for ($i = 1; $i <= $totalPages; $i++) {
|
||||
$pages[] = [
|
||||
'number' => $i,
|
||||
'url' => get_pagenum_link($i),
|
||||
'is_current' => ($i === $currentPage),
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
'pages' => $pages,
|
||||
'current' => $currentPage,
|
||||
'total' => $totalPages,
|
||||
'prev_url' => ($currentPage > 1) ? get_pagenum_link($currentPage - 1) : null,
|
||||
'next_url' => ($currentPage < $totalPages) ? get_pagenum_link($currentPage + 1) : null,
|
||||
'prev_text' => __('Previous', 'wp-bootstrap'),
|
||||
'next_text' => __('Next', 'wp-bootstrap'),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get archive page data.
|
||||
*/
|
||||
private function getArchiveData(): array
|
||||
{
|
||||
return [
|
||||
'title' => get_the_archive_title(),
|
||||
'description' => get_the_archive_description(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get comments for the current post.
|
||||
*/
|
||||
private function getCommentsData(): array
|
||||
{
|
||||
$postId = get_the_ID();
|
||||
$count = (int) get_comments_number($postId);
|
||||
|
||||
$comments = get_comments([
|
||||
'post_id' => $postId,
|
||||
'status' => 'approve',
|
||||
'orderby' => 'comment_date_gmt',
|
||||
'order' => 'ASC',
|
||||
]);
|
||||
|
||||
return [
|
||||
'list' => $this->buildCommentTree($comments),
|
||||
'count' => $count,
|
||||
'title' => sprintf(
|
||||
_n('%s Comment', '%s Comments', $count, 'wp-bootstrap'),
|
||||
number_format_i18n($count)
|
||||
),
|
||||
'form' => $this->getCommentFormHtml(),
|
||||
'is_open' => comments_open($postId),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a nested comment tree from flat comments.
|
||||
*/
|
||||
private function buildCommentTree(array $comments, int $parentId = 0): array
|
||||
{
|
||||
$tree = [];
|
||||
|
||||
foreach ($comments as $comment) {
|
||||
if ((int) $comment->comment_parent !== $parentId) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$tree[] = [
|
||||
'id' => (int) $comment->comment_ID,
|
||||
'author' => $comment->comment_author,
|
||||
'author_url' => $comment->comment_author_url,
|
||||
'avatar_url' => get_avatar_url($comment, ['size' => 40]),
|
||||
'date' => get_comment_date('', $comment),
|
||||
'date_iso' => get_comment_date('c', $comment),
|
||||
'content' => apply_filters('comment_text', $comment->comment_content, $comment),
|
||||
'edit_url' => current_user_can('edit_comment', $comment->comment_ID)
|
||||
? get_edit_comment_link($comment)
|
||||
: '',
|
||||
'reply_url' => get_comment_reply_link([
|
||||
'depth' => 1,
|
||||
'max_depth' => get_option('thread_comments_depth', 5),
|
||||
], $comment),
|
||||
'children' => $this->buildCommentTree($comments, (int) $comment->comment_ID),
|
||||
];
|
||||
}
|
||||
|
||||
return $tree;
|
||||
}
|
||||
|
||||
/**
|
||||
* Capture the WordPress comment form HTML.
|
||||
*/
|
||||
private function getCommentFormHtml(): string
|
||||
{
|
||||
if (! comments_open()) {
|
||||
return '';
|
||||
}
|
||||
|
||||
ob_start();
|
||||
comment_form([
|
||||
'title_reply' => __('Leave a Comment', 'wp-bootstrap'),
|
||||
'title_reply_before' => '<h3 id="reply-title" class="comment-reply-title h5 mb-3">',
|
||||
'title_reply_after' => '</h3>',
|
||||
'class_form' => 'needs-validation',
|
||||
'class_submit' => 'btn btn-primary',
|
||||
'submit_button' => '<input name="%1$s" type="submit" id="%2$s" class="%3$s" value="%4$s" />',
|
||||
'comment_field' => '<div class="mb-3"><label for="comment" class="form-label">' . __('Comment', 'wp-bootstrap') . '</label><textarea id="comment" name="comment" class="form-control" rows="5" required></textarea></div>',
|
||||
]);
|
||||
return ob_get_clean();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get previous/next post navigation.
|
||||
*/
|
||||
private function getPostNavigation(): array
|
||||
{
|
||||
$prev = get_previous_post();
|
||||
$next = get_next_post();
|
||||
|
||||
$navigation = [];
|
||||
|
||||
if ($prev) {
|
||||
$navigation['previous'] = [
|
||||
'title' => get_the_title($prev),
|
||||
'url' => get_permalink($prev),
|
||||
];
|
||||
}
|
||||
|
||||
if ($next) {
|
||||
$navigation['next'] = [
|
||||
'title' => get_the_title($next),
|
||||
'url' => get_permalink($next),
|
||||
];
|
||||
}
|
||||
|
||||
return $navigation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get recent posts for the "More posts" section.
|
||||
*/
|
||||
private function getMorePosts(int $count = 3): array
|
||||
{
|
||||
$currentId = get_the_ID();
|
||||
|
||||
$query = new \WP_Query([
|
||||
'posts_per_page' => $count,
|
||||
'post__not_in' => [$currentId],
|
||||
'orderby' => 'date',
|
||||
'order' => 'DESC',
|
||||
]);
|
||||
|
||||
$posts = [];
|
||||
if ($query->have_posts()) {
|
||||
while ($query->have_posts()) {
|
||||
$query->the_post();
|
||||
$posts[] = [
|
||||
'id' => get_the_ID(),
|
||||
'title' => get_the_title(),
|
||||
'url' => get_permalink(),
|
||||
'date' => get_the_date(),
|
||||
'date_iso' => get_the_date('c'),
|
||||
'thumbnail' => get_the_post_thumbnail_url(null, 'medium_large') ?: '',
|
||||
];
|
||||
}
|
||||
wp_reset_postdata();
|
||||
}
|
||||
|
||||
return $posts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get sidebar widget data.
|
||||
*/
|
||||
private function getSidebarData(): array
|
||||
{
|
||||
return [
|
||||
'recent_posts' => $this->getSidebarRecentPosts(),
|
||||
'tags' => $this->getSidebarTags(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get recent posts for sidebar.
|
||||
*/
|
||||
private function getSidebarRecentPosts(int $count = 4): array
|
||||
{
|
||||
$query = new \WP_Query([
|
||||
'posts_per_page' => $count,
|
||||
'orderby' => 'date',
|
||||
'order' => 'DESC',
|
||||
]);
|
||||
|
||||
$posts = [];
|
||||
if ($query->have_posts()) {
|
||||
while ($query->have_posts()) {
|
||||
$query->the_post();
|
||||
$posts[] = [
|
||||
'title' => get_the_title(),
|
||||
'url' => get_permalink(),
|
||||
'date' => get_the_date(),
|
||||
];
|
||||
}
|
||||
wp_reset_postdata();
|
||||
}
|
||||
|
||||
return $posts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get tags for sidebar tag cloud.
|
||||
*/
|
||||
private function getSidebarTags(int $count = 15): array
|
||||
{
|
||||
$tags = get_tags([
|
||||
'number' => $count,
|
||||
'orderby' => 'count',
|
||||
'order' => 'DESC',
|
||||
]);
|
||||
|
||||
if (! $tags || is_wp_error($tags)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$items = [];
|
||||
foreach ($tags as $tag) {
|
||||
$items[] = [
|
||||
'name' => $tag->name,
|
||||
'url' => get_tag_link($tag->term_id),
|
||||
'count' => $tag->count,
|
||||
];
|
||||
}
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the active header variant.
|
||||
*
|
||||
* @since 0.2.0
|
||||
*/
|
||||
private function getHeaderVariant(): string
|
||||
{
|
||||
return get_theme_mod('wp_bootstrap_header_variant', 'default');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the active footer variant.
|
||||
*
|
||||
* @since 0.2.0
|
||||
*/
|
||||
private function getFooterVariant(): string
|
||||
{
|
||||
return get_theme_mod('wp_bootstrap_footer_variant', 'default');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get terms list for a taxonomy.
|
||||
*/
|
||||
private function getTermsList(string $taxonomy): array
|
||||
{
|
||||
$terms = get_the_terms(get_the_ID(), $taxonomy);
|
||||
if (! $terms || is_wp_error($terms)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$list = [];
|
||||
foreach ($terms as $term) {
|
||||
$list[] = [
|
||||
'name' => $term->name,
|
||||
'url' => get_term_link($term),
|
||||
];
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
}
|
||||
80
inc/Template/NavWalker.php
Normal file
80
inc/Template/NavWalker.php
Normal file
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
/**
|
||||
* Bootstrap 5 Navigation Walker.
|
||||
*
|
||||
* Converts flat WordPress menu items into a nested tree
|
||||
* suitable for rendering Bootstrap navbar dropdowns in Twig.
|
||||
*
|
||||
* @package WPBootstrap
|
||||
* @since 0.1.1
|
||||
*/
|
||||
|
||||
namespace WPBootstrap\Template;
|
||||
|
||||
class NavWalker
|
||||
{
|
||||
/**
|
||||
* Build a nested menu tree from flat WordPress menu items.
|
||||
*
|
||||
* @param array $items Array of WP_Post menu item objects.
|
||||
* @return array Nested array suitable for Twig iteration.
|
||||
*/
|
||||
public function buildTree(array $items): array
|
||||
{
|
||||
$tree = [];
|
||||
$children = [];
|
||||
|
||||
foreach ($items as $item) {
|
||||
$node = [
|
||||
'id' => (int) $item->ID,
|
||||
'title' => $item->title,
|
||||
'url' => $item->url,
|
||||
'target' => $item->target ?: '',
|
||||
'classes' => implode(' ', array_filter($item->classes ?? [])),
|
||||
'active' => $this->isActive($item),
|
||||
'children' => [],
|
||||
];
|
||||
|
||||
if ((int) $item->menu_item_parent === 0) {
|
||||
$tree[$item->ID] = $node;
|
||||
} else {
|
||||
$children[(int) $item->menu_item_parent][] = $node;
|
||||
}
|
||||
}
|
||||
|
||||
// Assign children to their parent items.
|
||||
foreach ($children as $parentId => $childItems) {
|
||||
if (isset($tree[$parentId])) {
|
||||
$tree[$parentId]['children'] = $childItems;
|
||||
}
|
||||
}
|
||||
|
||||
return array_values($tree);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if a menu item is currently active.
|
||||
*/
|
||||
private function isActive(object $item): bool
|
||||
{
|
||||
$classes = $item->classes ?? [];
|
||||
|
||||
if (in_array('current-menu-item', $classes, true)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (in_array('current-menu-ancestor', $classes, true)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($item->object === 'page' && is_page((int) $item->object_id)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($item->object === 'category' && is_category((int) $item->object_id)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
106
inc/Template/TemplateController.php
Normal file
106
inc/Template/TemplateController.php
Normal file
@@ -0,0 +1,106 @@
|
||||
<?php
|
||||
/**
|
||||
* Template Controller.
|
||||
*
|
||||
* Intercepts frontend requests and renders Twig templates
|
||||
* with proper Bootstrap 5 HTML instead of FSE block markup.
|
||||
*
|
||||
* @package WPBootstrap
|
||||
* @since 0.1.1
|
||||
*/
|
||||
|
||||
namespace WPBootstrap\Template;
|
||||
|
||||
use WPBootstrap\Twig\TwigService;
|
||||
|
||||
class TemplateController
|
||||
{
|
||||
private ContextBuilder $contextBuilder;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->contextBuilder = new ContextBuilder();
|
||||
add_action('template_redirect', [$this, 'render']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the appropriate Twig template for the current request.
|
||||
*/
|
||||
public function render(): void
|
||||
{
|
||||
// Skip admin, REST API, and AJAX requests.
|
||||
if (is_admin() || wp_doing_ajax()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (defined('REST_REQUEST') && REST_REQUEST) {
|
||||
return;
|
||||
}
|
||||
|
||||
$template = $this->resolveTemplate();
|
||||
if (! $template) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
$context = $this->contextBuilder->build();
|
||||
$twig = TwigService::getInstance();
|
||||
|
||||
echo $twig->render($template, $context);
|
||||
exit;
|
||||
} catch (\Throwable $e) {
|
||||
// Log the error and fall back to FSE rendering.
|
||||
error_log('WP Bootstrap Twig Error: ' . $e->getMessage() . ' in ' . $e->getFile() . ':' . $e->getLine());
|
||||
if (defined('WP_DEBUG') && WP_DEBUG) {
|
||||
wp_die(
|
||||
'<h1>Template Rendering Error</h1>'
|
||||
. '<p><strong>' . esc_html($e->getMessage()) . '</strong></p>'
|
||||
. '<p>' . esc_html($e->getFile()) . ':' . esc_html($e->getLine()) . '</p>'
|
||||
. '<pre>' . esc_html($e->getTraceAsString()) . '</pre>',
|
||||
'Template Error',
|
||||
['response' => 500]
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine which Twig template to render based on WordPress conditionals.
|
||||
*/
|
||||
private function resolveTemplate(): ?string
|
||||
{
|
||||
if (is_404()) {
|
||||
return 'pages/404.html.twig';
|
||||
}
|
||||
|
||||
if (is_search()) {
|
||||
return 'pages/search.html.twig';
|
||||
}
|
||||
|
||||
if (is_singular('post')) {
|
||||
return 'pages/single.html.twig';
|
||||
}
|
||||
|
||||
if (is_page()) {
|
||||
$slug = get_page_template_slug();
|
||||
return match ($slug) {
|
||||
'page-landing' => 'pages/landing.html.twig',
|
||||
'page-full-width' => 'pages/full-width.html.twig',
|
||||
'page-hero' => 'pages/hero.html.twig',
|
||||
'page-sidebar' => 'pages/page-sidebar.html.twig',
|
||||
default => 'pages/page.html.twig',
|
||||
};
|
||||
}
|
||||
|
||||
if (is_archive()) {
|
||||
return 'pages/archive.html.twig';
|
||||
}
|
||||
|
||||
if (is_home()) {
|
||||
return 'pages/index.html.twig';
|
||||
}
|
||||
|
||||
// Fallback.
|
||||
return 'pages/index.html.twig';
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,7 @@ namespace WPBootstrap\Twig;
|
||||
use Twig\Environment;
|
||||
use Twig\Loader\FilesystemLoader;
|
||||
use Twig\TwigFunction;
|
||||
use Twig\TwigFilter;
|
||||
|
||||
class TwigService
|
||||
{
|
||||
@@ -30,6 +31,8 @@ class TwigService
|
||||
]);
|
||||
|
||||
$this->registerWordPressFunctions();
|
||||
$this->registerWordPressGlobals();
|
||||
$this->registerFilters();
|
||||
}
|
||||
|
||||
public static function getInstance(): self
|
||||
@@ -57,6 +60,7 @@ class TwigService
|
||||
|
||||
private function registerWordPressFunctions(): void
|
||||
{
|
||||
// Translation functions.
|
||||
$this->twig->addFunction(new TwigFunction('__', function (string $text, string $domain = 'wp-bootstrap'): string {
|
||||
return __($text, $domain);
|
||||
}));
|
||||
@@ -65,8 +69,88 @@ class TwigService
|
||||
_e($text, $domain);
|
||||
}));
|
||||
|
||||
$this->twig->addFunction(new TwigFunction('_n', function (string $single, string $plural, int $number, string $domain = 'wp-bootstrap'): string {
|
||||
return _n($single, $plural, $number, $domain);
|
||||
}));
|
||||
|
||||
// Escaping functions.
|
||||
$this->twig->addFunction(new TwigFunction('esc_html', 'esc_html'));
|
||||
$this->twig->addFunction(new TwigFunction('esc_attr', 'esc_attr'));
|
||||
$this->twig->addFunction(new TwigFunction('esc_url', 'esc_url'));
|
||||
|
||||
// WordPress head/footer output (captured via output buffering).
|
||||
$this->twig->addFunction(new TwigFunction('wp_head', function (): string {
|
||||
ob_start();
|
||||
wp_head();
|
||||
return ob_get_clean();
|
||||
}, ['is_safe' => ['html']]));
|
||||
|
||||
$this->twig->addFunction(new TwigFunction('wp_footer', function (): string {
|
||||
ob_start();
|
||||
wp_footer();
|
||||
return ob_get_clean();
|
||||
}, ['is_safe' => ['html']]));
|
||||
|
||||
$this->twig->addFunction(new TwigFunction('wp_body_open', function (): string {
|
||||
ob_start();
|
||||
wp_body_open();
|
||||
return ob_get_clean();
|
||||
}, ['is_safe' => ['html']]));
|
||||
|
||||
// HTML attribute helpers.
|
||||
$this->twig->addFunction(new TwigFunction('language_attributes', function (): string {
|
||||
ob_start();
|
||||
language_attributes();
|
||||
return ob_get_clean();
|
||||
}, ['is_safe' => ['html']]));
|
||||
|
||||
$this->twig->addFunction(new TwigFunction('body_class', function (string $extra = ''): string {
|
||||
ob_start();
|
||||
body_class($extra);
|
||||
return ob_get_clean();
|
||||
}, ['is_safe' => ['html']]));
|
||||
|
||||
// URL and info helpers.
|
||||
$this->twig->addFunction(new TwigFunction('home_url', function (string $path = '/'): string {
|
||||
return home_url($path);
|
||||
}));
|
||||
|
||||
$this->twig->addFunction(new TwigFunction('get_template_directory_uri', function (): string {
|
||||
return get_template_directory_uri();
|
||||
}));
|
||||
|
||||
$this->twig->addFunction(new TwigFunction('get_bloginfo', function (string $show): string {
|
||||
return get_bloginfo($show);
|
||||
}));
|
||||
|
||||
$this->twig->addFunction(new TwigFunction('get_search_query', function (): string {
|
||||
return get_search_query();
|
||||
}));
|
||||
|
||||
// Content filtering.
|
||||
$this->twig->addFunction(new TwigFunction('wp_kses_post', function (string $content): string {
|
||||
return wp_kses_post($content);
|
||||
}, ['is_safe' => ['html']]));
|
||||
|
||||
// Formatting.
|
||||
$this->twig->addFunction(new TwigFunction('number_format_i18n', function (float $number, int $decimals = 0): string {
|
||||
return number_format_i18n($number, $decimals);
|
||||
}));
|
||||
}
|
||||
|
||||
private function registerWordPressGlobals(): void
|
||||
{
|
||||
$this->twig->addGlobal('site_name', get_bloginfo('name'));
|
||||
$this->twig->addGlobal('site_description', get_bloginfo('description'));
|
||||
$this->twig->addGlobal('site_url', home_url('/'));
|
||||
$this->twig->addGlobal('theme_uri', get_template_directory_uri());
|
||||
$this->twig->addGlobal('charset', get_bloginfo('charset'));
|
||||
$this->twig->addGlobal('current_year', date('Y'));
|
||||
}
|
||||
|
||||
private function registerFilters(): void
|
||||
{
|
||||
$this->twig->addFilter(new TwigFilter('wpautop', 'wpautop', ['is_safe' => ['html']]));
|
||||
$this->twig->addFilter(new TwigFilter('wp_kses_post', 'wp_kses_post', ['is_safe' => ['html']]));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: WP Bootstrap 0.1.0\n"
|
||||
"Project-Id-Version: WP Bootstrap 0.3.0\n"
|
||||
"Report-Msgid-Bugs-To: https://src.bundespruefstelle.ch/magdev/wp-bootstrap/issues\n"
|
||||
"POT-Creation-Date: 2026-02-08 00:00+0000\n"
|
||||
"PO-Revision-Date: 2026-02-08 00:00+0000\n"
|
||||
@@ -27,10 +27,12 @@ msgid "A modern WordPress Block Theme built from scratch with Bootstrap 5. Featu
|
||||
msgstr "Ein modernes WordPress Block-Theme, erstellt mit Bootstrap 5. Mit responsivem Design, Darkmode-Unterstützung und voller Kompatibilität mit dem WordPress Site-Editor."
|
||||
|
||||
#: patterns/footer.php
|
||||
#: patterns/footer-columns.php
|
||||
msgid "Powered by %s"
|
||||
msgstr "Betrieben mit %s"
|
||||
|
||||
#: patterns/footer.php
|
||||
#: patterns/footer-columns.php
|
||||
msgid "https://wordpress.org"
|
||||
msgstr "https://de.wordpress.org"
|
||||
|
||||
@@ -91,6 +93,7 @@ msgstr "Erstellen Sie moderne, responsive Websites mit der Leistung von Bootstra
|
||||
#: patterns/hero-cover.php
|
||||
#: patterns/hero-centered.php
|
||||
#: patterns/pricing-3-col.php
|
||||
#: patterns/page-services.php
|
||||
msgid "Get Started"
|
||||
msgstr "Jetzt starten"
|
||||
|
||||
@@ -339,6 +342,8 @@ msgid "Custom Development"
|
||||
msgstr "Individuelle Entwicklung"
|
||||
|
||||
#: patterns/pricing-3-col.php
|
||||
#: patterns/page-services.php
|
||||
#: patterns/page-contact.php
|
||||
msgid "Contact Us"
|
||||
msgstr "Kontaktieren Sie uns"
|
||||
|
||||
@@ -351,6 +356,7 @@ msgid "We would love to hear from you. Reach out through any of the channels bel
|
||||
msgstr "Wir freuen uns von Ihnen zu hören. Kontaktieren Sie uns über einen der folgenden Kanäle."
|
||||
|
||||
#: patterns/contact-info.php
|
||||
#: patterns/page-contact.php
|
||||
msgid "Address"
|
||||
msgstr "Adresse"
|
||||
|
||||
@@ -363,6 +369,7 @@ msgid "8000 Zurich, Switzerland"
|
||||
msgstr "8000 Zürich, Schweiz"
|
||||
|
||||
#: patterns/contact-info.php
|
||||
#: patterns/page-contact.php
|
||||
msgid "Phone"
|
||||
msgstr "Telefon"
|
||||
|
||||
@@ -372,10 +379,12 @@ msgstr "+41 44 123 45 67"
|
||||
|
||||
#: patterns/contact-info.php
|
||||
#: patterns/cta-newsletter.php
|
||||
#: patterns/page-contact.php
|
||||
msgid "Email"
|
||||
msgstr "E-Mail"
|
||||
|
||||
#: patterns/contact-info.php
|
||||
#: patterns/page-contact.php
|
||||
msgid "info@example.com"
|
||||
msgstr "info@example.com"
|
||||
|
||||
@@ -428,6 +437,7 @@ msgid "With years of experience in web development and design, we understand wha
|
||||
msgstr "Mit jahrelanger Erfahrung in Webentwicklung und Design verstehen wir, was nötig ist, um ein Theme zu erstellen, das sowohl leistungsstark als auch einfach zu bedienen ist."
|
||||
|
||||
#: patterns/text-about.php
|
||||
#: patterns/page-about.php
|
||||
msgid "About us image"
|
||||
msgstr "Über-uns-Bild"
|
||||
|
||||
@@ -447,6 +457,14 @@ msgstr "Zum Darkmode wechseln"
|
||||
msgid "Switch to light mode"
|
||||
msgstr "Zum hellen Modus wechseln"
|
||||
|
||||
#: functions.php
|
||||
msgid "Primary Navigation"
|
||||
msgstr "Primäre Navigation"
|
||||
|
||||
#: functions.php
|
||||
msgid "Footer Navigation"
|
||||
msgstr "Fusszeilen-Navigation"
|
||||
|
||||
#: functions.php
|
||||
msgid "Pages"
|
||||
msgstr "Seiten"
|
||||
@@ -570,3 +588,324 @@ msgstr "Klein"
|
||||
#: functions.php
|
||||
msgid "Wide"
|
||||
msgstr "Breit"
|
||||
|
||||
#: functions.php
|
||||
msgid "Name"
|
||||
msgstr "Name"
|
||||
|
||||
#: functions.php
|
||||
msgid "Website"
|
||||
msgstr "Website"
|
||||
|
||||
#: functions.php
|
||||
msgid "Save my name, email, and website in this browser for the next time I comment."
|
||||
msgstr "Meinen Namen, meine E-Mail-Adresse und meine Website in diesem Browser für meinen nächsten Kommentar speichern."
|
||||
|
||||
#: functions.php
|
||||
msgid "Bootstrap Layout"
|
||||
msgstr "Bootstrap-Layout"
|
||||
|
||||
#: functions.php
|
||||
msgid "Bootstrap Components"
|
||||
msgstr "Bootstrap-Komponenten"
|
||||
|
||||
#: functions.php
|
||||
msgid "Bootstrap Navigation"
|
||||
msgstr "Bootstrap-Navigation"
|
||||
|
||||
#: functions.php
|
||||
msgid "Layout"
|
||||
msgstr "Layout"
|
||||
|
||||
#: functions.php
|
||||
msgid "Layout building blocks for page structure."
|
||||
msgstr "Layout-Bausteine für die Seitenstruktur."
|
||||
|
||||
#: functions.php
|
||||
msgid "Components"
|
||||
msgstr "Komponenten"
|
||||
|
||||
#: functions.php
|
||||
msgid "Reusable Bootstrap component patterns."
|
||||
msgstr "Wiederverwendbare Bootstrap-Komponentenvorlagen."
|
||||
|
||||
#: functions.php
|
||||
#: patterns/footer-columns.php
|
||||
msgid "Navigation"
|
||||
msgstr "Navigation"
|
||||
|
||||
#: functions.php
|
||||
msgid "Navigation and header patterns."
|
||||
msgstr "Navigations- und Kopfzeilenvorlagen."
|
||||
|
||||
#: patterns/layout-container.php
|
||||
msgid "Heading goes here"
|
||||
msgstr "Überschrift hier eingeben"
|
||||
|
||||
#: patterns/layout-container.php
|
||||
msgid "This is a content container with constrained width and comfortable padding. Replace this text with your own content."
|
||||
msgstr "Dies ist ein Inhaltscontainer mit begrenzter Breite und komfortablem Innenabstand. Ersetzen Sie diesen Text durch Ihren eigenen Inhalt."
|
||||
|
||||
#: patterns/layout-2-col.php
|
||||
#: patterns/layout-3-col.php
|
||||
msgid "Column One"
|
||||
msgstr "Spalte Eins"
|
||||
|
||||
#: patterns/layout-2-col.php
|
||||
msgid "Add your content here. This column takes up half the available width on larger screens and stacks on mobile devices."
|
||||
msgstr "Fügen Sie hier Ihren Inhalt ein. Diese Spalte nimmt auf grösseren Bildschirmen die Hälfte der verfügbaren Breite ein und wird auf Mobilgeräten gestapelt."
|
||||
|
||||
#: patterns/layout-2-col.php
|
||||
#: patterns/layout-3-col.php
|
||||
msgid "Column Two"
|
||||
msgstr "Spalte Zwei"
|
||||
|
||||
#: patterns/layout-3-col.php
|
||||
msgid "Column Three"
|
||||
msgstr "Spalte Drei"
|
||||
|
||||
#: patterns/layout-3-col.php
|
||||
msgid "Add your content here. This column takes up one third of the available width on larger screens."
|
||||
msgstr "Fügen Sie hier Ihren Inhalt ein. Diese Spalte nimmt auf grösseren Bildschirmen ein Drittel der verfügbaren Breite ein."
|
||||
|
||||
#: patterns/layout-full-width-section.php
|
||||
msgid "Full Width Section Heading"
|
||||
msgstr "Überschrift des Vollbreiten-Abschnitts"
|
||||
|
||||
#: patterns/layout-full-width-section.php
|
||||
msgid "This full-width section stands out with a colored background. Use it to highlight important content, announcements, or calls to action."
|
||||
msgstr "Dieser Vollbreiten-Abschnitt fällt durch einen farbigen Hintergrund auf. Verwenden Sie ihn, um wichtige Inhalte, Ankündigungen oder Handlungsaufforderungen hervorzuheben."
|
||||
|
||||
#: patterns/component-card-group.php
|
||||
msgid "Card One"
|
||||
msgstr "Karte Eins"
|
||||
|
||||
#: patterns/component-card-group.php
|
||||
msgid "Card Two"
|
||||
msgstr "Karte Zwei"
|
||||
|
||||
#: patterns/component-card-group.php
|
||||
msgid "Card Three"
|
||||
msgstr "Karte Drei"
|
||||
|
||||
#: patterns/component-card-group.php
|
||||
msgid "Add a short description for this card. Cards are a great way to organize and present related content."
|
||||
msgstr "Fügen Sie eine kurze Beschreibung für diese Karte hinzu. Karten sind eine hervorragende Möglichkeit, zusammengehörige Inhalte zu organisieren und zu präsentieren."
|
||||
|
||||
#: patterns/component-accordion.php
|
||||
msgid "Accordion"
|
||||
msgstr "Akkordeon"
|
||||
|
||||
#: patterns/component-accordion.php
|
||||
msgid "Click on each item to expand and reveal its content."
|
||||
msgstr "Klicken Sie auf jedes Element, um es aufzuklappen und den Inhalt anzuzeigen."
|
||||
|
||||
#: patterns/component-accordion.php
|
||||
msgid "Accordion Item One"
|
||||
msgstr "Akkordeon-Element Eins"
|
||||
|
||||
#: patterns/component-accordion.php
|
||||
msgid "This is the content for the first accordion item. You can add any blocks inside this details element to create rich, expandable content sections."
|
||||
msgstr "Dies ist der Inhalt des ersten Akkordeon-Elements. Sie können beliebige Blöcke in dieses Details-Element einfügen, um reichhaltige, aufklappbare Inhaltsabschnitte zu erstellen."
|
||||
|
||||
#: patterns/component-accordion.php
|
||||
msgid "Accordion Item Two"
|
||||
msgstr "Akkordeon-Element Zwei"
|
||||
|
||||
#: patterns/component-accordion.php
|
||||
msgid "This is the content for the second accordion item. Details blocks are a native HTML element that provide toggle functionality without JavaScript."
|
||||
msgstr "Dies ist der Inhalt des zweiten Akkordeon-Elements. Details-Blöcke sind native HTML-Elemente, die Aufklappfunktionalität ohne JavaScript bieten."
|
||||
|
||||
#: patterns/component-accordion.php
|
||||
msgid "Accordion Item Three"
|
||||
msgstr "Akkordeon-Element Drei"
|
||||
|
||||
#: patterns/component-accordion.php
|
||||
msgid "This is the content for the third accordion item. Use accordions to organize frequently asked questions, feature lists, or any content that benefits from progressive disclosure."
|
||||
msgstr "Dies ist der Inhalt des dritten Akkordeon-Elements. Verwenden Sie Akkordeons, um häufig gestellte Fragen, Funktionslisten oder andere Inhalte zu organisieren, die von schrittweiser Offenlegung profitieren."
|
||||
|
||||
#: patterns/page-about.php
|
||||
msgid "About Us"
|
||||
msgstr "Über uns"
|
||||
|
||||
#: patterns/page-about.php
|
||||
msgid "Learn more about who we are, what we do, and the people behind our mission."
|
||||
msgstr "Erfahren Sie mehr darüber, wer wir sind, was wir tun und wer hinter unserer Mission steht."
|
||||
|
||||
#: patterns/page-about.php
|
||||
msgid "Our Story"
|
||||
msgstr "Unsere Geschichte"
|
||||
|
||||
#: patterns/page-about.php
|
||||
msgid "Founded with a passion for innovation and excellence, our journey began with a simple idea: to create meaningful solutions that make a real difference. Over the years, we have grown from a small team into a dedicated group of professionals committed to delivering outstanding results."
|
||||
msgstr "Gegründet mit einer Leidenschaft für Innovation und Exzellenz, begann unsere Reise mit einer einfachen Idee: bedeutungsvolle Lösungen zu schaffen, die einen echten Unterschied machen. Im Laufe der Jahre sind wir von einem kleinen Team zu einer engagierten Gruppe von Fachleuten gewachsen, die sich der Erbringung herausragender Ergebnisse verschrieben haben."
|
||||
|
||||
#: patterns/page-about.php
|
||||
msgid "Today, we continue to push boundaries and challenge conventions. Our approach combines creative thinking with proven methodologies, ensuring that every project we undertake meets the highest standards of quality and craftsmanship."
|
||||
msgstr "Heute stossen wir weiterhin Grenzen und hinterfragen Konventionen. Unser Ansatz verbindet kreatives Denken mit bewährten Methoden und stellt sicher, dass jedes Projekt, das wir übernehmen, den höchsten Qualitäts- und Handwerksstandards entspricht."
|
||||
|
||||
#: patterns/page-about.php
|
||||
msgid "Our Team"
|
||||
msgstr "Unser Team"
|
||||
|
||||
#: patterns/page-about.php
|
||||
msgid "Meet the people who make it all happen."
|
||||
msgstr "Lernen Sie die Menschen kennen, die alles möglich machen."
|
||||
|
||||
#: patterns/page-about.php
|
||||
msgid "Jane Doe"
|
||||
msgstr "Jane Doe"
|
||||
|
||||
#: patterns/page-about.php
|
||||
msgid "Founder & CEO"
|
||||
msgstr "Gründerin & CEO"
|
||||
|
||||
#: patterns/page-about.php
|
||||
msgid "John Smith"
|
||||
msgstr "John Smith"
|
||||
|
||||
#: patterns/page-about.php
|
||||
msgid "Lead Developer"
|
||||
msgstr "Leitender Entwickler"
|
||||
|
||||
#: patterns/page-about.php
|
||||
msgid "Emily Johnson"
|
||||
msgstr "Emily Johnson"
|
||||
|
||||
#: patterns/page-about.php
|
||||
msgid "Creative Director"
|
||||
msgstr "Kreativdirektorin"
|
||||
|
||||
#: patterns/page-services.php
|
||||
msgid "Our Services"
|
||||
msgstr "Unsere Dienstleistungen"
|
||||
|
||||
#: patterns/page-services.php
|
||||
msgid "Professional solutions tailored to your needs."
|
||||
msgstr "Professionelle Lösungen, massgeschneidert auf Ihre Bedürfnisse."
|
||||
|
||||
#: patterns/page-services.php
|
||||
msgid "What We Offer"
|
||||
msgstr "Was wir anbieten"
|
||||
|
||||
#: patterns/page-services.php
|
||||
msgid "We provide a wide range of services to help your business grow and succeed."
|
||||
msgstr "Wir bieten ein breites Spektrum an Dienstleistungen, um Ihr Unternehmen beim Wachstum und Erfolg zu unterstützen."
|
||||
|
||||
#: patterns/page-services.php
|
||||
msgid "Design"
|
||||
msgstr "Design"
|
||||
|
||||
#: patterns/page-services.php
|
||||
msgid "Beautiful, user-centered designs that capture your brand identity and engage your audience across all platforms and devices."
|
||||
msgstr "Schöne, benutzerzentrierte Designs, die Ihre Markenidentität einfangen und Ihr Publikum auf allen Plattformen und Geräten ansprechen."
|
||||
|
||||
#: patterns/page-services.php
|
||||
msgid "Development"
|
||||
msgstr "Entwicklung"
|
||||
|
||||
#: patterns/page-services.php
|
||||
msgid "Robust, scalable web applications built with modern technologies and best practices to ensure performance and reliability."
|
||||
msgstr "Robuste, skalierbare Webanwendungen, erstellt mit modernen Technologien und bewährten Methoden, um Leistung und Zuverlässigkeit zu gewährleisten."
|
||||
|
||||
#: patterns/page-services.php
|
||||
msgid "Strategy"
|
||||
msgstr "Strategie"
|
||||
|
||||
#: patterns/page-services.php
|
||||
msgid "Data-driven strategies and consulting to help you achieve your business goals and stay ahead of the competition."
|
||||
msgstr "Datengetriebene Strategien und Beratung, um Ihnen zu helfen, Ihre Geschäftsziele zu erreichen und der Konkurrenz voraus zu sein."
|
||||
|
||||
#: patterns/page-services.php
|
||||
msgid "Ready to take your project to the next level? Let us help you build something great."
|
||||
msgstr "Bereit, Ihr Projekt auf die nächste Stufe zu heben? Lassen Sie uns Ihnen helfen, etwas Grossartiges zu bauen."
|
||||
|
||||
#: patterns/page-services.php
|
||||
msgid "View Portfolio"
|
||||
msgstr "Portfolio ansehen"
|
||||
|
||||
#: patterns/page-contact.php
|
||||
msgid "We would love to hear from you. Reach out to us anytime."
|
||||
msgstr "Wir freuen uns von Ihnen zu hören. Kontaktieren Sie uns jederzeit."
|
||||
|
||||
#: patterns/page-contact.php
|
||||
msgid "Get in Touch"
|
||||
msgstr "Kontakt aufnehmen"
|
||||
|
||||
#: patterns/page-contact.php
|
||||
msgid "123 Main Street, Suite 100, Anytown, ST 12345"
|
||||
msgstr "Hauptstrasse 123, Suite 100, 8000 Zürich"
|
||||
|
||||
#: patterns/page-contact.php
|
||||
msgid "+1 (555) 123-4567"
|
||||
msgstr "+41 44 123 45 67"
|
||||
|
||||
#: patterns/page-contact.php
|
||||
msgid "Business Hours"
|
||||
msgstr "Öffnungszeiten"
|
||||
|
||||
#: patterns/page-contact.php
|
||||
msgid "Monday - Friday:"
|
||||
msgstr "Montag - Freitag:"
|
||||
|
||||
#: patterns/page-contact.php
|
||||
msgid "9:00 AM - 6:00 PM"
|
||||
msgstr "09:00 - 18:00 Uhr"
|
||||
|
||||
#: patterns/page-contact.php
|
||||
msgid "Saturday:"
|
||||
msgstr "Samstag:"
|
||||
|
||||
#: patterns/page-contact.php
|
||||
msgid "10:00 AM - 4:00 PM"
|
||||
msgstr "10:00 - 16:00 Uhr"
|
||||
|
||||
#: patterns/page-contact.php
|
||||
msgid "Sunday:"
|
||||
msgstr "Sonntag:"
|
||||
|
||||
#: patterns/page-contact.php
|
||||
msgid "Closed"
|
||||
msgstr "Geschlossen"
|
||||
|
||||
#. translators: Copyright notice. %1$s: Year, %2$s: Site title.
|
||||
#: patterns/footer-minimal.php
|
||||
msgid "© %1$s %2$s. All rights reserved."
|
||||
msgstr "© %1$s %2$s. Alle Rechte vorbehalten."
|
||||
|
||||
#: patterns/footer-columns.php
|
||||
msgid "A modern WordPress theme built with Bootstrap 5."
|
||||
msgstr "Ein modernes WordPress-Theme, erstellt mit Bootstrap 5."
|
||||
|
||||
#: patterns/footer-columns.php
|
||||
msgid "About"
|
||||
msgstr "Über"
|
||||
|
||||
#: patterns/footer-columns.php
|
||||
msgid "This theme is proudly built with Bootstrap 5 and WordPress Full Site Editing."
|
||||
msgstr "Dieses Theme wurde mit Stolz mit Bootstrap 5 und WordPress Full Site Editing erstellt."
|
||||
|
||||
#. translators: Copyright notice. %1$s: Year, %2$s: Site title.
|
||||
#: patterns/footer-columns.php
|
||||
msgid "© %1$s %2$s"
|
||||
msgstr "© %1$s %2$s"
|
||||
|
||||
#: views/base.html.twig
|
||||
msgid "Skip to main content"
|
||||
msgstr "Zum Hauptinhalt springen"
|
||||
|
||||
#: views/partials/header.html.twig
|
||||
#: views/partials/header-centered.html.twig
|
||||
#: views/partials/header-transparent.html.twig
|
||||
#: views/partials/header-offcanvas.html.twig
|
||||
msgid "Primary navigation"
|
||||
msgstr "Hauptnavigation"
|
||||
|
||||
#: views/partials/footer.html.twig
|
||||
#: views/partials/footer-columns.html.twig
|
||||
msgid "Footer navigation"
|
||||
msgstr "Fussnavigation"
|
||||
|
||||
#: views/partials/sidebar.html.twig
|
||||
msgid "Blog sidebar"
|
||||
msgstr "Blog-Seitenleiste"
|
||||
|
||||
909
languages/fr_FR.po
Normal file
909
languages/fr_FR.po
Normal file
@@ -0,0 +1,909 @@
|
||||
# French translation for WP Bootstrap theme.
|
||||
# Copyright (C) 2026 Marco Graetsch
|
||||
# This file is distributed under the same license as the WP Bootstrap theme.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: WP Bootstrap 0.3.0\n"
|
||||
"Report-Msgid-Bugs-To: https://src.bundespruefstelle.ch/magdev/wp-bootstrap/issues\n"
|
||||
"POT-Creation-Date: 2026-02-08 00:00+0000\n"
|
||||
"PO-Revision-Date: 2026-02-08 00:00+0000\n"
|
||||
"Last-Translator: Claude AI <noreply@anthropic.com>\n"
|
||||
"Language-Team: French\n"
|
||||
"Language: fr_FR\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Domain: wp-bootstrap\n"
|
||||
|
||||
#. Theme Name of the theme
|
||||
#: patterns/footer.php
|
||||
msgid "WP Bootstrap"
|
||||
msgstr "WP Bootstrap"
|
||||
|
||||
#. Description of the theme
|
||||
msgid "A modern WordPress Block Theme built from scratch with Bootstrap 5. Features responsive design, dark mode support, and full compatibility with the WordPress Site Editor."
|
||||
msgstr "Un theme WordPress Block moderne construit de zéro avec Bootstrap 5. Design réactif, prise en charge du mode sombre et compatibilité totale avec l'éditeur de site WordPress."
|
||||
|
||||
#: patterns/footer.php
|
||||
#: patterns/footer-columns.php
|
||||
msgid "Powered by %s"
|
||||
msgstr "Propulsé par %s"
|
||||
|
||||
#: patterns/footer.php
|
||||
#: patterns/footer-columns.php
|
||||
msgid "https://wordpress.org"
|
||||
msgstr "https://fr.wordpress.org"
|
||||
|
||||
#: patterns/hidden-404.php
|
||||
msgid "Page not found"
|
||||
msgstr "Page non trouvée"
|
||||
|
||||
#: patterns/hidden-404.php
|
||||
msgid "The page you are looking for does not exist, or it has been moved. Please try searching using the form below."
|
||||
msgstr "La page que vous recherchez n'existe pas ou a été déplacée. Veuillez essayer de rechercher en utilisant le formulaire ci-dessous."
|
||||
|
||||
#: patterns/hidden-search.php
|
||||
#: patterns/hidden-sidebar.php
|
||||
msgid "Search"
|
||||
msgstr "Rechercher"
|
||||
|
||||
#: patterns/hidden-search.php
|
||||
#: patterns/hidden-sidebar.php
|
||||
msgid "Search..."
|
||||
msgstr "Rechercher..."
|
||||
|
||||
#: patterns/hidden-blog-heading.php
|
||||
msgid "Blog"
|
||||
msgstr "Blog"
|
||||
|
||||
#: patterns/comments.php
|
||||
msgid "Comments"
|
||||
msgstr "Commentaires"
|
||||
|
||||
#: patterns/post-navigation.php
|
||||
msgid "Previous"
|
||||
msgstr "Précédent"
|
||||
|
||||
#: patterns/post-navigation.php
|
||||
msgid "Next"
|
||||
msgstr "Suivant"
|
||||
|
||||
#: patterns/more-posts.php
|
||||
msgid "More posts"
|
||||
msgstr "Plus d'articles"
|
||||
|
||||
#: patterns/template-query-loop.php
|
||||
msgid "Read more"
|
||||
msgstr "Lire la suite"
|
||||
|
||||
#: patterns/template-query-loop.php
|
||||
msgid "No posts were found."
|
||||
msgstr "Aucun article n'a été trouvé."
|
||||
|
||||
#: patterns/hero-cover.php
|
||||
msgid "Build something amazing"
|
||||
msgstr "Créez quelque chose d'incroyable"
|
||||
|
||||
#: patterns/hero-cover.php
|
||||
msgid "Create modern, responsive websites with the power of Bootstrap 5 and the WordPress Site Editor."
|
||||
msgstr "Créez des sites web modernes et réactifs grâce à la puissance de Bootstrap 5 et de l'éditeur de site WordPress."
|
||||
|
||||
#: patterns/hero-cover.php
|
||||
#: patterns/hero-centered.php
|
||||
#: patterns/pricing-3-col.php
|
||||
#: patterns/page-services.php
|
||||
msgid "Get Started"
|
||||
msgstr "Commencer"
|
||||
|
||||
#: patterns/hero-split.php
|
||||
msgid "Modern design meets powerful features"
|
||||
msgstr "Un design moderne allié à des fonctionnalités puissantes"
|
||||
|
||||
#: patterns/hero-split.php
|
||||
msgid "A WordPress theme built from the ground up with Bootstrap 5 for a seamless editing and browsing experience."
|
||||
msgstr "Un thème WordPress construit de zéro avec Bootstrap 5 pour une expérience d'édition et de navigation fluide."
|
||||
|
||||
#: patterns/hero-split.php
|
||||
#: patterns/hero-centered.php
|
||||
#: patterns/text-about.php
|
||||
msgid "Learn More"
|
||||
msgstr "En savoir plus"
|
||||
|
||||
#: patterns/hero-split.php
|
||||
msgid "View Demo"
|
||||
msgstr "Voir la démo"
|
||||
|
||||
#: patterns/hero-split.php
|
||||
msgid "Hero image"
|
||||
msgstr "Image héros"
|
||||
|
||||
#: patterns/hero-centered.php
|
||||
msgid "Welcome to your new website"
|
||||
msgstr "Bienvenue sur votre nouveau site web"
|
||||
|
||||
#: patterns/hero-centered.php
|
||||
msgid "Start building beautiful, responsive pages with the full power of Bootstrap 5 and the WordPress block editor."
|
||||
msgstr "Commencez à créer de belles pages réactives avec toute la puissance de Bootstrap 5 et de l'éditeur de blocs WordPress."
|
||||
|
||||
#: patterns/features-3-col.php
|
||||
#: functions.php
|
||||
msgid "Features"
|
||||
msgstr "Fonctionnalités"
|
||||
|
||||
#: patterns/features-3-col.php
|
||||
msgid "Everything you need to build a modern website."
|
||||
msgstr "Tout ce dont vous avez besoin pour créer un site web moderne."
|
||||
|
||||
#: patterns/features-3-col.php
|
||||
msgid "Responsive Design"
|
||||
msgstr "Design réactif"
|
||||
|
||||
#: patterns/features-3-col.php
|
||||
msgid "Your website looks great on every device, from mobile phones to large desktop screens."
|
||||
msgstr "Votre site web est superbe sur tous les appareils, des téléphones mobiles aux grands écrans de bureau."
|
||||
|
||||
#: patterns/features-3-col.php
|
||||
msgid "Easy Customization"
|
||||
msgstr "Personnalisation facile"
|
||||
|
||||
#: patterns/features-3-col.php
|
||||
msgid "Customize colors, fonts, and layouts using the WordPress Site Editor with no code required."
|
||||
msgstr "Personnalisez les couleurs, les polices et les mises en page avec l'éditeur de site WordPress, sans aucun code requis."
|
||||
|
||||
#: patterns/features-3-col.php
|
||||
msgid "Performance First"
|
||||
msgstr "La performance avant tout"
|
||||
|
||||
#: patterns/features-3-col.php
|
||||
msgid "Built with speed in mind. Optimized assets and clean code for lightning-fast page loads."
|
||||
msgstr "Conçu pour la vitesse. Ressources optimisées et code propre pour des chargements de pages ultra-rapides."
|
||||
|
||||
#: patterns/features-icon-list.php
|
||||
msgid "Why choose us"
|
||||
msgstr "Pourquoi nous choisir"
|
||||
|
||||
#: patterns/features-icon-list.php
|
||||
msgid "Bootstrap 5 Framework"
|
||||
msgstr "Framework Bootstrap 5"
|
||||
|
||||
#: patterns/features-icon-list.php
|
||||
msgid "Built on the most popular CSS framework. Leverage a proven, well-documented design system."
|
||||
msgstr "Construit sur le framework CSS le plus populaire. Tirez parti d'un système de design éprouvé et bien documenté."
|
||||
|
||||
#: patterns/features-icon-list.php
|
||||
msgid "Full Site Editing"
|
||||
msgstr "Édition complète du site"
|
||||
|
||||
#: patterns/features-icon-list.php
|
||||
msgid "Edit every part of your site visually. Headers, footers, templates, and content are all customizable."
|
||||
msgstr "Modifiez chaque partie de votre site visuellement. En-têtes, pieds de page, modèles et contenu sont tous personnalisables."
|
||||
|
||||
#: patterns/features-icon-list.php
|
||||
msgid "Dark Mode Support"
|
||||
msgstr "Prise en charge du mode sombre"
|
||||
|
||||
#: patterns/features-icon-list.php
|
||||
msgid "Built-in dark mode toggle that respects user preferences and persists across visits."
|
||||
msgstr "Bouton de mode sombre intégré qui respecte les préférences de l'utilisateur et persiste entre les visites."
|
||||
|
||||
#: patterns/features-2-col-offset.php
|
||||
msgid "Feature illustration"
|
||||
msgstr "Illustration de fonctionnalité"
|
||||
|
||||
#: patterns/features-2-col-offset.php
|
||||
msgid "Designed for modern workflows"
|
||||
msgstr "Conçu pour les flux de travail modernes"
|
||||
|
||||
#: patterns/features-2-col-offset.php
|
||||
msgid "Streamline your development process with a theme that works the way you do."
|
||||
msgstr "Optimisez votre processus de développement avec un thème qui fonctionne comme vous."
|
||||
|
||||
#: patterns/features-2-col-offset.php
|
||||
msgid "Block Patterns"
|
||||
msgstr "Modèles de blocs"
|
||||
|
||||
#: patterns/features-2-col-offset.php
|
||||
msgid "Pre-built patterns for common page sections. Drop them in and customize to fit your needs."
|
||||
msgstr "Modèles préconçus pour les sections de page courantes. Insérez-les et personnalisez-les selon vos besoins."
|
||||
|
||||
#: patterns/features-2-col-offset.php
|
||||
msgid "Style Variations"
|
||||
msgstr "Variations de style"
|
||||
|
||||
#: patterns/features-2-col-offset.php
|
||||
msgid "Switch between color schemes with a single click. Choose from multiple professionally designed palettes."
|
||||
msgstr "Basculez entre les palettes de couleurs en un seul clic. Choisissez parmi plusieurs palettes conçues professionnellement."
|
||||
|
||||
#: patterns/cta-banner.php
|
||||
msgid "Ready to get started?"
|
||||
msgstr "Prêt à commencer ?"
|
||||
|
||||
#: patterns/cta-banner.php
|
||||
msgid "Start building your website today with our powerful and flexible theme."
|
||||
msgstr "Commencez à créer votre site web dès aujourd'hui avec notre thème puissant et flexible."
|
||||
|
||||
#: patterns/cta-banner.php
|
||||
msgid "Start Now"
|
||||
msgstr "Commencer maintenant"
|
||||
|
||||
#: patterns/cta-newsletter.php
|
||||
msgid "Stay in the loop"
|
||||
msgstr "Restez informé"
|
||||
|
||||
#: patterns/cta-newsletter.php
|
||||
msgid "Subscribe to our newsletter for updates, tips, and exclusive content."
|
||||
msgstr "Abonnez-vous à notre newsletter pour des mises à jour, des conseils et du contenu exclusif."
|
||||
|
||||
#: patterns/cta-newsletter.php
|
||||
msgid "Enter your email address"
|
||||
msgstr "Entrez votre adresse courriel"
|
||||
|
||||
#: patterns/cta-newsletter.php
|
||||
msgid "Subscribe"
|
||||
msgstr "S'abonner"
|
||||
|
||||
#: patterns/testimonials-2-col.php
|
||||
msgid "What our clients say"
|
||||
msgstr "Ce que disent nos clients"
|
||||
|
||||
#: patterns/testimonials-2-col.php
|
||||
msgid "This theme completely transformed our website. The Bootstrap integration makes it incredibly easy to create professional-looking pages without any custom code."
|
||||
msgstr "Ce thème a complètement transformé notre site web. L'intégration de Bootstrap rend incroyablement facile la création de pages d'aspect professionnel sans aucun code personnalisé."
|
||||
|
||||
#: patterns/testimonials-2-col.php
|
||||
msgid "Jane Doe, Web Designer"
|
||||
msgstr "Jane Doe, Webdesigneuse"
|
||||
|
||||
#: patterns/testimonials-2-col.php
|
||||
msgid "The dark mode support and style variations give us the flexibility we need. Our clients love being able to switch between color schemes effortlessly."
|
||||
msgstr "La prise en charge du mode sombre et les variations de style nous donnent la flexibilité dont nous avons besoin. Nos clients adorent pouvoir basculer entre les palettes de couleurs sans effort."
|
||||
|
||||
#: patterns/testimonials-2-col.php
|
||||
msgid "John Smith, Developer"
|
||||
msgstr "John Smith, Développeur"
|
||||
|
||||
#: patterns/testimonials-centered.php
|
||||
msgid "The best WordPress theme we have ever used. Clean code, beautiful design, and incredible flexibility."
|
||||
msgstr "Le meilleur thème WordPress que nous ayons jamais utilisé. Code propre, beau design et flexibilité incroyable."
|
||||
|
||||
#: patterns/testimonials-centered.php
|
||||
msgid "Alex Johnson, Creative Director"
|
||||
msgstr "Alex Johnson, Directeur créatif"
|
||||
|
||||
#: patterns/pricing-3-col.php
|
||||
#: functions.php
|
||||
msgid "Pricing"
|
||||
msgstr "Tarifs"
|
||||
|
||||
#: patterns/pricing-3-col.php
|
||||
msgid "Choose the plan that works best for you."
|
||||
msgstr "Choisissez le forfait qui vous convient le mieux."
|
||||
|
||||
#: patterns/pricing-3-col.php
|
||||
msgid "Basic"
|
||||
msgstr "Basique"
|
||||
|
||||
#: patterns/pricing-3-col.php
|
||||
msgid "Free"
|
||||
msgstr "Gratuit"
|
||||
|
||||
#: patterns/pricing-3-col.php
|
||||
msgid "1 Website"
|
||||
msgstr "1 site web"
|
||||
|
||||
#: patterns/pricing-3-col.php
|
||||
msgid "Community Support"
|
||||
msgstr "Support communautaire"
|
||||
|
||||
#: patterns/pricing-3-col.php
|
||||
msgid "Core Features"
|
||||
msgstr "Fonctionnalités de base"
|
||||
|
||||
#: patterns/pricing-3-col.php
|
||||
msgid "Professional"
|
||||
msgstr "Professionnel"
|
||||
|
||||
#: patterns/pricing-3-col.php
|
||||
msgid "$49"
|
||||
msgstr "49 $"
|
||||
|
||||
#: patterns/pricing-3-col.php
|
||||
msgid "5 Websites"
|
||||
msgstr "5 sites web"
|
||||
|
||||
#: patterns/pricing-3-col.php
|
||||
msgid "Priority Support"
|
||||
msgstr "Support prioritaire"
|
||||
|
||||
#: patterns/pricing-3-col.php
|
||||
msgid "All Features"
|
||||
msgstr "Toutes les fonctionnalités"
|
||||
|
||||
#: patterns/pricing-3-col.php
|
||||
msgid "Enterprise"
|
||||
msgstr "Entreprise"
|
||||
|
||||
#: patterns/pricing-3-col.php
|
||||
msgid "$199"
|
||||
msgstr "199 $"
|
||||
|
||||
#: patterns/pricing-3-col.php
|
||||
msgid "Unlimited Websites"
|
||||
msgstr "Sites web illimités"
|
||||
|
||||
#: patterns/pricing-3-col.php
|
||||
msgid "Dedicated Support"
|
||||
msgstr "Support dédié"
|
||||
|
||||
#: patterns/pricing-3-col.php
|
||||
msgid "Custom Development"
|
||||
msgstr "Développement sur mesure"
|
||||
|
||||
#: patterns/pricing-3-col.php
|
||||
#: patterns/page-services.php
|
||||
#: patterns/page-contact.php
|
||||
msgid "Contact Us"
|
||||
msgstr "Contactez-nous"
|
||||
|
||||
#: patterns/contact-info.php
|
||||
msgid "Get in touch"
|
||||
msgstr "Prenez contact"
|
||||
|
||||
#: patterns/contact-info.php
|
||||
msgid "We would love to hear from you. Reach out through any of the channels below."
|
||||
msgstr "Nous serions ravis d'avoir de vos nouvelles. Contactez-nous via l'un des canaux ci-dessous."
|
||||
|
||||
#: patterns/contact-info.php
|
||||
#: patterns/page-contact.php
|
||||
msgid "Address"
|
||||
msgstr "Adresse"
|
||||
|
||||
#: patterns/contact-info.php
|
||||
msgid "123 Example Street"
|
||||
msgstr "123, rue de l'Exemple"
|
||||
|
||||
#: patterns/contact-info.php
|
||||
msgid "8000 Zurich, Switzerland"
|
||||
msgstr "8000 Zurich, Suisse"
|
||||
|
||||
#: patterns/contact-info.php
|
||||
#: patterns/page-contact.php
|
||||
msgid "Phone"
|
||||
msgstr "Téléphone"
|
||||
|
||||
#: patterns/contact-info.php
|
||||
msgid "+41 44 123 45 67"
|
||||
msgstr "+41 44 123 45 67"
|
||||
|
||||
#: patterns/contact-info.php
|
||||
#: patterns/cta-newsletter.php
|
||||
#: patterns/page-contact.php
|
||||
msgid "Email"
|
||||
msgstr "Courriel"
|
||||
|
||||
#: patterns/contact-info.php
|
||||
#: patterns/page-contact.php
|
||||
msgid "info@example.com"
|
||||
msgstr "info@example.com"
|
||||
|
||||
#: patterns/text-faq.php
|
||||
msgid "Frequently Asked Questions"
|
||||
msgstr "Foire aux questions"
|
||||
|
||||
#: patterns/text-faq.php
|
||||
msgid "How do I install the theme?"
|
||||
msgstr "Comment installer le thème ?"
|
||||
|
||||
#: patterns/text-faq.php
|
||||
msgid "Download the ZIP file from the releases page, then upload it via WordPress Admin > Appearance > Themes > Add New > Upload Theme."
|
||||
msgstr "Téléchargez le fichier ZIP depuis la page des versions, puis importez-le via Administration WordPress > Apparence > Thèmes > Ajouter > Téléverser un thème."
|
||||
|
||||
#: patterns/text-faq.php
|
||||
msgid "Does it work with the Site Editor?"
|
||||
msgstr "Fonctionne-t-il avec l'éditeur de site ?"
|
||||
|
||||
#: patterns/text-faq.php
|
||||
msgid "Yes, this is a Full Site Editing block theme. You can customize templates, headers, footers, and all block patterns using the WordPress Site Editor."
|
||||
msgstr "Oui, c'est un thème bloc d'édition complète du site. Vous pouvez personnaliser les modèles, en-têtes, pieds de page et tous les modèles de blocs avec l'éditeur de site WordPress."
|
||||
|
||||
#: patterns/text-faq.php
|
||||
msgid "Can I use my own fonts?"
|
||||
msgstr "Puis-je utiliser mes propres polices ?"
|
||||
|
||||
#: patterns/text-faq.php
|
||||
msgid "The theme comes with Inter, Lora, and system font stacks. You can add custom fonts through the Site Editor or by modifying theme.json."
|
||||
msgstr "Le thème est livré avec Inter, Lora et des polices système. Vous pouvez ajouter des polices personnalisées via l'éditeur de site ou en modifiant theme.json."
|
||||
|
||||
#: patterns/text-faq.php
|
||||
msgid "Is dark mode supported?"
|
||||
msgstr "Le mode sombre est-il pris en charge ?"
|
||||
|
||||
#: patterns/text-faq.php
|
||||
msgid "Yes, the theme includes a dark mode toggle that uses Bootstrap 5.3 built-in dark mode. It respects system preferences and remembers your choice."
|
||||
msgstr "Oui, le thème inclut un bouton de mode sombre qui utilise le mode sombre intégré de Bootstrap 5.3. Il respecte les préférences système et mémorise votre choix."
|
||||
|
||||
#: patterns/text-about.php
|
||||
msgid "About us"
|
||||
msgstr "À propos de nous"
|
||||
|
||||
#: patterns/text-about.php
|
||||
msgid "We are passionate about creating tools that empower people to build beautiful websites. Our theme combines the reliability of Bootstrap with the flexibility of WordPress."
|
||||
msgstr "Nous sommes passionnés par la création d'outils qui permettent aux gens de construire de beaux sites web. Notre thème combine la fiabilité de Bootstrap avec la flexibilité de WordPress."
|
||||
|
||||
#: patterns/text-about.php
|
||||
msgid "With years of experience in web development and design, we understand what it takes to create a theme that is both powerful and easy to use."
|
||||
msgstr "Avec des années d'expérience en développement web et en design, nous comprenons ce qu'il faut pour créer un thème à la fois puissant et facile à utiliser."
|
||||
|
||||
#: patterns/text-about.php
|
||||
#: patterns/page-about.php
|
||||
msgid "About us image"
|
||||
msgstr "Image à propos de nous"
|
||||
|
||||
#: patterns/hidden-sidebar.php
|
||||
msgid "Recent Posts"
|
||||
msgstr "Articles récents"
|
||||
|
||||
#: patterns/hidden-sidebar.php
|
||||
msgid "Tags"
|
||||
msgstr "Étiquettes"
|
||||
|
||||
#: patterns/dark-mode-toggle.php
|
||||
msgid "Switch to dark mode"
|
||||
msgstr "Passer en mode sombre"
|
||||
|
||||
#: patterns/dark-mode-toggle.php
|
||||
msgid "Switch to light mode"
|
||||
msgstr "Passer en mode clair"
|
||||
|
||||
#: functions.php
|
||||
msgid "Primary Navigation"
|
||||
msgstr "Navigation principale"
|
||||
|
||||
#: functions.php
|
||||
msgid "Footer Navigation"
|
||||
msgstr "Navigation du pied de page"
|
||||
|
||||
#: functions.php
|
||||
msgid "Pages"
|
||||
msgstr "Pages"
|
||||
|
||||
#: functions.php
|
||||
msgid "A collection of full page layouts."
|
||||
msgstr "Une collection de mises en page pleine page."
|
||||
|
||||
#: functions.php
|
||||
msgid "Hero Sections"
|
||||
msgstr "Sections héros"
|
||||
|
||||
#: functions.php
|
||||
msgid "Large hero and banner sections."
|
||||
msgstr "Grandes sections héros et bannières."
|
||||
|
||||
#: functions.php
|
||||
msgid "Call to Action"
|
||||
msgstr "Appel à l'action"
|
||||
|
||||
#: functions.php
|
||||
msgid "Call to action sections."
|
||||
msgstr "Sections d'appel à l'action."
|
||||
|
||||
#: functions.php
|
||||
msgid "Feature and service showcase sections."
|
||||
msgstr "Sections de présentation des fonctionnalités et services."
|
||||
|
||||
#: functions.php
|
||||
msgid "Testimonials"
|
||||
msgstr "Témoignages"
|
||||
|
||||
#: functions.php
|
||||
msgid "Testimonial and review sections."
|
||||
msgstr "Sections de témoignages et d'avis."
|
||||
|
||||
#: functions.php
|
||||
msgid "Pricing table sections."
|
||||
msgstr "Sections de tableaux de tarifs."
|
||||
|
||||
#: functions.php
|
||||
msgid "Contact"
|
||||
msgstr "Contact"
|
||||
|
||||
#: functions.php
|
||||
msgid "Contact information sections."
|
||||
msgstr "Sections d'informations de contact."
|
||||
|
||||
#: functions.php
|
||||
msgid "Text & Content"
|
||||
msgstr "Texte et contenu"
|
||||
|
||||
#: functions.php
|
||||
msgid "Text-focused content sections."
|
||||
msgstr "Sections de contenu axées sur le texte."
|
||||
|
||||
#: functions.php
|
||||
msgid "Checkmark"
|
||||
msgstr "Coche"
|
||||
|
||||
#: functions.php
|
||||
msgid "Unstyled"
|
||||
msgstr "Sans style"
|
||||
|
||||
#: functions.php
|
||||
msgid "Card"
|
||||
msgstr "Carte"
|
||||
|
||||
#: functions.php
|
||||
msgid "Card with Shadow"
|
||||
msgstr "Carte avec ombre"
|
||||
|
||||
#: functions.php
|
||||
msgid "Alert - Info"
|
||||
msgstr "Alerte - Info"
|
||||
|
||||
#: functions.php
|
||||
msgid "Alert - Success"
|
||||
msgstr "Alerte - Succès"
|
||||
|
||||
#: functions.php
|
||||
msgid "Alert - Warning"
|
||||
msgstr "Alerte - Avertissement"
|
||||
|
||||
#: functions.php
|
||||
msgid "Alert - Danger"
|
||||
msgstr "Alerte - Danger"
|
||||
|
||||
#: functions.php
|
||||
msgid "Striped Rows"
|
||||
msgstr "Lignes rayées"
|
||||
|
||||
#: functions.php
|
||||
msgid "Hover Rows"
|
||||
msgstr "Lignes survolées"
|
||||
|
||||
#: functions.php
|
||||
msgid "Bordered"
|
||||
msgstr "Avec bordure"
|
||||
|
||||
#: functions.php
|
||||
msgid "Accent Border"
|
||||
msgstr "Bordure d'accent"
|
||||
|
||||
#: functions.php
|
||||
msgid "Shadow"
|
||||
msgstr "Ombre"
|
||||
|
||||
#: functions.php
|
||||
msgid "Large Rounded"
|
||||
msgstr "Grand arrondi"
|
||||
|
||||
#: functions.php
|
||||
msgid "Large"
|
||||
msgstr "Grand"
|
||||
|
||||
#: functions.php
|
||||
msgid "Small"
|
||||
msgstr "Petit"
|
||||
|
||||
#: functions.php
|
||||
msgid "Wide"
|
||||
msgstr "Large"
|
||||
|
||||
#: functions.php
|
||||
msgid "Name"
|
||||
msgstr "Nom"
|
||||
|
||||
#: functions.php
|
||||
msgid "Website"
|
||||
msgstr "Site web"
|
||||
|
||||
#: functions.php
|
||||
msgid "Save my name, email, and website in this browser for the next time I comment."
|
||||
msgstr "Enregistrer mon nom, mon courriel et mon site web dans ce navigateur pour la prochaine fois que je commenterai."
|
||||
|
||||
#: functions.php
|
||||
msgid "Bootstrap Layout"
|
||||
msgstr "Mise en page Bootstrap"
|
||||
|
||||
#: functions.php
|
||||
msgid "Bootstrap Components"
|
||||
msgstr "Composants Bootstrap"
|
||||
|
||||
#: functions.php
|
||||
msgid "Bootstrap Navigation"
|
||||
msgstr "Navigation Bootstrap"
|
||||
|
||||
#: functions.php
|
||||
msgid "Layout"
|
||||
msgstr "Mise en page"
|
||||
|
||||
#: functions.php
|
||||
msgid "Layout building blocks for page structure."
|
||||
msgstr "Blocs de construction de mise en page pour la structure des pages."
|
||||
|
||||
#: functions.php
|
||||
msgid "Components"
|
||||
msgstr "Composants"
|
||||
|
||||
#: functions.php
|
||||
msgid "Reusable Bootstrap component patterns."
|
||||
msgstr "Modèles de composants Bootstrap réutilisables."
|
||||
|
||||
#: functions.php
|
||||
#: patterns/footer-columns.php
|
||||
msgid "Navigation"
|
||||
msgstr "Navigation"
|
||||
|
||||
#: functions.php
|
||||
msgid "Navigation and header patterns."
|
||||
msgstr "Modèles de navigation et d'en-tête."
|
||||
|
||||
#: patterns/layout-container.php
|
||||
msgid "Heading goes here"
|
||||
msgstr "Le titre va ici"
|
||||
|
||||
#: patterns/layout-container.php
|
||||
msgid "This is a content container with constrained width and comfortable padding. Replace this text with your own content."
|
||||
msgstr "Ceci est un conteneur de contenu avec une largeur limitée et un espacement confortable. Remplacez ce texte par votre propre contenu."
|
||||
|
||||
#: patterns/layout-2-col.php
|
||||
#: patterns/layout-3-col.php
|
||||
msgid "Column One"
|
||||
msgstr "Colonne un"
|
||||
|
||||
#: patterns/layout-2-col.php
|
||||
msgid "Add your content here. This column takes up half the available width on larger screens and stacks on mobile devices."
|
||||
msgstr "Ajoutez votre contenu ici. Cette colonne occupe la moitié de la largeur disponible sur les grands écrans et s'empile sur les appareils mobiles."
|
||||
|
||||
#: patterns/layout-2-col.php
|
||||
#: patterns/layout-3-col.php
|
||||
msgid "Column Two"
|
||||
msgstr "Colonne deux"
|
||||
|
||||
#: patterns/layout-3-col.php
|
||||
msgid "Column Three"
|
||||
msgstr "Colonne trois"
|
||||
|
||||
#: patterns/layout-3-col.php
|
||||
msgid "Add your content here. This column takes up one third of the available width on larger screens."
|
||||
msgstr "Ajoutez votre contenu ici. Cette colonne occupe un tiers de la largeur disponible sur les grands écrans."
|
||||
|
||||
#: patterns/layout-full-width-section.php
|
||||
msgid "Full Width Section Heading"
|
||||
msgstr "Titre de la section pleine largeur"
|
||||
|
||||
#: patterns/layout-full-width-section.php
|
||||
msgid "This full-width section stands out with a colored background. Use it to highlight important content, announcements, or calls to action."
|
||||
msgstr "Cette section pleine largeur se distingue par un arrière-plan coloré. Utilisez-la pour mettre en valeur du contenu important, des annonces ou des appels à l'action."
|
||||
|
||||
#: patterns/component-card-group.php
|
||||
msgid "Card One"
|
||||
msgstr "Carte un"
|
||||
|
||||
#: patterns/component-card-group.php
|
||||
msgid "Card Two"
|
||||
msgstr "Carte deux"
|
||||
|
||||
#: patterns/component-card-group.php
|
||||
msgid "Card Three"
|
||||
msgstr "Carte trois"
|
||||
|
||||
#: patterns/component-card-group.php
|
||||
msgid "Add a short description for this card. Cards are a great way to organize and present related content."
|
||||
msgstr "Ajoutez une courte description pour cette carte. Les cartes sont un excellent moyen d'organiser et de présenter du contenu connexe."
|
||||
|
||||
#: patterns/component-accordion.php
|
||||
msgid "Accordion"
|
||||
msgstr "Accordéon"
|
||||
|
||||
#: patterns/component-accordion.php
|
||||
msgid "Click on each item to expand and reveal its content."
|
||||
msgstr "Cliquez sur chaque élément pour le développer et révéler son contenu."
|
||||
|
||||
#: patterns/component-accordion.php
|
||||
msgid "Accordion Item One"
|
||||
msgstr "Élément d'accordéon un"
|
||||
|
||||
#: patterns/component-accordion.php
|
||||
msgid "This is the content for the first accordion item. You can add any blocks inside this details element to create rich, expandable content sections."
|
||||
msgstr "Ceci est le contenu du premier élément d'accordéon. Vous pouvez ajouter n'importe quels blocs à l'intérieur de cet élément details pour créer des sections de contenu riches et dépliables."
|
||||
|
||||
#: patterns/component-accordion.php
|
||||
msgid "Accordion Item Two"
|
||||
msgstr "Élément d'accordéon deux"
|
||||
|
||||
#: patterns/component-accordion.php
|
||||
msgid "This is the content for the second accordion item. Details blocks are a native HTML element that provide toggle functionality without JavaScript."
|
||||
msgstr "Ceci est le contenu du deuxième élément d'accordéon. Les blocs details sont un élément HTML natif qui offre une fonctionnalité de basculement sans JavaScript."
|
||||
|
||||
#: patterns/component-accordion.php
|
||||
msgid "Accordion Item Three"
|
||||
msgstr "Élément d'accordéon trois"
|
||||
|
||||
#: patterns/component-accordion.php
|
||||
msgid "This is the content for the third accordion item. Use accordions to organize frequently asked questions, feature lists, or any content that benefits from progressive disclosure."
|
||||
msgstr "Ceci est le contenu du troisième élément d'accordéon. Utilisez les accordéons pour organiser les questions fréquentes, les listes de fonctionnalités ou tout contenu qui bénéficie d'une divulgation progressive."
|
||||
|
||||
#: patterns/page-about.php
|
||||
msgid "About Us"
|
||||
msgstr "À propos"
|
||||
|
||||
#: patterns/page-about.php
|
||||
msgid "Learn more about who we are, what we do, and the people behind our mission."
|
||||
msgstr "Apprenez-en plus sur qui nous sommes, ce que nous faisons et les personnes derrière notre mission."
|
||||
|
||||
#: patterns/page-about.php
|
||||
msgid "Our Story"
|
||||
msgstr "Notre histoire"
|
||||
|
||||
#: patterns/page-about.php
|
||||
msgid "Founded with a passion for innovation and excellence, our journey began with a simple idea: to create meaningful solutions that make a real difference. Over the years, we have grown from a small team into a dedicated group of professionals committed to delivering outstanding results."
|
||||
msgstr "Fondée avec une passion pour l'innovation et l'excellence, notre aventure a commencé avec une idée simple : créer des solutions significatives qui font une vraie différence. Au fil des années, nous sommes passés d'une petite équipe à un groupe dédié de professionnels engagés à fournir des résultats exceptionnels."
|
||||
|
||||
#: patterns/page-about.php
|
||||
msgid "Today, we continue to push boundaries and challenge conventions. Our approach combines creative thinking with proven methodologies, ensuring that every project we undertake meets the highest standards of quality and craftsmanship."
|
||||
msgstr "Aujourd'hui, nous continuons à repousser les limites et à remettre en question les conventions. Notre approche combine la pensée créative avec des méthodologies éprouvées, garantissant que chaque projet que nous entreprenons répond aux plus hauts standards de qualité et de savoir-faire."
|
||||
|
||||
#: patterns/page-about.php
|
||||
msgid "Our Team"
|
||||
msgstr "Notre équipe"
|
||||
|
||||
#: patterns/page-about.php
|
||||
msgid "Meet the people who make it all happen."
|
||||
msgstr "Rencontrez les personnes qui rendent tout cela possible."
|
||||
|
||||
#: patterns/page-about.php
|
||||
msgid "Jane Doe"
|
||||
msgstr "Jane Doe"
|
||||
|
||||
#: patterns/page-about.php
|
||||
msgid "Founder & CEO"
|
||||
msgstr "Fondatrice et PDG"
|
||||
|
||||
#: patterns/page-about.php
|
||||
msgid "John Smith"
|
||||
msgstr "John Smith"
|
||||
|
||||
#: patterns/page-about.php
|
||||
msgid "Lead Developer"
|
||||
msgstr "Développeur principal"
|
||||
|
||||
#: patterns/page-about.php
|
||||
msgid "Emily Johnson"
|
||||
msgstr "Emily Johnson"
|
||||
|
||||
#: patterns/page-about.php
|
||||
msgid "Creative Director"
|
||||
msgstr "Directrice créative"
|
||||
|
||||
#: patterns/page-services.php
|
||||
msgid "Our Services"
|
||||
msgstr "Nos services"
|
||||
|
||||
#: patterns/page-services.php
|
||||
msgid "Professional solutions tailored to your needs."
|
||||
msgstr "Des solutions professionnelles adaptées à vos besoins."
|
||||
|
||||
#: patterns/page-services.php
|
||||
msgid "What We Offer"
|
||||
msgstr "Ce que nous offrons"
|
||||
|
||||
#: patterns/page-services.php
|
||||
msgid "We provide a wide range of services to help your business grow and succeed."
|
||||
msgstr "Nous fournissons une large gamme de services pour aider votre entreprise à croître et réussir."
|
||||
|
||||
#: patterns/page-services.php
|
||||
msgid "Design"
|
||||
msgstr "Design"
|
||||
|
||||
#: patterns/page-services.php
|
||||
msgid "Beautiful, user-centered designs that capture your brand identity and engage your audience across all platforms and devices."
|
||||
msgstr "De beaux designs centrés sur l'utilisateur qui capturent l'identité de votre marque et engagent votre public sur toutes les plateformes et appareils."
|
||||
|
||||
#: patterns/page-services.php
|
||||
msgid "Development"
|
||||
msgstr "Développement"
|
||||
|
||||
#: patterns/page-services.php
|
||||
msgid "Robust, scalable web applications built with modern technologies and best practices to ensure performance and reliability."
|
||||
msgstr "Des applications web robustes et évolutives construites avec des technologies modernes et les meilleures pratiques pour garantir performance et fiabilité."
|
||||
|
||||
#: patterns/page-services.php
|
||||
msgid "Strategy"
|
||||
msgstr "Stratégie"
|
||||
|
||||
#: patterns/page-services.php
|
||||
msgid "Data-driven strategies and consulting to help you achieve your business goals and stay ahead of the competition."
|
||||
msgstr "Des stratégies basées sur les données et du conseil pour vous aider à atteindre vos objectifs commerciaux et garder une longueur d'avance sur la concurrence."
|
||||
|
||||
#: patterns/page-services.php
|
||||
msgid "Ready to take your project to the next level? Let us help you build something great."
|
||||
msgstr "Prêt à faire passer votre projet au niveau supérieur ? Laissez-nous vous aider à construire quelque chose de formidable."
|
||||
|
||||
#: patterns/page-services.php
|
||||
msgid "View Portfolio"
|
||||
msgstr "Voir le portfolio"
|
||||
|
||||
#: patterns/page-contact.php
|
||||
msgid "We would love to hear from you. Reach out to us anytime."
|
||||
msgstr "Nous serions ravis d'avoir de vos nouvelles. Contactez-nous à tout moment."
|
||||
|
||||
#: patterns/page-contact.php
|
||||
msgid "Get in Touch"
|
||||
msgstr "Prenez contact"
|
||||
|
||||
#: patterns/page-contact.php
|
||||
msgid "123 Main Street, Suite 100, Anytown, ST 12345"
|
||||
msgstr "123, rue Principale, Bureau 100, 75001 Paris"
|
||||
|
||||
#: patterns/page-contact.php
|
||||
msgid "+1 (555) 123-4567"
|
||||
msgstr "+33 1 23 45 67 89"
|
||||
|
||||
#: patterns/page-contact.php
|
||||
msgid "Business Hours"
|
||||
msgstr "Heures d'ouverture"
|
||||
|
||||
#: patterns/page-contact.php
|
||||
msgid "Monday - Friday:"
|
||||
msgstr "Lundi - Vendredi :"
|
||||
|
||||
#: patterns/page-contact.php
|
||||
msgid "9:00 AM - 6:00 PM"
|
||||
msgstr "9h00 - 18h00"
|
||||
|
||||
#: patterns/page-contact.php
|
||||
msgid "Saturday:"
|
||||
msgstr "Samedi :"
|
||||
|
||||
#: patterns/page-contact.php
|
||||
msgid "10:00 AM - 4:00 PM"
|
||||
msgstr "10h00 - 16h00"
|
||||
|
||||
#: patterns/page-contact.php
|
||||
msgid "Sunday:"
|
||||
msgstr "Dimanche :"
|
||||
|
||||
#: patterns/page-contact.php
|
||||
msgid "Closed"
|
||||
msgstr "Fermé"
|
||||
|
||||
#. translators: Copyright notice. %1$s: Year, %2$s: Site title.
|
||||
#: patterns/footer-minimal.php
|
||||
msgid "© %1$s %2$s. All rights reserved."
|
||||
msgstr "© %1$s %2$s. Tous droits réservés."
|
||||
|
||||
#: patterns/footer-columns.php
|
||||
msgid "A modern WordPress theme built with Bootstrap 5."
|
||||
msgstr "Un thème WordPress moderne construit avec Bootstrap 5."
|
||||
|
||||
#: patterns/footer-columns.php
|
||||
msgid "About"
|
||||
msgstr "À propos"
|
||||
|
||||
#: patterns/footer-columns.php
|
||||
msgid "This theme is proudly built with Bootstrap 5 and WordPress Full Site Editing."
|
||||
msgstr "Ce thème est fièrement construit avec Bootstrap 5 et l'éditeur de site complet WordPress."
|
||||
|
||||
#. translators: Copyright notice. %1$s: Year, %2$s: Site title.
|
||||
#: patterns/footer-columns.php
|
||||
msgid "© %1$s %2$s"
|
||||
msgstr "© %1$s %2$s"
|
||||
|
||||
#: views/base.html.twig
|
||||
msgid "Skip to main content"
|
||||
msgstr "Aller au contenu principal"
|
||||
|
||||
#: views/partials/header.html.twig
|
||||
#: views/partials/header-centered.html.twig
|
||||
#: views/partials/header-transparent.html.twig
|
||||
#: views/partials/header-offcanvas.html.twig
|
||||
msgid "Primary navigation"
|
||||
msgstr "Navigation principale"
|
||||
|
||||
#: views/partials/footer.html.twig
|
||||
#: views/partials/footer-columns.html.twig
|
||||
msgid "Footer navigation"
|
||||
msgstr "Navigation du pied de page"
|
||||
|
||||
#: views/partials/sidebar.html.twig
|
||||
msgid "Blog sidebar"
|
||||
msgstr "Barre latérale du blog"
|
||||
@@ -2,7 +2,7 @@
|
||||
# This file is distributed under the same license as the WP Bootstrap theme.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: WP Bootstrap 0.1.0\n"
|
||||
"Project-Id-Version: WP Bootstrap 0.3.0\n"
|
||||
"Report-Msgid-Bugs-To: https://src.bundespruefstelle.ch/magdev/wp-bootstrap/issues\n"
|
||||
"POT-Creation-Date: 2026-02-08 00:00+0000\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@@ -24,10 +24,12 @@ msgid "A modern WordPress Block Theme built from scratch with Bootstrap 5. Featu
|
||||
msgstr ""
|
||||
|
||||
#: patterns/footer.php
|
||||
#: patterns/footer-columns.php
|
||||
msgid "Powered by %s"
|
||||
msgstr ""
|
||||
|
||||
#: patterns/footer.php
|
||||
#: patterns/footer-columns.php
|
||||
msgid "https://wordpress.org"
|
||||
msgstr ""
|
||||
|
||||
@@ -88,6 +90,7 @@ msgstr ""
|
||||
#: patterns/hero-cover.php
|
||||
#: patterns/hero-centered.php
|
||||
#: patterns/pricing-3-col.php
|
||||
#: patterns/page-services.php
|
||||
msgid "Get Started"
|
||||
msgstr ""
|
||||
|
||||
@@ -336,6 +339,8 @@ msgid "Custom Development"
|
||||
msgstr ""
|
||||
|
||||
#: patterns/pricing-3-col.php
|
||||
#: patterns/page-services.php
|
||||
#: patterns/page-contact.php
|
||||
msgid "Contact Us"
|
||||
msgstr ""
|
||||
|
||||
@@ -348,6 +353,7 @@ msgid "We would love to hear from you. Reach out through any of the channels bel
|
||||
msgstr ""
|
||||
|
||||
#: patterns/contact-info.php
|
||||
#: patterns/page-contact.php
|
||||
msgid "Address"
|
||||
msgstr ""
|
||||
|
||||
@@ -360,6 +366,7 @@ msgid "8000 Zurich, Switzerland"
|
||||
msgstr ""
|
||||
|
||||
#: patterns/contact-info.php
|
||||
#: patterns/page-contact.php
|
||||
msgid "Phone"
|
||||
msgstr ""
|
||||
|
||||
@@ -369,10 +376,12 @@ msgstr ""
|
||||
|
||||
#: patterns/contact-info.php
|
||||
#: patterns/cta-newsletter.php
|
||||
#: patterns/page-contact.php
|
||||
msgid "Email"
|
||||
msgstr ""
|
||||
|
||||
#: patterns/contact-info.php
|
||||
#: patterns/page-contact.php
|
||||
msgid "info@example.com"
|
||||
msgstr ""
|
||||
|
||||
@@ -425,6 +434,7 @@ msgid "With years of experience in web development and design, we understand wha
|
||||
msgstr ""
|
||||
|
||||
#: patterns/text-about.php
|
||||
#: patterns/page-about.php
|
||||
msgid "About us image"
|
||||
msgstr ""
|
||||
|
||||
@@ -444,6 +454,14 @@ msgstr ""
|
||||
msgid "Switch to light mode"
|
||||
msgstr ""
|
||||
|
||||
#: functions.php
|
||||
msgid "Primary Navigation"
|
||||
msgstr ""
|
||||
|
||||
#: functions.php
|
||||
msgid "Footer Navigation"
|
||||
msgstr ""
|
||||
|
||||
#: functions.php
|
||||
msgid "Pages"
|
||||
msgstr ""
|
||||
@@ -567,3 +585,324 @@ msgstr ""
|
||||
#: functions.php
|
||||
msgid "Wide"
|
||||
msgstr ""
|
||||
|
||||
#: functions.php
|
||||
msgid "Name"
|
||||
msgstr ""
|
||||
|
||||
#: functions.php
|
||||
msgid "Website"
|
||||
msgstr ""
|
||||
|
||||
#: functions.php
|
||||
msgid "Save my name, email, and website in this browser for the next time I comment."
|
||||
msgstr ""
|
||||
|
||||
#: functions.php
|
||||
msgid "Bootstrap Layout"
|
||||
msgstr ""
|
||||
|
||||
#: functions.php
|
||||
msgid "Bootstrap Components"
|
||||
msgstr ""
|
||||
|
||||
#: functions.php
|
||||
msgid "Bootstrap Navigation"
|
||||
msgstr ""
|
||||
|
||||
#: functions.php
|
||||
msgid "Layout"
|
||||
msgstr ""
|
||||
|
||||
#: functions.php
|
||||
msgid "Layout building blocks for page structure."
|
||||
msgstr ""
|
||||
|
||||
#: functions.php
|
||||
msgid "Components"
|
||||
msgstr ""
|
||||
|
||||
#: functions.php
|
||||
msgid "Reusable Bootstrap component patterns."
|
||||
msgstr ""
|
||||
|
||||
#: functions.php
|
||||
#: patterns/footer-columns.php
|
||||
msgid "Navigation"
|
||||
msgstr ""
|
||||
|
||||
#: functions.php
|
||||
msgid "Navigation and header patterns."
|
||||
msgstr ""
|
||||
|
||||
#: patterns/layout-container.php
|
||||
msgid "Heading goes here"
|
||||
msgstr ""
|
||||
|
||||
#: patterns/layout-container.php
|
||||
msgid "This is a content container with constrained width and comfortable padding. Replace this text with your own content."
|
||||
msgstr ""
|
||||
|
||||
#: patterns/layout-2-col.php
|
||||
#: patterns/layout-3-col.php
|
||||
msgid "Column One"
|
||||
msgstr ""
|
||||
|
||||
#: patterns/layout-2-col.php
|
||||
msgid "Add your content here. This column takes up half the available width on larger screens and stacks on mobile devices."
|
||||
msgstr ""
|
||||
|
||||
#: patterns/layout-2-col.php
|
||||
#: patterns/layout-3-col.php
|
||||
msgid "Column Two"
|
||||
msgstr ""
|
||||
|
||||
#: patterns/layout-3-col.php
|
||||
msgid "Column Three"
|
||||
msgstr ""
|
||||
|
||||
#: patterns/layout-3-col.php
|
||||
msgid "Add your content here. This column takes up one third of the available width on larger screens."
|
||||
msgstr ""
|
||||
|
||||
#: patterns/layout-full-width-section.php
|
||||
msgid "Full Width Section Heading"
|
||||
msgstr ""
|
||||
|
||||
#: patterns/layout-full-width-section.php
|
||||
msgid "This full-width section stands out with a colored background. Use it to highlight important content, announcements, or calls to action."
|
||||
msgstr ""
|
||||
|
||||
#: patterns/component-card-group.php
|
||||
msgid "Card One"
|
||||
msgstr ""
|
||||
|
||||
#: patterns/component-card-group.php
|
||||
msgid "Card Two"
|
||||
msgstr ""
|
||||
|
||||
#: patterns/component-card-group.php
|
||||
msgid "Card Three"
|
||||
msgstr ""
|
||||
|
||||
#: patterns/component-card-group.php
|
||||
msgid "Add a short description for this card. Cards are a great way to organize and present related content."
|
||||
msgstr ""
|
||||
|
||||
#: patterns/component-accordion.php
|
||||
msgid "Accordion"
|
||||
msgstr ""
|
||||
|
||||
#: patterns/component-accordion.php
|
||||
msgid "Click on each item to expand and reveal its content."
|
||||
msgstr ""
|
||||
|
||||
#: patterns/component-accordion.php
|
||||
msgid "Accordion Item One"
|
||||
msgstr ""
|
||||
|
||||
#: patterns/component-accordion.php
|
||||
msgid "This is the content for the first accordion item. You can add any blocks inside this details element to create rich, expandable content sections."
|
||||
msgstr ""
|
||||
|
||||
#: patterns/component-accordion.php
|
||||
msgid "Accordion Item Two"
|
||||
msgstr ""
|
||||
|
||||
#: patterns/component-accordion.php
|
||||
msgid "This is the content for the second accordion item. Details blocks are a native HTML element that provide toggle functionality without JavaScript."
|
||||
msgstr ""
|
||||
|
||||
#: patterns/component-accordion.php
|
||||
msgid "Accordion Item Three"
|
||||
msgstr ""
|
||||
|
||||
#: patterns/component-accordion.php
|
||||
msgid "This is the content for the third accordion item. Use accordions to organize frequently asked questions, feature lists, or any content that benefits from progressive disclosure."
|
||||
msgstr ""
|
||||
|
||||
#: patterns/page-about.php
|
||||
msgid "About Us"
|
||||
msgstr ""
|
||||
|
||||
#: patterns/page-about.php
|
||||
msgid "Learn more about who we are, what we do, and the people behind our mission."
|
||||
msgstr ""
|
||||
|
||||
#: patterns/page-about.php
|
||||
msgid "Our Story"
|
||||
msgstr ""
|
||||
|
||||
#: patterns/page-about.php
|
||||
msgid "Founded with a passion for innovation and excellence, our journey began with a simple idea: to create meaningful solutions that make a real difference. Over the years, we have grown from a small team into a dedicated group of professionals committed to delivering outstanding results."
|
||||
msgstr ""
|
||||
|
||||
#: patterns/page-about.php
|
||||
msgid "Today, we continue to push boundaries and challenge conventions. Our approach combines creative thinking with proven methodologies, ensuring that every project we undertake meets the highest standards of quality and craftsmanship."
|
||||
msgstr ""
|
||||
|
||||
#: patterns/page-about.php
|
||||
msgid "Our Team"
|
||||
msgstr ""
|
||||
|
||||
#: patterns/page-about.php
|
||||
msgid "Meet the people who make it all happen."
|
||||
msgstr ""
|
||||
|
||||
#: patterns/page-about.php
|
||||
msgid "Jane Doe"
|
||||
msgstr ""
|
||||
|
||||
#: patterns/page-about.php
|
||||
msgid "Founder & CEO"
|
||||
msgstr ""
|
||||
|
||||
#: patterns/page-about.php
|
||||
msgid "John Smith"
|
||||
msgstr ""
|
||||
|
||||
#: patterns/page-about.php
|
||||
msgid "Lead Developer"
|
||||
msgstr ""
|
||||
|
||||
#: patterns/page-about.php
|
||||
msgid "Emily Johnson"
|
||||
msgstr ""
|
||||
|
||||
#: patterns/page-about.php
|
||||
msgid "Creative Director"
|
||||
msgstr ""
|
||||
|
||||
#: patterns/page-services.php
|
||||
msgid "Our Services"
|
||||
msgstr ""
|
||||
|
||||
#: patterns/page-services.php
|
||||
msgid "Professional solutions tailored to your needs."
|
||||
msgstr ""
|
||||
|
||||
#: patterns/page-services.php
|
||||
msgid "What We Offer"
|
||||
msgstr ""
|
||||
|
||||
#: patterns/page-services.php
|
||||
msgid "We provide a wide range of services to help your business grow and succeed."
|
||||
msgstr ""
|
||||
|
||||
#: patterns/page-services.php
|
||||
msgid "Design"
|
||||
msgstr ""
|
||||
|
||||
#: patterns/page-services.php
|
||||
msgid "Beautiful, user-centered designs that capture your brand identity and engage your audience across all platforms and devices."
|
||||
msgstr ""
|
||||
|
||||
#: patterns/page-services.php
|
||||
msgid "Development"
|
||||
msgstr ""
|
||||
|
||||
#: patterns/page-services.php
|
||||
msgid "Robust, scalable web applications built with modern technologies and best practices to ensure performance and reliability."
|
||||
msgstr ""
|
||||
|
||||
#: patterns/page-services.php
|
||||
msgid "Strategy"
|
||||
msgstr ""
|
||||
|
||||
#: patterns/page-services.php
|
||||
msgid "Data-driven strategies and consulting to help you achieve your business goals and stay ahead of the competition."
|
||||
msgstr ""
|
||||
|
||||
#: patterns/page-services.php
|
||||
msgid "Ready to take your project to the next level? Let us help you build something great."
|
||||
msgstr ""
|
||||
|
||||
#: patterns/page-services.php
|
||||
msgid "View Portfolio"
|
||||
msgstr ""
|
||||
|
||||
#: patterns/page-contact.php
|
||||
msgid "We would love to hear from you. Reach out to us anytime."
|
||||
msgstr ""
|
||||
|
||||
#: patterns/page-contact.php
|
||||
msgid "Get in Touch"
|
||||
msgstr ""
|
||||
|
||||
#: patterns/page-contact.php
|
||||
msgid "123 Main Street, Suite 100, Anytown, ST 12345"
|
||||
msgstr ""
|
||||
|
||||
#: patterns/page-contact.php
|
||||
msgid "+1 (555) 123-4567"
|
||||
msgstr ""
|
||||
|
||||
#: patterns/page-contact.php
|
||||
msgid "Business Hours"
|
||||
msgstr ""
|
||||
|
||||
#: patterns/page-contact.php
|
||||
msgid "Monday - Friday:"
|
||||
msgstr ""
|
||||
|
||||
#: patterns/page-contact.php
|
||||
msgid "9:00 AM - 6:00 PM"
|
||||
msgstr ""
|
||||
|
||||
#: patterns/page-contact.php
|
||||
msgid "Saturday:"
|
||||
msgstr ""
|
||||
|
||||
#: patterns/page-contact.php
|
||||
msgid "10:00 AM - 4:00 PM"
|
||||
msgstr ""
|
||||
|
||||
#: patterns/page-contact.php
|
||||
msgid "Sunday:"
|
||||
msgstr ""
|
||||
|
||||
#: patterns/page-contact.php
|
||||
msgid "Closed"
|
||||
msgstr ""
|
||||
|
||||
#. translators: Copyright notice. %1$s: Year, %2$s: Site title.
|
||||
#: patterns/footer-minimal.php
|
||||
msgid "© %1$s %2$s. All rights reserved."
|
||||
msgstr ""
|
||||
|
||||
#: patterns/footer-columns.php
|
||||
msgid "A modern WordPress theme built with Bootstrap 5."
|
||||
msgstr ""
|
||||
|
||||
#: patterns/footer-columns.php
|
||||
msgid "About"
|
||||
msgstr ""
|
||||
|
||||
#: patterns/footer-columns.php
|
||||
msgid "This theme is proudly built with Bootstrap 5 and WordPress Full Site Editing."
|
||||
msgstr ""
|
||||
|
||||
#. translators: Copyright notice. %1$s: Year, %2$s: Site title.
|
||||
#: patterns/footer-columns.php
|
||||
msgid "© %1$s %2$s"
|
||||
msgstr ""
|
||||
|
||||
#: views/base.html.twig
|
||||
msgid "Skip to main content"
|
||||
msgstr ""
|
||||
|
||||
#: views/partials/header.html.twig
|
||||
#: views/partials/header-centered.html.twig
|
||||
#: views/partials/header-transparent.html.twig
|
||||
#: views/partials/header-offcanvas.html.twig
|
||||
msgid "Primary navigation"
|
||||
msgstr ""
|
||||
|
||||
#: views/partials/footer.html.twig
|
||||
#: views/partials/footer-columns.html.twig
|
||||
msgid "Footer navigation"
|
||||
msgstr ""
|
||||
|
||||
#: views/partials/sidebar.html.twig
|
||||
msgid "Blog sidebar"
|
||||
msgstr ""
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "wp-bootstrap",
|
||||
"version": "0.1.0",
|
||||
"version": "0.3.1",
|
||||
"description": "WordPress Theme built with Bootstrap 5",
|
||||
"author": "Marco Graetsch <magdev3.0@gmail.com>",
|
||||
"license": "GPL-2.0-or-later",
|
||||
@@ -26,11 +26,12 @@
|
||||
},
|
||||
"scripts": {
|
||||
"scss": "sass src/scss/style.scss:assets/css/style.css src/scss/editor-style.scss:assets/css/editor-style.css --load-path=node_modules",
|
||||
"scss:rtl": "sass src/scss/rtl.scss:assets/css/rtl.css --style=compressed --no-source-map",
|
||||
"scss:watch": "sass --watch src/scss/style.scss:assets/css/style.css src/scss/editor-style.scss:assets/css/editor-style.css --load-path=node_modules",
|
||||
"postcss": "postcss assets/css/style.css --use autoprefixer cssnano -o assets/css/style.min.css --no-map",
|
||||
"copy:js": "copyfiles -f node_modules/bootstrap/dist/js/bootstrap.bundle.min.js node_modules/bootstrap/dist/js/bootstrap.bundle.min.js.map assets/js/",
|
||||
"copy:theme-js": "copyfiles -f src/js/dark-mode.js assets/js/",
|
||||
"build": "npm run copy:js && npm run copy:theme-js && npm run scss && npm run postcss",
|
||||
"build": "npm run copy:js && npm run copy:theme-js && npm run scss && npm run scss:rtl && npm run postcss",
|
||||
"watch": "npm run copy:js && npm run scss:watch",
|
||||
"dev": "npm run watch"
|
||||
}
|
||||
|
||||
1
parts/footer-columns.html
Normal file
1
parts/footer-columns.html
Normal file
@@ -0,0 +1 @@
|
||||
<!-- wp:pattern {"slug":"wp-bootstrap/footer-columns"} /-->
|
||||
1
parts/footer-minimal.html
Normal file
1
parts/footer-minimal.html
Normal file
@@ -0,0 +1 @@
|
||||
<!-- wp:pattern {"slug":"wp-bootstrap/footer-minimal"} /-->
|
||||
1
parts/header-centered.html
Normal file
1
parts/header-centered.html
Normal file
@@ -0,0 +1 @@
|
||||
<!-- wp:pattern {"slug":"wp-bootstrap/header-centered"} /-->
|
||||
1
parts/header-transparent.html
Normal file
1
parts/header-transparent.html
Normal file
@@ -0,0 +1 @@
|
||||
<!-- wp:pattern {"slug":"wp-bootstrap/header-transparent"} /-->
|
||||
38
patterns/component-accordion.php
Normal file
38
patterns/component-accordion.php
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
/**
|
||||
* Title: Accordion
|
||||
* Slug: wp-bootstrap/component-accordion
|
||||
* Categories: wp-bootstrap-components, text
|
||||
* Description: An accordion section using details blocks with summary and content paragraphs.
|
||||
*
|
||||
* @package WPBootstrap
|
||||
* @since 0.2.0
|
||||
*/
|
||||
?>
|
||||
<!-- wp:group {"align":"full","style":{"spacing":{"padding":{"top":"var:preset|spacing|70","bottom":"var:preset|spacing|70"}}},"layout":{"type":"constrained","contentSize":"720px"}} -->
|
||||
<div class="wp-block-group alignfull" style="padding-top:var(--wp--preset--spacing--70);padding-bottom:var(--wp--preset--spacing--70)"><!-- wp:heading {"textAlign":"center","fontSize":"xx-large"} -->
|
||||
<h2 class="wp-block-heading has-text-align-center has-xx-large-font-size"><?php esc_html_e( 'Accordion', 'wp-bootstrap' ); ?></h2>
|
||||
<!-- /wp:heading -->
|
||||
|
||||
<!-- wp:paragraph {"align":"center","textColor":"secondary"} -->
|
||||
<p class="has-text-align-center has-secondary-color has-text-color"><?php esc_html_e( 'Click on each item to expand and reveal its content.', 'wp-bootstrap' ); ?></p>
|
||||
<!-- /wp:paragraph -->
|
||||
|
||||
<!-- wp:details -->
|
||||
<details class="wp-block-details"><summary><?php esc_html_e( 'Accordion Item One', 'wp-bootstrap' ); ?></summary><!-- wp:paragraph {"textColor":"secondary"} -->
|
||||
<p class="has-secondary-color has-text-color"><?php esc_html_e( 'This is the content for the first accordion item. You can add any blocks inside this details element to create rich, expandable content sections.', 'wp-bootstrap' ); ?></p>
|
||||
<!-- /wp:paragraph --></details>
|
||||
<!-- /wp:details -->
|
||||
|
||||
<!-- wp:details -->
|
||||
<details class="wp-block-details"><summary><?php esc_html_e( 'Accordion Item Two', 'wp-bootstrap' ); ?></summary><!-- wp:paragraph {"textColor":"secondary"} -->
|
||||
<p class="has-secondary-color has-text-color"><?php esc_html_e( 'This is the content for the second accordion item. Details blocks are a native HTML element that provide toggle functionality without JavaScript.', 'wp-bootstrap' ); ?></p>
|
||||
<!-- /wp:paragraph --></details>
|
||||
<!-- /wp:details -->
|
||||
|
||||
<!-- wp:details -->
|
||||
<details class="wp-block-details"><summary><?php esc_html_e( 'Accordion Item Three', 'wp-bootstrap' ); ?></summary><!-- wp:paragraph {"textColor":"secondary"} -->
|
||||
<p class="has-secondary-color has-text-color"><?php esc_html_e( 'This is the content for the third accordion item. Use accordions to organize frequently asked questions, feature lists, or any content that benefits from progressive disclosure.', 'wp-bootstrap' ); ?></p>
|
||||
<!-- /wp:paragraph --></details>
|
||||
<!-- /wp:details --></div>
|
||||
<!-- /wp:group -->
|
||||
50
patterns/component-card-group.php
Normal file
50
patterns/component-card-group.php
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
/**
|
||||
* Title: Card Group
|
||||
* Slug: wp-bootstrap/component-card-group
|
||||
* Categories: wp-bootstrap-components
|
||||
* Description: A three-column card group with shadow-styled cards, each containing a heading and paragraph.
|
||||
*
|
||||
* @package WPBootstrap
|
||||
* @since 0.2.0
|
||||
*/
|
||||
?>
|
||||
<!-- wp:group {"align":"full","style":{"spacing":{"padding":{"top":"var:preset|spacing|70","bottom":"var:preset|spacing|70"}}},"layout":{"type":"constrained"}} -->
|
||||
<div class="wp-block-group alignfull" style="padding-top:var(--wp--preset--spacing--70);padding-bottom:var(--wp--preset--spacing--70)"><!-- wp:columns {"align":"wide","style":{"spacing":{"blockGap":{"left":"var:preset|spacing|40"}}}} -->
|
||||
<div class="wp-block-columns alignwide"><!-- wp:column -->
|
||||
<div class="wp-block-column"><!-- wp:group {"className":"is-style-card-shadow","style":{"spacing":{"padding":{"top":"var:preset|spacing|50","bottom":"var:preset|spacing|50","left":"var:preset|spacing|40","right":"var:preset|spacing|40"}}},"layout":{"type":"constrained"}} -->
|
||||
<div class="wp-block-group is-style-card-shadow" style="padding-top:var(--wp--preset--spacing--50);padding-right:var(--wp--preset--spacing--40);padding-bottom:var(--wp--preset--spacing--50);padding-left:var(--wp--preset--spacing--40)"><!-- wp:heading {"level":3} -->
|
||||
<h3 class="wp-block-heading"><?php esc_html_e( 'Card One', 'wp-bootstrap' ); ?></h3>
|
||||
<!-- /wp:heading -->
|
||||
|
||||
<!-- wp:paragraph {"textColor":"secondary"} -->
|
||||
<p class="has-secondary-color has-text-color"><?php esc_html_e( 'Add a short description for this card. Cards are a great way to organize and present related content.', 'wp-bootstrap' ); ?></p>
|
||||
<!-- /wp:paragraph --></div>
|
||||
<!-- /wp:group --></div>
|
||||
<!-- /wp:column -->
|
||||
|
||||
<!-- wp:column -->
|
||||
<div class="wp-block-column"><!-- wp:group {"className":"is-style-card-shadow","style":{"spacing":{"padding":{"top":"var:preset|spacing|50","bottom":"var:preset|spacing|50","left":"var:preset|spacing|40","right":"var:preset|spacing|40"}}},"layout":{"type":"constrained"}} -->
|
||||
<div class="wp-block-group is-style-card-shadow" style="padding-top:var(--wp--preset--spacing--50);padding-right:var(--wp--preset--spacing--40);padding-bottom:var(--wp--preset--spacing--50);padding-left:var(--wp--preset--spacing--40)"><!-- wp:heading {"level":3} -->
|
||||
<h3 class="wp-block-heading"><?php esc_html_e( 'Card Two', 'wp-bootstrap' ); ?></h3>
|
||||
<!-- /wp:heading -->
|
||||
|
||||
<!-- wp:paragraph {"textColor":"secondary"} -->
|
||||
<p class="has-secondary-color has-text-color"><?php esc_html_e( 'Add a short description for this card. Cards are a great way to organize and present related content.', 'wp-bootstrap' ); ?></p>
|
||||
<!-- /wp:paragraph --></div>
|
||||
<!-- /wp:group --></div>
|
||||
<!-- /wp:column -->
|
||||
|
||||
<!-- wp:column -->
|
||||
<div class="wp-block-column"><!-- wp:group {"className":"is-style-card-shadow","style":{"spacing":{"padding":{"top":"var:preset|spacing|50","bottom":"var:preset|spacing|50","left":"var:preset|spacing|40","right":"var:preset|spacing|40"}}},"layout":{"type":"constrained"}} -->
|
||||
<div class="wp-block-group is-style-card-shadow" style="padding-top:var(--wp--preset--spacing--50);padding-right:var(--wp--preset--spacing--40);padding-bottom:var(--wp--preset--spacing--50);padding-left:var(--wp--preset--spacing--40)"><!-- wp:heading {"level":3} -->
|
||||
<h3 class="wp-block-heading"><?php esc_html_e( 'Card Three', 'wp-bootstrap' ); ?></h3>
|
||||
<!-- /wp:heading -->
|
||||
|
||||
<!-- wp:paragraph {"textColor":"secondary"} -->
|
||||
<p class="has-secondary-color has-text-color"><?php esc_html_e( 'Add a short description for this card. Cards are a great way to organize and present related content.', 'wp-bootstrap' ); ?></p>
|
||||
<!-- /wp:paragraph --></div>
|
||||
<!-- /wp:group --></div>
|
||||
<!-- /wp:column --></div>
|
||||
<!-- /wp:columns --></div>
|
||||
<!-- /wp:group -->
|
||||
85
patterns/footer-columns.php
Normal file
85
patterns/footer-columns.php
Normal file
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
/**
|
||||
* Title: Footer - Multi-Column
|
||||
* Slug: wp-bootstrap/footer-columns
|
||||
* Categories: footer
|
||||
* Block Types: core/template-part/footer
|
||||
* Description: Multi-column footer with site info, navigation, and credits.
|
||||
*
|
||||
* @package WPBootstrap
|
||||
* @since 0.2.0
|
||||
*/
|
||||
?>
|
||||
<!-- wp:group {"style":{"spacing":{"padding":{"top":"var:preset|spacing|60","bottom":"var:preset|spacing|50"}}},"backgroundColor":"dark","textColor":"base","layout":{"type":"constrained"}} -->
|
||||
<div class="wp-block-group has-base-color has-dark-background-color has-text-color has-background" style="padding-top:var(--wp--preset--spacing--60);padding-bottom:var(--wp--preset--spacing--50)">
|
||||
<!-- wp:columns {"align":"wide"} -->
|
||||
<div class="wp-block-columns alignwide">
|
||||
<!-- wp:column -->
|
||||
<div class="wp-block-column">
|
||||
<!-- wp:site-title {"level":3} /-->
|
||||
<!-- wp:site-tagline {"fontSize":"small"} /-->
|
||||
<!-- wp:paragraph {"fontSize":"small"} -->
|
||||
<p class="has-small-font-size"><?php esc_html_e( 'A modern WordPress theme built with Bootstrap 5.', 'wp-bootstrap' ); ?></p>
|
||||
<!-- /wp:paragraph -->
|
||||
</div>
|
||||
<!-- /wp:column -->
|
||||
|
||||
<!-- wp:column -->
|
||||
<div class="wp-block-column">
|
||||
<!-- wp:heading {"level":4,"fontSize":"medium"} -->
|
||||
<h4 class="wp-block-heading has-medium-font-size"><?php esc_html_e( 'Navigation', 'wp-bootstrap' ); ?></h4>
|
||||
<!-- /wp:heading -->
|
||||
<!-- wp:navigation {"overlayMenu":"never","layout":{"type":"flex","orientation":"vertical"},"style":{"spacing":{"blockGap":"var:preset|spacing|10"}}} /-->
|
||||
</div>
|
||||
<!-- /wp:column -->
|
||||
|
||||
<!-- wp:column -->
|
||||
<div class="wp-block-column">
|
||||
<!-- wp:heading {"level":4,"fontSize":"medium"} -->
|
||||
<h4 class="wp-block-heading has-medium-font-size"><?php esc_html_e( 'About', 'wp-bootstrap' ); ?></h4>
|
||||
<!-- /wp:heading -->
|
||||
<!-- wp:paragraph {"fontSize":"small"} -->
|
||||
<p class="has-small-font-size"><?php esc_html_e( 'This theme is proudly built with Bootstrap 5 and WordPress Full Site Editing.', 'wp-bootstrap' ); ?></p>
|
||||
<!-- /wp:paragraph -->
|
||||
</div>
|
||||
<!-- /wp:column -->
|
||||
</div>
|
||||
<!-- /wp:columns -->
|
||||
|
||||
<!-- wp:spacer {"height":"var:preset|spacing|40"} -->
|
||||
<div style="height:var(--wp--preset--spacing--40)" aria-hidden="true" class="wp-block-spacer"></div>
|
||||
<!-- /wp:spacer -->
|
||||
|
||||
<!-- wp:separator {"align":"wide","className":"is-style-separator-wide"} -->
|
||||
<hr class="wp-block-separator alignwide has-alpha-channel-opacity is-style-separator-wide"/>
|
||||
<!-- /wp:separator -->
|
||||
|
||||
<!-- wp:group {"align":"wide","layout":{"type":"flex","flexWrap":"wrap","justifyContent":"space-between"}} -->
|
||||
<div class="wp-block-group alignwide">
|
||||
<!-- wp:paragraph {"fontSize":"small"} -->
|
||||
<p class="has-small-font-size">
|
||||
<?php
|
||||
printf(
|
||||
/* translators: Copyright notice. %1$s: Year, %2$s: Site title. */
|
||||
esc_html__( '© %1$s %2$s', 'wp-bootstrap' ),
|
||||
esc_html( gmdate( 'Y' ) ),
|
||||
esc_html( get_bloginfo( 'name' ) )
|
||||
);
|
||||
?>
|
||||
</p>
|
||||
<!-- /wp:paragraph -->
|
||||
<!-- wp:paragraph {"fontSize":"small"} -->
|
||||
<p class="has-small-font-size">
|
||||
<?php
|
||||
printf(
|
||||
/* translators: Powered by WordPress. %s: WordPress link. */
|
||||
esc_html__( 'Powered by %s', 'wp-bootstrap' ),
|
||||
'<a href="' . esc_url( __( 'https://wordpress.org', 'wp-bootstrap' ) ) . '" rel="nofollow">WordPress</a>'
|
||||
);
|
||||
?>
|
||||
</p>
|
||||
<!-- /wp:paragraph -->
|
||||
</div>
|
||||
<!-- /wp:group -->
|
||||
</div>
|
||||
<!-- /wp:group -->
|
||||
35
patterns/footer-minimal.php
Normal file
35
patterns/footer-minimal.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
/**
|
||||
* Title: Footer - Minimal
|
||||
* Slug: wp-bootstrap/footer-minimal
|
||||
* Categories: footer
|
||||
* Block Types: core/template-part/footer
|
||||
* Description: Minimal single-line footer with copyright.
|
||||
*
|
||||
* @package WPBootstrap
|
||||
* @since 0.2.0
|
||||
*/
|
||||
?>
|
||||
<!-- wp:group {"style":{"spacing":{"padding":{"top":"var:preset|spacing|40","bottom":"var:preset|spacing|40"}}},"layout":{"type":"constrained"}} -->
|
||||
<div class="wp-block-group" style="padding-top:var(--wp--preset--spacing--40);padding-bottom:var(--wp--preset--spacing--40)">
|
||||
<!-- wp:separator {"className":"is-style-separator-wide","style":{"spacing":{"margin":{"bottom":"var:preset|spacing|40"}}}} -->
|
||||
<hr class="wp-block-separator has-alpha-channel-opacity is-style-separator-wide" style="margin-bottom:var(--wp--preset--spacing--40)"/>
|
||||
<!-- /wp:separator -->
|
||||
<!-- wp:group {"align":"wide","layout":{"type":"flex","flexWrap":"nowrap","justifyContent":"center"}} -->
|
||||
<div class="wp-block-group alignwide">
|
||||
<!-- wp:paragraph {"fontSize":"small"} -->
|
||||
<p class="has-small-font-size">
|
||||
<?php
|
||||
printf(
|
||||
/* translators: Copyright notice. %1$s: Year, %2$s: Site title. */
|
||||
esc_html__( '© %1$s %2$s. All rights reserved.', 'wp-bootstrap' ),
|
||||
esc_html( gmdate( 'Y' ) ),
|
||||
esc_html( get_bloginfo( 'name' ) )
|
||||
);
|
||||
?>
|
||||
</p>
|
||||
<!-- /wp:paragraph -->
|
||||
</div>
|
||||
<!-- /wp:group -->
|
||||
</div>
|
||||
<!-- /wp:group -->
|
||||
32
patterns/header-centered.php
Normal file
32
patterns/header-centered.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
/**
|
||||
* Title: Header - Centered
|
||||
* Slug: wp-bootstrap/header-centered
|
||||
* Categories: header
|
||||
* Block Types: core/template-part/header
|
||||
* Description: Centered header with site title above navigation.
|
||||
*
|
||||
* @package WPBootstrap
|
||||
* @since 0.2.0
|
||||
*/
|
||||
?>
|
||||
<!-- wp:group {"align":"full","layout":{"type":"default"}} -->
|
||||
<div class="wp-block-group alignfull">
|
||||
<!-- wp:group {"layout":{"type":"constrained"}} -->
|
||||
<div class="wp-block-group">
|
||||
<!-- wp:group {"align":"wide","style":{"spacing":{"padding":{"top":"var:preset|spacing|40","bottom":"var:preset|spacing|20"}}},"layout":{"type":"flex","orientation":"vertical","justifyContent":"center"}} -->
|
||||
<div class="wp-block-group alignwide" style="padding-top:var(--wp--preset--spacing--40);padding-bottom:var(--wp--preset--spacing--20)">
|
||||
<!-- wp:site-title {"level":0,"textAlign":"center"} /-->
|
||||
<!-- wp:site-tagline {"textAlign":"center","fontSize":"small"} /-->
|
||||
</div>
|
||||
<!-- /wp:group -->
|
||||
<!-- wp:group {"align":"wide","style":{"spacing":{"padding":{"top":"var:preset|spacing|20","bottom":"var:preset|spacing|30"}}},"layout":{"type":"flex","flexWrap":"nowrap","justifyContent":"center"}} -->
|
||||
<div class="wp-block-group alignwide" style="padding-top:var(--wp--preset--spacing--20);padding-bottom:var(--wp--preset--spacing--30)">
|
||||
<!-- wp:navigation {"overlayBackgroundColor":"base","overlayTextColor":"contrast","layout":{"type":"flex","justifyContent":"center","flexWrap":"wrap"}} /-->
|
||||
<!-- wp:pattern {"slug":"wp-bootstrap/dark-mode-toggle"} /-->
|
||||
</div>
|
||||
<!-- /wp:group -->
|
||||
</div>
|
||||
<!-- /wp:group -->
|
||||
</div>
|
||||
<!-- /wp:group -->
|
||||
31
patterns/header-transparent.php
Normal file
31
patterns/header-transparent.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
/**
|
||||
* Title: Header - Transparent
|
||||
* Slug: wp-bootstrap/header-transparent
|
||||
* Categories: header
|
||||
* Block Types: core/template-part/header
|
||||
* Description: Transparent header that overlays page content, ideal for hero sections.
|
||||
*
|
||||
* @package WPBootstrap
|
||||
* @since 0.2.0
|
||||
*/
|
||||
?>
|
||||
<!-- wp:group {"align":"full","style":{"spacing":{"padding":{"top":"0","bottom":"0"}}},"layout":{"type":"default"}} -->
|
||||
<div class="wp-block-group alignfull" style="padding-top:0;padding-bottom:0">
|
||||
<!-- wp:group {"layout":{"type":"constrained"}} -->
|
||||
<div class="wp-block-group">
|
||||
<!-- wp:group {"align":"wide","style":{"spacing":{"padding":{"top":"var:preset|spacing|30","bottom":"var:preset|spacing|30"}}},"layout":{"type":"flex","flexWrap":"nowrap","justifyContent":"space-between"}} -->
|
||||
<div class="wp-block-group alignwide" style="padding-top:var(--wp--preset--spacing--30);padding-bottom:var(--wp--preset--spacing--30)">
|
||||
<!-- wp:site-title {"level":0,"style":{"elements":{"link":{"color":{"text":"var:preset|color|base"}}}}} /-->
|
||||
<!-- wp:group {"style":{"spacing":{"blockGap":"var:preset|spacing|20"}},"layout":{"type":"flex","flexWrap":"nowrap","justifyContent":"right","verticalAlignment":"center"}} -->
|
||||
<div class="wp-block-group">
|
||||
<!-- wp:navigation {"overlayBackgroundColor":"base","overlayTextColor":"contrast","style":{"elements":{"link":{"color":{"text":"var:preset|color|base"}}}},"layout":{"type":"flex","justifyContent":"right","flexWrap":"wrap"}} /-->
|
||||
<!-- wp:pattern {"slug":"wp-bootstrap/dark-mode-toggle"} /-->
|
||||
</div>
|
||||
<!-- /wp:group -->
|
||||
</div>
|
||||
<!-- /wp:group -->
|
||||
</div>
|
||||
<!-- /wp:group -->
|
||||
</div>
|
||||
<!-- /wp:group -->
|
||||
34
patterns/layout-2-col.php
Normal file
34
patterns/layout-2-col.php
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
/**
|
||||
* Title: Two Columns
|
||||
* Slug: wp-bootstrap/layout-2-col
|
||||
* Categories: wp-bootstrap-layout, columns
|
||||
* Description: A two-column layout with equal width columns, each containing a heading and paragraph.
|
||||
*
|
||||
* @package WPBootstrap
|
||||
* @since 0.2.0
|
||||
*/
|
||||
?>
|
||||
<!-- wp:group {"align":"full","style":{"spacing":{"padding":{"top":"var:preset|spacing|60","bottom":"var:preset|spacing|60"}}},"layout":{"type":"constrained"}} -->
|
||||
<div class="wp-block-group alignfull" style="padding-top:var(--wp--preset--spacing--60);padding-bottom:var(--wp--preset--spacing--60)"><!-- wp:columns {"align":"wide","style":{"spacing":{"blockGap":{"left":"var:preset|spacing|50"}}}} -->
|
||||
<div class="wp-block-columns alignwide"><!-- wp:column -->
|
||||
<div class="wp-block-column"><!-- wp:heading {"level":3,"fontSize":"x-large"} -->
|
||||
<h3 class="wp-block-heading has-x-large-font-size"><?php esc_html_e( 'Column One', 'wp-bootstrap' ); ?></h3>
|
||||
<!-- /wp:heading -->
|
||||
|
||||
<!-- wp:paragraph {"textColor":"secondary"} -->
|
||||
<p class="has-secondary-color has-text-color"><?php esc_html_e( 'Add your content here. This column takes up half the available width on larger screens and stacks on mobile devices.', 'wp-bootstrap' ); ?></p>
|
||||
<!-- /wp:paragraph --></div>
|
||||
<!-- /wp:column -->
|
||||
|
||||
<!-- wp:column -->
|
||||
<div class="wp-block-column"><!-- wp:heading {"level":3,"fontSize":"x-large"} -->
|
||||
<h3 class="wp-block-heading has-x-large-font-size"><?php esc_html_e( 'Column Two', 'wp-bootstrap' ); ?></h3>
|
||||
<!-- /wp:heading -->
|
||||
|
||||
<!-- wp:paragraph {"textColor":"secondary"} -->
|
||||
<p class="has-secondary-color has-text-color"><?php esc_html_e( 'Add your content here. This column takes up half the available width on larger screens and stacks on mobile devices.', 'wp-bootstrap' ); ?></p>
|
||||
<!-- /wp:paragraph --></div>
|
||||
<!-- /wp:column --></div>
|
||||
<!-- /wp:columns --></div>
|
||||
<!-- /wp:group -->
|
||||
44
patterns/layout-3-col.php
Normal file
44
patterns/layout-3-col.php
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
/**
|
||||
* Title: Three Columns
|
||||
* Slug: wp-bootstrap/layout-3-col
|
||||
* Categories: wp-bootstrap-layout, columns
|
||||
* Description: A three-column layout with equal width columns, each containing a heading and paragraph.
|
||||
*
|
||||
* @package WPBootstrap
|
||||
* @since 0.2.0
|
||||
*/
|
||||
?>
|
||||
<!-- wp:group {"align":"full","style":{"spacing":{"padding":{"top":"var:preset|spacing|60","bottom":"var:preset|spacing|60"}}},"layout":{"type":"constrained"}} -->
|
||||
<div class="wp-block-group alignfull" style="padding-top:var(--wp--preset--spacing--60);padding-bottom:var(--wp--preset--spacing--60)"><!-- wp:columns {"align":"wide","style":{"spacing":{"blockGap":{"left":"var:preset|spacing|50"}}}} -->
|
||||
<div class="wp-block-columns alignwide"><!-- wp:column -->
|
||||
<div class="wp-block-column"><!-- wp:heading {"level":3,"fontSize":"x-large"} -->
|
||||
<h3 class="wp-block-heading has-x-large-font-size"><?php esc_html_e( 'Column One', 'wp-bootstrap' ); ?></h3>
|
||||
<!-- /wp:heading -->
|
||||
|
||||
<!-- wp:paragraph {"textColor":"secondary"} -->
|
||||
<p class="has-secondary-color has-text-color"><?php esc_html_e( 'Add your content here. This column takes up one third of the available width on larger screens.', 'wp-bootstrap' ); ?></p>
|
||||
<!-- /wp:paragraph --></div>
|
||||
<!-- /wp:column -->
|
||||
|
||||
<!-- wp:column -->
|
||||
<div class="wp-block-column"><!-- wp:heading {"level":3,"fontSize":"x-large"} -->
|
||||
<h3 class="wp-block-heading has-x-large-font-size"><?php esc_html_e( 'Column Two', 'wp-bootstrap' ); ?></h3>
|
||||
<!-- /wp:heading -->
|
||||
|
||||
<!-- wp:paragraph {"textColor":"secondary"} -->
|
||||
<p class="has-secondary-color has-text-color"><?php esc_html_e( 'Add your content here. This column takes up one third of the available width on larger screens.', 'wp-bootstrap' ); ?></p>
|
||||
<!-- /wp:paragraph --></div>
|
||||
<!-- /wp:column -->
|
||||
|
||||
<!-- wp:column -->
|
||||
<div class="wp-block-column"><!-- wp:heading {"level":3,"fontSize":"x-large"} -->
|
||||
<h3 class="wp-block-heading has-x-large-font-size"><?php esc_html_e( 'Column Three', 'wp-bootstrap' ); ?></h3>
|
||||
<!-- /wp:heading -->
|
||||
|
||||
<!-- wp:paragraph {"textColor":"secondary"} -->
|
||||
<p class="has-secondary-color has-text-color"><?php esc_html_e( 'Add your content here. This column takes up one third of the available width on larger screens.', 'wp-bootstrap' ); ?></p>
|
||||
<!-- /wp:paragraph --></div>
|
||||
<!-- /wp:column --></div>
|
||||
<!-- /wp:columns --></div>
|
||||
<!-- /wp:group -->
|
||||
20
patterns/layout-container.php
Normal file
20
patterns/layout-container.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
/**
|
||||
* Title: Bootstrap Container
|
||||
* Slug: wp-bootstrap/layout-container
|
||||
* Categories: wp-bootstrap-layout
|
||||
* Description: A constrained container with padding, containing a heading and paragraph placeholder.
|
||||
*
|
||||
* @package WPBootstrap
|
||||
* @since 0.2.0
|
||||
*/
|
||||
?>
|
||||
<!-- wp:group {"align":"full","style":{"spacing":{"padding":{"top":"var:preset|spacing|60","bottom":"var:preset|spacing|60","left":"var:preset|spacing|40","right":"var:preset|spacing|40"}}},"layout":{"type":"constrained"}} -->
|
||||
<div class="wp-block-group alignfull" style="padding-top:var(--wp--preset--spacing--60);padding-right:var(--wp--preset--spacing--40);padding-bottom:var(--wp--preset--spacing--60);padding-left:var(--wp--preset--spacing--40)"><!-- wp:heading {"fontSize":"xx-large"} -->
|
||||
<h2 class="wp-block-heading has-xx-large-font-size"><?php esc_html_e( 'Heading goes here', 'wp-bootstrap' ); ?></h2>
|
||||
<!-- /wp:heading -->
|
||||
|
||||
<!-- wp:paragraph -->
|
||||
<p><?php esc_html_e( 'This is a content container with constrained width and comfortable padding. Replace this text with your own content.', 'wp-bootstrap' ); ?></p>
|
||||
<!-- /wp:paragraph --></div>
|
||||
<!-- /wp:group -->
|
||||
20
patterns/layout-full-width-section.php
Normal file
20
patterns/layout-full-width-section.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
/**
|
||||
* Title: Full Width Section
|
||||
* Slug: wp-bootstrap/layout-full-width-section
|
||||
* Categories: wp-bootstrap-layout, banner
|
||||
* Description: A full-width section with a primary background color, centered white heading and paragraph.
|
||||
*
|
||||
* @package WPBootstrap
|
||||
* @since 0.2.0
|
||||
*/
|
||||
?>
|
||||
<!-- wp:group {"align":"full","style":{"spacing":{"padding":{"top":"var:preset|spacing|80","bottom":"var:preset|spacing|80"}}},"backgroundColor":"primary","textColor":"base","layout":{"type":"constrained"}} -->
|
||||
<div class="wp-block-group alignfull has-base-color has-primary-background-color has-text-color has-background" style="padding-top:var(--wp--preset--spacing--80);padding-bottom:var(--wp--preset--spacing--80)"><!-- wp:heading {"textAlign":"center","fontSize":"xx-large"} -->
|
||||
<h2 class="wp-block-heading has-text-align-center has-xx-large-font-size"><?php esc_html_e( 'Full Width Section Heading', 'wp-bootstrap' ); ?></h2>
|
||||
<!-- /wp:heading -->
|
||||
|
||||
<!-- wp:paragraph {"align":"center","fontSize":"large"} -->
|
||||
<p class="has-text-align-center has-large-font-size"><?php esc_html_e( 'This full-width section stands out with a colored background. Use it to highlight important content, announcements, or calls to action.', 'wp-bootstrap' ); ?></p>
|
||||
<!-- /wp:paragraph --></div>
|
||||
<!-- /wp:group -->
|
||||
31
patterns/nav-dark.php
Normal file
31
patterns/nav-dark.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
/**
|
||||
* Title: Navigation - Dark
|
||||
* Slug: wp-bootstrap/nav-dark
|
||||
* Categories: wp-bootstrap-navigation, header
|
||||
* Block Types: core/template-part/header
|
||||
* Description: Dark-themed navigation header with dark background.
|
||||
*
|
||||
* @package WPBootstrap
|
||||
* @since 0.2.0
|
||||
*/
|
||||
?>
|
||||
<!-- wp:group {"align":"full","backgroundColor":"dark","textColor":"base","layout":{"type":"default"}} -->
|
||||
<div class="wp-block-group alignfull has-base-color has-dark-background-color has-text-color has-background">
|
||||
<!-- wp:group {"layout":{"type":"constrained"}} -->
|
||||
<div class="wp-block-group">
|
||||
<!-- wp:group {"align":"wide","style":{"spacing":{"padding":{"top":"var:preset|spacing|30","bottom":"var:preset|spacing|30"}}},"layout":{"type":"flex","flexWrap":"nowrap","justifyContent":"space-between"}} -->
|
||||
<div class="wp-block-group alignwide" style="padding-top:var(--wp--preset--spacing--30);padding-bottom:var(--wp--preset--spacing--30)">
|
||||
<!-- wp:site-title {"level":0,"style":{"elements":{"link":{"color":{"text":"var:preset|color|base"}}}}} /-->
|
||||
<!-- wp:group {"style":{"spacing":{"blockGap":"var:preset|spacing|20"}},"layout":{"type":"flex","flexWrap":"nowrap","justifyContent":"right","verticalAlignment":"center"}} -->
|
||||
<div class="wp-block-group">
|
||||
<!-- wp:navigation {"overlayBackgroundColor":"dark","overlayTextColor":"base","style":{"elements":{"link":{"color":{"text":"var:preset|color|base"}}}},"layout":{"type":"flex","justifyContent":"right","flexWrap":"wrap"}} /-->
|
||||
<!-- wp:pattern {"slug":"wp-bootstrap/dark-mode-toggle"} /-->
|
||||
</div>
|
||||
<!-- /wp:group -->
|
||||
</div>
|
||||
<!-- /wp:group -->
|
||||
</div>
|
||||
<!-- /wp:group -->
|
||||
</div>
|
||||
<!-- /wp:group -->
|
||||
31
patterns/nav-offcanvas.php
Normal file
31
patterns/nav-offcanvas.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
/**
|
||||
* Title: Navigation - Offcanvas
|
||||
* Slug: wp-bootstrap/nav-offcanvas
|
||||
* Categories: wp-bootstrap-navigation, header
|
||||
* Block Types: core/template-part/header
|
||||
* Description: Header with offcanvas mobile navigation using Bootstrap offcanvas component.
|
||||
*
|
||||
* @package WPBootstrap
|
||||
* @since 0.2.0
|
||||
*/
|
||||
?>
|
||||
<!-- wp:group {"align":"full","layout":{"type":"default"}} -->
|
||||
<div class="wp-block-group alignfull">
|
||||
<!-- wp:group {"layout":{"type":"constrained"}} -->
|
||||
<div class="wp-block-group">
|
||||
<!-- wp:group {"align":"wide","style":{"spacing":{"padding":{"top":"var:preset|spacing|30","bottom":"var:preset|spacing|30"}}},"layout":{"type":"flex","flexWrap":"nowrap","justifyContent":"space-between"}} -->
|
||||
<div class="wp-block-group alignwide" style="padding-top:var(--wp--preset--spacing--30);padding-bottom:var(--wp--preset--spacing--30)">
|
||||
<!-- wp:site-title {"level":0} /-->
|
||||
<!-- wp:group {"style":{"spacing":{"blockGap":"var:preset|spacing|20"}},"layout":{"type":"flex","flexWrap":"nowrap","justifyContent":"right","verticalAlignment":"center"}} -->
|
||||
<div class="wp-block-group">
|
||||
<!-- wp:navigation {"overlayMenu":"always","overlayBackgroundColor":"base","overlayTextColor":"contrast","layout":{"type":"flex","justifyContent":"right","flexWrap":"wrap"}} /-->
|
||||
<!-- wp:pattern {"slug":"wp-bootstrap/dark-mode-toggle"} /-->
|
||||
</div>
|
||||
<!-- /wp:group -->
|
||||
</div>
|
||||
<!-- /wp:group -->
|
||||
</div>
|
||||
<!-- /wp:group -->
|
||||
</div>
|
||||
<!-- /wp:group -->
|
||||
92
patterns/page-about.php
Normal file
92
patterns/page-about.php
Normal file
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
/**
|
||||
* Title: About Page
|
||||
* Slug: wp-bootstrap/page-about
|
||||
* Categories: wp-bootstrap_page
|
||||
* Description: A full about page layout with hero, story section, and team members.
|
||||
*
|
||||
* @package WPBootstrap
|
||||
* @since 0.2.0
|
||||
*/
|
||||
?>
|
||||
<!-- wp:group {"align":"full","style":{"spacing":{"padding":{"top":"var:preset|spacing|80","bottom":"var:preset|spacing|80"}}},"backgroundColor":"primary","textColor":"base","layout":{"type":"constrained"}} -->
|
||||
<div class="wp-block-group alignfull has-base-color has-primary-background-color has-text-color has-background" style="padding-top:var(--wp--preset--spacing--80);padding-bottom:var(--wp--preset--spacing--80)"><!-- wp:heading {"textAlign":"center","level":1,"fontSize":"display"} -->
|
||||
<h1 class="wp-block-heading has-text-align-center has-display-font-size"><?php esc_html_e( 'About Us', 'wp-bootstrap' ); ?></h1>
|
||||
<!-- /wp:heading -->
|
||||
|
||||
<!-- wp:paragraph {"align":"center","fontSize":"large"} -->
|
||||
<p class="has-text-align-center has-large-font-size"><?php esc_html_e( 'Learn more about who we are, what we do, and the people behind our mission.', 'wp-bootstrap' ); ?></p>
|
||||
<!-- /wp:paragraph --></div>
|
||||
<!-- /wp:group -->
|
||||
|
||||
<!-- wp:group {"align":"full","style":{"spacing":{"padding":{"top":"var:preset|spacing|70","bottom":"var:preset|spacing|70"}}},"layout":{"type":"constrained"}} -->
|
||||
<div class="wp-block-group alignfull" style="padding-top:var(--wp--preset--spacing--70);padding-bottom:var(--wp--preset--spacing--70)"><!-- wp:columns {"align":"wide","style":{"spacing":{"blockGap":{"left":"var:preset|spacing|60"}}}} -->
|
||||
<div class="wp-block-columns alignwide"><!-- wp:column {"verticalAlignment":"center"} -->
|
||||
<div class="wp-block-column is-vertically-aligned-center"><!-- wp:heading {"fontSize":"xx-large"} -->
|
||||
<h2 class="wp-block-heading has-xx-large-font-size"><?php esc_html_e( 'Our Story', 'wp-bootstrap' ); ?></h2>
|
||||
<!-- /wp:heading -->
|
||||
|
||||
<!-- wp:paragraph -->
|
||||
<p><?php esc_html_e( 'Founded with a passion for innovation and excellence, our journey began with a simple idea: to create meaningful solutions that make a real difference. Over the years, we have grown from a small team into a dedicated group of professionals committed to delivering outstanding results.', 'wp-bootstrap' ); ?></p>
|
||||
<!-- /wp:paragraph -->
|
||||
|
||||
<!-- wp:paragraph {"textColor":"secondary"} -->
|
||||
<p class="has-secondary-color has-text-color"><?php esc_html_e( 'Today, we continue to push boundaries and challenge conventions. Our approach combines creative thinking with proven methodologies, ensuring that every project we undertake meets the highest standards of quality and craftsmanship.', 'wp-bootstrap' ); ?></p>
|
||||
<!-- /wp:paragraph --></div>
|
||||
<!-- /wp:column -->
|
||||
|
||||
<!-- wp:column {"verticalAlignment":"center"} -->
|
||||
<div class="wp-block-column is-vertically-aligned-center"><!-- wp:image {"sizeSlug":"large","style":{"border":{"radius":"0.5rem"}}} -->
|
||||
<figure class="wp-block-image size-large" style="border-radius:0.5rem"><img src="" alt="<?php esc_attr_e( 'About us image', 'wp-bootstrap' ); ?>"/></figure>
|
||||
<!-- /wp:image --></div>
|
||||
<!-- /wp:column --></div>
|
||||
<!-- /wp:columns --></div>
|
||||
<!-- /wp:group -->
|
||||
|
||||
<!-- wp:group {"align":"full","style":{"spacing":{"padding":{"top":"var:preset|spacing|70","bottom":"var:preset|spacing|70"}}},"backgroundColor":"light","layout":{"type":"constrained"}} -->
|
||||
<div class="wp-block-group alignfull has-light-background-color has-background" style="padding-top:var(--wp--preset--spacing--70);padding-bottom:var(--wp--preset--spacing--70)"><!-- wp:heading {"textAlign":"center","fontSize":"xx-large"} -->
|
||||
<h2 class="wp-block-heading has-text-align-center has-xx-large-font-size"><?php esc_html_e( 'Our Team', 'wp-bootstrap' ); ?></h2>
|
||||
<!-- /wp:heading -->
|
||||
|
||||
<!-- wp:paragraph {"align":"center","textColor":"secondary"} -->
|
||||
<p class="has-text-align-center has-secondary-color has-text-color"><?php esc_html_e( 'Meet the people who make it all happen.', 'wp-bootstrap' ); ?></p>
|
||||
<!-- /wp:paragraph -->
|
||||
|
||||
<!-- wp:columns {"align":"wide","style":{"spacing":{"blockGap":{"left":"var:preset|spacing|40"}}}} -->
|
||||
<div class="wp-block-columns alignwide"><!-- wp:column -->
|
||||
<div class="wp-block-column"><!-- wp:group {"className":"is-style-card","style":{"spacing":{"padding":{"top":"var:preset|spacing|50","bottom":"var:preset|spacing|50","left":"var:preset|spacing|40","right":"var:preset|spacing|40"}}},"layout":{"type":"constrained"}} -->
|
||||
<div class="wp-block-group is-style-card" style="padding-top:var(--wp--preset--spacing--50);padding-right:var(--wp--preset--spacing--40);padding-bottom:var(--wp--preset--spacing--50);padding-left:var(--wp--preset--spacing--40)"><!-- wp:heading {"textAlign":"center","level":3} -->
|
||||
<h3 class="wp-block-heading has-text-align-center"><?php esc_html_e( 'Jane Doe', 'wp-bootstrap' ); ?></h3>
|
||||
<!-- /wp:heading -->
|
||||
|
||||
<!-- wp:paragraph {"align":"center","textColor":"secondary"} -->
|
||||
<p class="has-text-align-center has-secondary-color has-text-color"><?php esc_html_e( 'Founder & CEO', 'wp-bootstrap' ); ?></p>
|
||||
<!-- /wp:paragraph --></div>
|
||||
<!-- /wp:group --></div>
|
||||
<!-- /wp:column -->
|
||||
|
||||
<!-- wp:column -->
|
||||
<div class="wp-block-column"><!-- wp:group {"className":"is-style-card","style":{"spacing":{"padding":{"top":"var:preset|spacing|50","bottom":"var:preset|spacing|50","left":"var:preset|spacing|40","right":"var:preset|spacing|40"}}},"layout":{"type":"constrained"}} -->
|
||||
<div class="wp-block-group is-style-card" style="padding-top:var(--wp--preset--spacing--50);padding-right:var(--wp--preset--spacing--40);padding-bottom:var(--wp--preset--spacing--50);padding-left:var(--wp--preset--spacing--40)"><!-- wp:heading {"textAlign":"center","level":3} -->
|
||||
<h3 class="wp-block-heading has-text-align-center"><?php esc_html_e( 'John Smith', 'wp-bootstrap' ); ?></h3>
|
||||
<!-- /wp:heading -->
|
||||
|
||||
<!-- wp:paragraph {"align":"center","textColor":"secondary"} -->
|
||||
<p class="has-text-align-center has-secondary-color has-text-color"><?php esc_html_e( 'Lead Developer', 'wp-bootstrap' ); ?></p>
|
||||
<!-- /wp:paragraph --></div>
|
||||
<!-- /wp:group --></div>
|
||||
<!-- /wp:column -->
|
||||
|
||||
<!-- wp:column -->
|
||||
<div class="wp-block-column"><!-- wp:group {"className":"is-style-card","style":{"spacing":{"padding":{"top":"var:preset|spacing|50","bottom":"var:preset|spacing|50","left":"var:preset|spacing|40","right":"var:preset|spacing|40"}}},"layout":{"type":"constrained"}} -->
|
||||
<div class="wp-block-group is-style-card" style="padding-top:var(--wp--preset--spacing--50);padding-right:var(--wp--preset--spacing--40);padding-bottom:var(--wp--preset--spacing--50);padding-left:var(--wp--preset--spacing--40)"><!-- wp:heading {"textAlign":"center","level":3} -->
|
||||
<h3 class="wp-block-heading has-text-align-center"><?php esc_html_e( 'Emily Johnson', 'wp-bootstrap' ); ?></h3>
|
||||
<!-- /wp:heading -->
|
||||
|
||||
<!-- wp:paragraph {"align":"center","textColor":"secondary"} -->
|
||||
<p class="has-text-align-center has-secondary-color has-text-color"><?php esc_html_e( 'Creative Director', 'wp-bootstrap' ); ?></p>
|
||||
<!-- /wp:paragraph --></div>
|
||||
<!-- /wp:group --></div>
|
||||
<!-- /wp:column --></div>
|
||||
<!-- /wp:columns --></div>
|
||||
<!-- /wp:group -->
|
||||
66
patterns/page-contact.php
Normal file
66
patterns/page-contact.php
Normal file
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
/**
|
||||
* Title: Contact Page
|
||||
* Slug: wp-bootstrap/page-contact
|
||||
* Categories: wp-bootstrap_page
|
||||
* Description: A full contact page layout with hero, contact details, business hours, and spacer.
|
||||
*
|
||||
* @package WPBootstrap
|
||||
* @since 0.2.0
|
||||
*/
|
||||
?>
|
||||
<!-- wp:group {"align":"full","style":{"spacing":{"padding":{"top":"var:preset|spacing|80","bottom":"var:preset|spacing|80"}}},"backgroundColor":"primary","textColor":"base","layout":{"type":"constrained"}} -->
|
||||
<div class="wp-block-group alignfull has-base-color has-primary-background-color has-text-color has-background" style="padding-top:var(--wp--preset--spacing--80);padding-bottom:var(--wp--preset--spacing--80)"><!-- wp:heading {"textAlign":"center","level":1,"fontSize":"display"} -->
|
||||
<h1 class="wp-block-heading has-text-align-center has-display-font-size"><?php esc_html_e( 'Contact Us', 'wp-bootstrap' ); ?></h1>
|
||||
<!-- /wp:heading -->
|
||||
|
||||
<!-- wp:paragraph {"align":"center","fontSize":"large"} -->
|
||||
<p class="has-text-align-center has-large-font-size"><?php esc_html_e( 'We would love to hear from you. Reach out to us anytime.', 'wp-bootstrap' ); ?></p>
|
||||
<!-- /wp:paragraph --></div>
|
||||
<!-- /wp:group -->
|
||||
|
||||
<!-- wp:group {"align":"full","style":{"spacing":{"padding":{"top":"var:preset|spacing|70","bottom":"var:preset|spacing|70"}}},"layout":{"type":"constrained"}} -->
|
||||
<div class="wp-block-group alignfull" style="padding-top:var(--wp--preset--spacing--70);padding-bottom:var(--wp--preset--spacing--70)"><!-- wp:columns {"align":"wide","style":{"spacing":{"blockGap":{"left":"var:preset|spacing|60"}}}} -->
|
||||
<div class="wp-block-columns alignwide"><!-- wp:column {"verticalAlignment":"top"} -->
|
||||
<div class="wp-block-column is-vertically-aligned-top"><!-- wp:heading {"fontSize":"xx-large"} -->
|
||||
<h2 class="wp-block-heading has-xx-large-font-size"><?php esc_html_e( 'Get in Touch', 'wp-bootstrap' ); ?></h2>
|
||||
<!-- /wp:heading -->
|
||||
|
||||
<!-- wp:paragraph -->
|
||||
<p><strong><?php esc_html_e( 'Address', 'wp-bootstrap' ); ?></strong><br><?php esc_html_e( '123 Main Street, Suite 100, Anytown, ST 12345', 'wp-bootstrap' ); ?></p>
|
||||
<!-- /wp:paragraph -->
|
||||
|
||||
<!-- wp:paragraph -->
|
||||
<p><strong><?php esc_html_e( 'Email', 'wp-bootstrap' ); ?></strong><br><?php esc_html_e( 'info@example.com', 'wp-bootstrap' ); ?></p>
|
||||
<!-- /wp:paragraph -->
|
||||
|
||||
<!-- wp:paragraph -->
|
||||
<p><strong><?php esc_html_e( 'Phone', 'wp-bootstrap' ); ?></strong><br><?php esc_html_e( '+1 (555) 123-4567', 'wp-bootstrap' ); ?></p>
|
||||
<!-- /wp:paragraph --></div>
|
||||
<!-- /wp:column -->
|
||||
|
||||
<!-- wp:column {"verticalAlignment":"top"} -->
|
||||
<div class="wp-block-column is-vertically-aligned-top"><!-- wp:heading {"fontSize":"xx-large"} -->
|
||||
<h2 class="wp-block-heading has-xx-large-font-size"><?php esc_html_e( 'Business Hours', 'wp-bootstrap' ); ?></h2>
|
||||
<!-- /wp:heading -->
|
||||
|
||||
<!-- wp:list {"className":"is-style-list-unstyled","style":{"spacing":{"blockGap":"var:preset|spacing|20"}}} -->
|
||||
<ul class="is-style-list-unstyled"><!-- wp:list-item -->
|
||||
<li><strong><?php esc_html_e( 'Monday - Friday:', 'wp-bootstrap' ); ?></strong> <?php esc_html_e( '9:00 AM - 6:00 PM', 'wp-bootstrap' ); ?></li>
|
||||
<!-- /wp:list-item -->
|
||||
|
||||
<!-- wp:list-item -->
|
||||
<li><strong><?php esc_html_e( 'Saturday:', 'wp-bootstrap' ); ?></strong> <?php esc_html_e( '10:00 AM - 4:00 PM', 'wp-bootstrap' ); ?></li>
|
||||
<!-- /wp:list-item -->
|
||||
|
||||
<!-- wp:list-item -->
|
||||
<li><strong><?php esc_html_e( 'Sunday:', 'wp-bootstrap' ); ?></strong> <?php esc_html_e( 'Closed', 'wp-bootstrap' ); ?></li>
|
||||
<!-- /wp:list-item --></ul>
|
||||
<!-- /wp:list --></div>
|
||||
<!-- /wp:column --></div>
|
||||
<!-- /wp:columns --></div>
|
||||
<!-- /wp:group -->
|
||||
|
||||
<!-- wp:spacer {"height":"var:preset|spacing|70"} -->
|
||||
<div style="height:var(--wp--preset--spacing--70)" aria-hidden="true" class="wp-block-spacer"></div>
|
||||
<!-- /wp:spacer -->
|
||||
94
patterns/page-services.php
Normal file
94
patterns/page-services.php
Normal file
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
/**
|
||||
* Title: Services Page
|
||||
* Slug: wp-bootstrap/page-services
|
||||
* Categories: wp-bootstrap_page
|
||||
* Description: A full services page layout with hero, service offerings, and call to action.
|
||||
*
|
||||
* @package WPBootstrap
|
||||
* @since 0.2.0
|
||||
*/
|
||||
?>
|
||||
<!-- wp:group {"align":"full","style":{"spacing":{"padding":{"top":"var:preset|spacing|80","bottom":"var:preset|spacing|80"}}},"backgroundColor":"dark","textColor":"base","layout":{"type":"constrained"}} -->
|
||||
<div class="wp-block-group alignfull has-base-color has-dark-background-color has-text-color has-background" style="padding-top:var(--wp--preset--spacing--80);padding-bottom:var(--wp--preset--spacing--80)"><!-- wp:heading {"textAlign":"center","level":1,"fontSize":"display"} -->
|
||||
<h1 class="wp-block-heading has-text-align-center has-display-font-size"><?php esc_html_e( 'Our Services', 'wp-bootstrap' ); ?></h1>
|
||||
<!-- /wp:heading -->
|
||||
|
||||
<!-- wp:paragraph {"align":"center","fontSize":"large"} -->
|
||||
<p class="has-text-align-center has-large-font-size"><?php esc_html_e( 'Professional solutions tailored to your needs.', 'wp-bootstrap' ); ?></p>
|
||||
<!-- /wp:paragraph --></div>
|
||||
<!-- /wp:group -->
|
||||
|
||||
<!-- wp:group {"align":"full","style":{"spacing":{"padding":{"top":"var:preset|spacing|70","bottom":"var:preset|spacing|70"}}},"layout":{"type":"constrained"}} -->
|
||||
<div class="wp-block-group alignfull" style="padding-top:var(--wp--preset--spacing--70);padding-bottom:var(--wp--preset--spacing--70)"><!-- wp:heading {"textAlign":"center","fontSize":"xx-large"} -->
|
||||
<h2 class="wp-block-heading has-text-align-center has-xx-large-font-size"><?php esc_html_e( 'What We Offer', 'wp-bootstrap' ); ?></h2>
|
||||
<!-- /wp:heading -->
|
||||
|
||||
<!-- wp:paragraph {"align":"center","textColor":"secondary"} -->
|
||||
<p class="has-text-align-center has-secondary-color has-text-color"><?php esc_html_e( 'We provide a wide range of services to help your business grow and succeed.', 'wp-bootstrap' ); ?></p>
|
||||
<!-- /wp:paragraph -->
|
||||
|
||||
<!-- wp:columns {"align":"wide","style":{"spacing":{"blockGap":{"left":"var:preset|spacing|50"}}}} -->
|
||||
<div class="wp-block-columns alignwide"><!-- wp:column -->
|
||||
<div class="wp-block-column"><!-- wp:heading {"textAlign":"center","level":3,"fontSize":"display"} -->
|
||||
<h3 class="wp-block-heading has-text-align-center has-display-font-size"><?php esc_html_e( "\xF0\x9F\x8E\xA8", 'wp-bootstrap' ); ?></h3>
|
||||
<!-- /wp:heading -->
|
||||
|
||||
<!-- wp:heading {"textAlign":"center","level":3} -->
|
||||
<h3 class="wp-block-heading has-text-align-center"><?php esc_html_e( 'Design', 'wp-bootstrap' ); ?></h3>
|
||||
<!-- /wp:heading -->
|
||||
|
||||
<!-- wp:paragraph {"align":"center","textColor":"secondary"} -->
|
||||
<p class="has-text-align-center has-secondary-color has-text-color"><?php esc_html_e( 'Beautiful, user-centered designs that capture your brand identity and engage your audience across all platforms and devices.', 'wp-bootstrap' ); ?></p>
|
||||
<!-- /wp:paragraph --></div>
|
||||
<!-- /wp:column -->
|
||||
|
||||
<!-- wp:column -->
|
||||
<div class="wp-block-column"><!-- wp:heading {"textAlign":"center","level":3,"fontSize":"display"} -->
|
||||
<h3 class="wp-block-heading has-text-align-center has-display-font-size"><?php esc_html_e( "\xE2\x9A\x99\xEF\xB8\x8F", 'wp-bootstrap' ); ?></h3>
|
||||
<!-- /wp:heading -->
|
||||
|
||||
<!-- wp:heading {"textAlign":"center","level":3} -->
|
||||
<h3 class="wp-block-heading has-text-align-center"><?php esc_html_e( 'Development', 'wp-bootstrap' ); ?></h3>
|
||||
<!-- /wp:heading -->
|
||||
|
||||
<!-- wp:paragraph {"align":"center","textColor":"secondary"} -->
|
||||
<p class="has-text-align-center has-secondary-color has-text-color"><?php esc_html_e( 'Robust, scalable web applications built with modern technologies and best practices to ensure performance and reliability.', 'wp-bootstrap' ); ?></p>
|
||||
<!-- /wp:paragraph --></div>
|
||||
<!-- /wp:column -->
|
||||
|
||||
<!-- wp:column -->
|
||||
<div class="wp-block-column"><!-- wp:heading {"textAlign":"center","level":3,"fontSize":"display"} -->
|
||||
<h3 class="wp-block-heading has-text-align-center has-display-font-size"><?php esc_html_e( "\xF0\x9F\x93\x88", 'wp-bootstrap' ); ?></h3>
|
||||
<!-- /wp:heading -->
|
||||
|
||||
<!-- wp:heading {"textAlign":"center","level":3} -->
|
||||
<h3 class="wp-block-heading has-text-align-center"><?php esc_html_e( 'Strategy', 'wp-bootstrap' ); ?></h3>
|
||||
<!-- /wp:heading -->
|
||||
|
||||
<!-- wp:paragraph {"align":"center","textColor":"secondary"} -->
|
||||
<p class="has-text-align-center has-secondary-color has-text-color"><?php esc_html_e( 'Data-driven strategies and consulting to help you achieve your business goals and stay ahead of the competition.', 'wp-bootstrap' ); ?></p>
|
||||
<!-- /wp:paragraph --></div>
|
||||
<!-- /wp:column --></div>
|
||||
<!-- /wp:columns --></div>
|
||||
<!-- /wp:group -->
|
||||
|
||||
<!-- wp:group {"align":"full","style":{"spacing":{"padding":{"top":"var:preset|spacing|70","bottom":"var:preset|spacing|70"}}},"backgroundColor":"primary","textColor":"base","layout":{"type":"constrained"}} -->
|
||||
<div class="wp-block-group alignfull has-base-color has-primary-background-color has-text-color has-background" style="padding-top:var(--wp--preset--spacing--70);padding-bottom:var(--wp--preset--spacing--70)"><!-- wp:heading {"textAlign":"center","fontSize":"xx-large"} -->
|
||||
<h2 class="wp-block-heading has-text-align-center has-xx-large-font-size"><?php esc_html_e( 'Get Started', 'wp-bootstrap' ); ?></h2>
|
||||
<!-- /wp:heading -->
|
||||
|
||||
<!-- wp:paragraph {"align":"center","fontSize":"medium"} -->
|
||||
<p class="has-text-align-center has-medium-font-size"><?php esc_html_e( 'Ready to take your project to the next level? Let us help you build something great.', 'wp-bootstrap' ); ?></p>
|
||||
<!-- /wp:paragraph -->
|
||||
|
||||
<!-- wp:buttons {"layout":{"type":"flex","justifyContent":"center"}} -->
|
||||
<div class="wp-block-buttons"><!-- wp:button {"backgroundColor":"base","textColor":"primary"} -->
|
||||
<div class="wp-block-button"><a class="wp-block-button__link has-primary-color has-base-background-color has-text-color has-background wp-element-button"><?php esc_html_e( 'Contact Us', 'wp-bootstrap' ); ?></a></div>
|
||||
<!-- /wp:button -->
|
||||
|
||||
<!-- wp:button {"className":"is-style-outline","style":{"elements":{"link":{"color":{"text":"var:preset|color|base"}}}},"textColor":"base"} -->
|
||||
<div class="wp-block-button is-style-outline"><a class="wp-block-button__link has-base-color has-text-color has-link-color wp-element-button"><?php esc_html_e( 'View Portfolio', 'wp-bootstrap' ); ?></a></div>
|
||||
<!-- /wp:button --></div>
|
||||
<!-- /wp:buttons --></div>
|
||||
<!-- /wp:group -->
|
||||
@@ -61,6 +61,7 @@
|
||||
var newTheme = currentTheme === 'dark' ? 'light' : 'dark';
|
||||
localStorage.setItem(STORAGE_KEY, newTheme);
|
||||
setTheme(newTheme);
|
||||
announceTheme(newTheme);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -71,4 +72,23 @@
|
||||
setTheme(e.matches ? 'dark' : 'light');
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Announce theme change to screen readers via a live region.
|
||||
*
|
||||
* @param {string} theme - 'dark' or 'light'
|
||||
*/
|
||||
function announceTheme(theme) {
|
||||
var msg = theme === 'dark' ? 'Dark mode enabled' : 'Light mode enabled';
|
||||
var el = document.getElementById('wp-bootstrap-theme-status');
|
||||
if (!el) {
|
||||
el = document.createElement('div');
|
||||
el.id = 'wp-bootstrap-theme-status';
|
||||
el.setAttribute('role', 'status');
|
||||
el.setAttribute('aria-live', 'polite');
|
||||
el.className = 'visually-hidden';
|
||||
document.body.appendChild(el);
|
||||
}
|
||||
el.textContent = msg;
|
||||
}
|
||||
})();
|
||||
|
||||
@@ -25,6 +25,24 @@
|
||||
}
|
||||
}
|
||||
|
||||
// Transparent header variant
|
||||
.header-transparent {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
z-index: $zindex-fixed;
|
||||
|
||||
.navbar {
|
||||
background: transparent !important;
|
||||
}
|
||||
}
|
||||
|
||||
// Offcanvas navigation dark mode compatibility
|
||||
[data-bs-theme="dark"] {
|
||||
.offcanvas {
|
||||
--bs-offcanvas-bg: var(--bs-body-bg);
|
||||
}
|
||||
}
|
||||
|
||||
// Dark mode overrides for block styles with hardcoded colors
|
||||
[data-bs-theme="dark"] {
|
||||
.is-style-alert-info {
|
||||
@@ -57,3 +75,46 @@
|
||||
background: var(--bs-body-bg);
|
||||
}
|
||||
}
|
||||
|
||||
// Skip link (accessibility)
|
||||
.wp-bootstrap-skip-link {
|
||||
position: absolute;
|
||||
top: -100%;
|
||||
left: 0;
|
||||
z-index: $zindex-fixed + 10;
|
||||
padding: 0.5rem 1rem;
|
||||
background: var(--bs-primary);
|
||||
color: #fff;
|
||||
text-decoration: none;
|
||||
font-weight: 600;
|
||||
|
||||
&:focus {
|
||||
top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Post featured image
|
||||
.post-thumbnail {
|
||||
aspect-ratio: 16 / 9;
|
||||
object-fit: cover;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
// Card thumbnail
|
||||
.card-thumbnail {
|
||||
aspect-ratio: 3 / 2;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
// Sidebar heading
|
||||
.sidebar-heading {
|
||||
letter-spacing: 1.6px;
|
||||
}
|
||||
|
||||
// Hero overlay
|
||||
.hero-overlay {
|
||||
background-position: center;
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
29
src/scss/_editor-overrides.scss
Normal file
29
src/scss/_editor-overrides.scss
Normal file
@@ -0,0 +1,29 @@
|
||||
// Editor-specific overrides
|
||||
// Adjustments for the block editor iframe to match frontend appearance
|
||||
|
||||
.editor-styles-wrapper {
|
||||
font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
||||
line-height: 1.5;
|
||||
|
||||
a {
|
||||
text-decoration-thickness: 1px !important;
|
||||
text-underline-offset: 0.1em;
|
||||
}
|
||||
|
||||
// Alignment overrides matching Bootstrap container widths
|
||||
.alignfull {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.alignwide {
|
||||
max-width: 1140px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
// Block gap matching theme.json blockGap
|
||||
> * + * {
|
||||
margin-block-start: 1.5rem;
|
||||
}
|
||||
}
|
||||
@@ -1,23 +1,22 @@
|
||||
/*!
|
||||
* WP Bootstrap Theme - Editor Styles
|
||||
* Imports full Bootstrap so WYSIWYG matches the frontend.
|
||||
*/
|
||||
|
||||
// Import Bootstrap functions and variables for consistency
|
||||
// 1. Import Bootstrap functions first (needed for variable manipulation)
|
||||
@import "bootstrap/scss/functions";
|
||||
|
||||
// 2. Override Bootstrap variables BEFORE they're set
|
||||
@import "variables";
|
||||
@import "bootstrap/scss/variables";
|
||||
@import "bootstrap/scss/variables-dark";
|
||||
@import "bootstrap/scss/maps";
|
||||
@import "bootstrap/scss/mixins";
|
||||
@import "bootstrap/scss/root";
|
||||
|
||||
// Editor-specific adjustments
|
||||
.editor-styles-wrapper {
|
||||
font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
||||
line-height: 1.5;
|
||||
// 3. Import all of Bootstrap
|
||||
@import "bootstrap/scss/bootstrap";
|
||||
|
||||
a {
|
||||
text-decoration-thickness: 1px !important;
|
||||
text-underline-offset: 0.1em;
|
||||
}
|
||||
}
|
||||
// 4. WordPress block compatibility
|
||||
@import "wordpress";
|
||||
|
||||
// 5. Custom styles (dark mode overrides, block styles, etc.)
|
||||
@import "custom";
|
||||
|
||||
// 6. Editor-specific overrides
|
||||
@import "editor-overrides";
|
||||
|
||||
11
src/scss/rtl.scss
Normal file
11
src/scss/rtl.scss
Normal file
@@ -0,0 +1,11 @@
|
||||
/*!
|
||||
* WP Bootstrap Theme - RTL Overrides
|
||||
* Right-to-left language support
|
||||
*/
|
||||
|
||||
// Blockquote accent border (LTR uses border-left, RTL needs border-right)
|
||||
.is-style-blockquote-accent {
|
||||
border-left: none;
|
||||
border-right: 4px solid var(--wp--preset--color--primary);
|
||||
border-radius: 0.375rem 0 0 0.375rem;
|
||||
}
|
||||
@@ -7,7 +7,7 @@ Description: A modern WordPress Block Theme built from scratch with Bootstrap 5.
|
||||
Requires at least: 6.7
|
||||
Tested up to: 6.7
|
||||
Requires PHP: 8.3
|
||||
Version: 0.1.0
|
||||
Version: 0.3.1
|
||||
License: GNU General Public License v2 or later
|
||||
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
Text Domain: wp-bootstrap
|
||||
|
||||
86
styles/05-ember.json
Normal file
86
styles/05-ember.json
Normal file
@@ -0,0 +1,86 @@
|
||||
{
|
||||
"$schema": "https://schemas.wp.org/wp/6.7/theme.json",
|
||||
"version": 3,
|
||||
"title": "Ember",
|
||||
"settings": {
|
||||
"color": {
|
||||
"palette": [
|
||||
{
|
||||
"color": "#1c1210",
|
||||
"name": "Base",
|
||||
"slug": "base"
|
||||
},
|
||||
{
|
||||
"color": "#f0e6e0",
|
||||
"name": "Contrast",
|
||||
"slug": "contrast"
|
||||
},
|
||||
{
|
||||
"color": "#e85d26",
|
||||
"name": "Primary",
|
||||
"slug": "primary"
|
||||
},
|
||||
{
|
||||
"color": "#a8a09c",
|
||||
"name": "Secondary",
|
||||
"slug": "secondary"
|
||||
},
|
||||
{
|
||||
"color": "#4ade80",
|
||||
"name": "Success",
|
||||
"slug": "success"
|
||||
},
|
||||
{
|
||||
"color": "#f87171",
|
||||
"name": "Danger",
|
||||
"slug": "danger"
|
||||
},
|
||||
{
|
||||
"color": "#fbbf24",
|
||||
"name": "Warning",
|
||||
"slug": "warning"
|
||||
},
|
||||
{
|
||||
"color": "#fb923c",
|
||||
"name": "Info",
|
||||
"slug": "info"
|
||||
},
|
||||
{
|
||||
"color": "#2a1f1b",
|
||||
"name": "Light",
|
||||
"slug": "light"
|
||||
},
|
||||
{
|
||||
"color": "#3d2117",
|
||||
"name": "Dark",
|
||||
"slug": "dark"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"styles": {
|
||||
"elements": {
|
||||
"button": {
|
||||
"color": {
|
||||
"background": "var:preset|color|primary",
|
||||
"text": "var:preset|color|base"
|
||||
},
|
||||
":hover": {
|
||||
"color": {
|
||||
"background": "#c44b1b"
|
||||
}
|
||||
}
|
||||
},
|
||||
"link": {
|
||||
"color": {
|
||||
"text": "var:preset|color|primary"
|
||||
},
|
||||
":hover": {
|
||||
"color": {
|
||||
"text": "#c44b1b"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
86
styles/06-arctic.json
Normal file
86
styles/06-arctic.json
Normal file
@@ -0,0 +1,86 @@
|
||||
{
|
||||
"$schema": "https://schemas.wp.org/wp/6.7/theme.json",
|
||||
"version": 3,
|
||||
"title": "Arctic",
|
||||
"settings": {
|
||||
"color": {
|
||||
"palette": [
|
||||
{
|
||||
"color": "#0d1b2a",
|
||||
"name": "Base",
|
||||
"slug": "base"
|
||||
},
|
||||
{
|
||||
"color": "#e0e8f0",
|
||||
"name": "Contrast",
|
||||
"slug": "contrast"
|
||||
},
|
||||
{
|
||||
"color": "#38bdf8",
|
||||
"name": "Primary",
|
||||
"slug": "primary"
|
||||
},
|
||||
{
|
||||
"color": "#94a3b8",
|
||||
"name": "Secondary",
|
||||
"slug": "secondary"
|
||||
},
|
||||
{
|
||||
"color": "#34d399",
|
||||
"name": "Success",
|
||||
"slug": "success"
|
||||
},
|
||||
{
|
||||
"color": "#fb7185",
|
||||
"name": "Danger",
|
||||
"slug": "danger"
|
||||
},
|
||||
{
|
||||
"color": "#facc15",
|
||||
"name": "Warning",
|
||||
"slug": "warning"
|
||||
},
|
||||
{
|
||||
"color": "#22d3ee",
|
||||
"name": "Info",
|
||||
"slug": "info"
|
||||
},
|
||||
{
|
||||
"color": "#1b2838",
|
||||
"name": "Light",
|
||||
"slug": "light"
|
||||
},
|
||||
{
|
||||
"color": "#0f4c75",
|
||||
"name": "Dark",
|
||||
"slug": "dark"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"styles": {
|
||||
"elements": {
|
||||
"button": {
|
||||
"color": {
|
||||
"background": "var:preset|color|primary",
|
||||
"text": "var:preset|color|base"
|
||||
},
|
||||
":hover": {
|
||||
"color": {
|
||||
"background": "#0ea5e9"
|
||||
}
|
||||
}
|
||||
},
|
||||
"link": {
|
||||
"color": {
|
||||
"text": "var:preset|color|primary"
|
||||
},
|
||||
":hover": {
|
||||
"color": {
|
||||
"text": "#0ea5e9"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
86
styles/07-amethyst.json
Normal file
86
styles/07-amethyst.json
Normal file
@@ -0,0 +1,86 @@
|
||||
{
|
||||
"$schema": "https://schemas.wp.org/wp/6.7/theme.json",
|
||||
"version": 3,
|
||||
"title": "Amethyst",
|
||||
"settings": {
|
||||
"color": {
|
||||
"palette": [
|
||||
{
|
||||
"color": "#1a1028",
|
||||
"name": "Base",
|
||||
"slug": "base"
|
||||
},
|
||||
{
|
||||
"color": "#e8e0f0",
|
||||
"name": "Contrast",
|
||||
"slug": "contrast"
|
||||
},
|
||||
{
|
||||
"color": "#a78bfa",
|
||||
"name": "Primary",
|
||||
"slug": "primary"
|
||||
},
|
||||
{
|
||||
"color": "#9ca3af",
|
||||
"name": "Secondary",
|
||||
"slug": "secondary"
|
||||
},
|
||||
{
|
||||
"color": "#6ee7b7",
|
||||
"name": "Success",
|
||||
"slug": "success"
|
||||
},
|
||||
{
|
||||
"color": "#fca5a5",
|
||||
"name": "Danger",
|
||||
"slug": "danger"
|
||||
},
|
||||
{
|
||||
"color": "#fde68a",
|
||||
"name": "Warning",
|
||||
"slug": "warning"
|
||||
},
|
||||
{
|
||||
"color": "#c084fc",
|
||||
"name": "Info",
|
||||
"slug": "info"
|
||||
},
|
||||
{
|
||||
"color": "#221538",
|
||||
"name": "Light",
|
||||
"slug": "light"
|
||||
},
|
||||
{
|
||||
"color": "#3b1f6e",
|
||||
"name": "Dark",
|
||||
"slug": "dark"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"styles": {
|
||||
"elements": {
|
||||
"button": {
|
||||
"color": {
|
||||
"background": "var:preset|color|primary",
|
||||
"text": "var:preset|color|base"
|
||||
},
|
||||
":hover": {
|
||||
"color": {
|
||||
"background": "#8b5cf6"
|
||||
}
|
||||
}
|
||||
},
|
||||
"link": {
|
||||
"color": {
|
||||
"text": "var:preset|color|primary"
|
||||
},
|
||||
":hover": {
|
||||
"color": {
|
||||
"text": "#8b5cf6"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
79
styles/08-rose.json
Normal file
79
styles/08-rose.json
Normal file
@@ -0,0 +1,79 @@
|
||||
{
|
||||
"$schema": "https://schemas.wp.org/wp/6.7/theme.json",
|
||||
"version": 3,
|
||||
"title": "Rose",
|
||||
"settings": {
|
||||
"color": {
|
||||
"palette": [
|
||||
{
|
||||
"color": "#FFFBFC",
|
||||
"name": "Base",
|
||||
"slug": "base"
|
||||
},
|
||||
{
|
||||
"color": "#2e1a21",
|
||||
"name": "Contrast",
|
||||
"slug": "contrast"
|
||||
},
|
||||
{
|
||||
"color": "#be185d",
|
||||
"name": "Primary",
|
||||
"slug": "primary"
|
||||
},
|
||||
{
|
||||
"color": "#78716c",
|
||||
"name": "Secondary",
|
||||
"slug": "secondary"
|
||||
},
|
||||
{
|
||||
"color": "#16a34a",
|
||||
"name": "Success",
|
||||
"slug": "success"
|
||||
},
|
||||
{
|
||||
"color": "#dc2626",
|
||||
"name": "Danger",
|
||||
"slug": "danger"
|
||||
},
|
||||
{
|
||||
"color": "#eab308",
|
||||
"name": "Warning",
|
||||
"slug": "warning"
|
||||
},
|
||||
{
|
||||
"color": "#ec4899",
|
||||
"name": "Info",
|
||||
"slug": "info"
|
||||
},
|
||||
{
|
||||
"color": "#fdf2f8",
|
||||
"name": "Light",
|
||||
"slug": "light"
|
||||
},
|
||||
{
|
||||
"color": "#4a1030",
|
||||
"name": "Dark",
|
||||
"slug": "dark"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"styles": {
|
||||
"elements": {
|
||||
"button": {
|
||||
":hover": {
|
||||
"color": {
|
||||
"background": "#9d174d"
|
||||
}
|
||||
}
|
||||
},
|
||||
"link": {
|
||||
":hover": {
|
||||
"color": {
|
||||
"text": "#9d174d"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
79
styles/09-sand.json
Normal file
79
styles/09-sand.json
Normal file
@@ -0,0 +1,79 @@
|
||||
{
|
||||
"$schema": "https://schemas.wp.org/wp/6.7/theme.json",
|
||||
"version": 3,
|
||||
"title": "Sand",
|
||||
"settings": {
|
||||
"color": {
|
||||
"palette": [
|
||||
{
|
||||
"color": "#FEFCF8",
|
||||
"name": "Base",
|
||||
"slug": "base"
|
||||
},
|
||||
{
|
||||
"color": "#292017",
|
||||
"name": "Contrast",
|
||||
"slug": "contrast"
|
||||
},
|
||||
{
|
||||
"color": "#b45309",
|
||||
"name": "Primary",
|
||||
"slug": "primary"
|
||||
},
|
||||
{
|
||||
"color": "#78716c",
|
||||
"name": "Secondary",
|
||||
"slug": "secondary"
|
||||
},
|
||||
{
|
||||
"color": "#15803d",
|
||||
"name": "Success",
|
||||
"slug": "success"
|
||||
},
|
||||
{
|
||||
"color": "#b91c1c",
|
||||
"name": "Danger",
|
||||
"slug": "danger"
|
||||
},
|
||||
{
|
||||
"color": "#d97706",
|
||||
"name": "Warning",
|
||||
"slug": "warning"
|
||||
},
|
||||
{
|
||||
"color": "#d4956b",
|
||||
"name": "Info",
|
||||
"slug": "info"
|
||||
},
|
||||
{
|
||||
"color": "#f5f0e8",
|
||||
"name": "Light",
|
||||
"slug": "light"
|
||||
},
|
||||
{
|
||||
"color": "#3d2c14",
|
||||
"name": "Dark",
|
||||
"slug": "dark"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"styles": {
|
||||
"elements": {
|
||||
"button": {
|
||||
":hover": {
|
||||
"color": {
|
||||
"background": "#92400e"
|
||||
}
|
||||
}
|
||||
},
|
||||
"link": {
|
||||
":hover": {
|
||||
"color": {
|
||||
"text": "#92400e"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
79
styles/10-lavender.json
Normal file
79
styles/10-lavender.json
Normal file
@@ -0,0 +1,79 @@
|
||||
{
|
||||
"$schema": "https://schemas.wp.org/wp/6.7/theme.json",
|
||||
"version": 3,
|
||||
"title": "Lavender",
|
||||
"settings": {
|
||||
"color": {
|
||||
"palette": [
|
||||
{
|
||||
"color": "#FCFBFF",
|
||||
"name": "Base",
|
||||
"slug": "base"
|
||||
},
|
||||
{
|
||||
"color": "#1e1b2e",
|
||||
"name": "Contrast",
|
||||
"slug": "contrast"
|
||||
},
|
||||
{
|
||||
"color": "#7c3aed",
|
||||
"name": "Primary",
|
||||
"slug": "primary"
|
||||
},
|
||||
{
|
||||
"color": "#71717a",
|
||||
"name": "Secondary",
|
||||
"slug": "secondary"
|
||||
},
|
||||
{
|
||||
"color": "#059669",
|
||||
"name": "Success",
|
||||
"slug": "success"
|
||||
},
|
||||
{
|
||||
"color": "#dc2626",
|
||||
"name": "Danger",
|
||||
"slug": "danger"
|
||||
},
|
||||
{
|
||||
"color": "#eab308",
|
||||
"name": "Warning",
|
||||
"slug": "warning"
|
||||
},
|
||||
{
|
||||
"color": "#8b5cf6",
|
||||
"name": "Info",
|
||||
"slug": "info"
|
||||
},
|
||||
{
|
||||
"color": "#f3f0ff",
|
||||
"name": "Light",
|
||||
"slug": "light"
|
||||
},
|
||||
{
|
||||
"color": "#3b1f8e",
|
||||
"name": "Dark",
|
||||
"slug": "dark"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"styles": {
|
||||
"elements": {
|
||||
"button": {
|
||||
":hover": {
|
||||
"color": {
|
||||
"background": "#6d28d9"
|
||||
}
|
||||
}
|
||||
},
|
||||
"link": {
|
||||
":hover": {
|
||||
"color": {
|
||||
"text": "#6d28d9"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
79
styles/11-mint.json
Normal file
79
styles/11-mint.json
Normal file
@@ -0,0 +1,79 @@
|
||||
{
|
||||
"$schema": "https://schemas.wp.org/wp/6.7/theme.json",
|
||||
"version": 3,
|
||||
"title": "Mint",
|
||||
"settings": {
|
||||
"color": {
|
||||
"palette": [
|
||||
{
|
||||
"color": "#F8FFFE",
|
||||
"name": "Base",
|
||||
"slug": "base"
|
||||
},
|
||||
{
|
||||
"color": "#14291f",
|
||||
"name": "Contrast",
|
||||
"slug": "contrast"
|
||||
},
|
||||
{
|
||||
"color": "#0d9488",
|
||||
"name": "Primary",
|
||||
"slug": "primary"
|
||||
},
|
||||
{
|
||||
"color": "#6b7280",
|
||||
"name": "Secondary",
|
||||
"slug": "secondary"
|
||||
},
|
||||
{
|
||||
"color": "#16a34a",
|
||||
"name": "Success",
|
||||
"slug": "success"
|
||||
},
|
||||
{
|
||||
"color": "#dc2626",
|
||||
"name": "Danger",
|
||||
"slug": "danger"
|
||||
},
|
||||
{
|
||||
"color": "#ca8a04",
|
||||
"name": "Warning",
|
||||
"slug": "warning"
|
||||
},
|
||||
{
|
||||
"color": "#2dd4bf",
|
||||
"name": "Info",
|
||||
"slug": "info"
|
||||
},
|
||||
{
|
||||
"color": "#ecfdf5",
|
||||
"name": "Light",
|
||||
"slug": "light"
|
||||
},
|
||||
{
|
||||
"color": "#134e4a",
|
||||
"name": "Dark",
|
||||
"slug": "dark"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"styles": {
|
||||
"elements": {
|
||||
"button": {
|
||||
":hover": {
|
||||
"color": {
|
||||
"background": "#0f766e"
|
||||
}
|
||||
}
|
||||
},
|
||||
"link": {
|
||||
":hover": {
|
||||
"color": {
|
||||
"text": "#0f766e"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
86
styles/12-slate.json
Normal file
86
styles/12-slate.json
Normal file
@@ -0,0 +1,86 @@
|
||||
{
|
||||
"$schema": "https://schemas.wp.org/wp/6.7/theme.json",
|
||||
"version": 3,
|
||||
"title": "Slate",
|
||||
"settings": {
|
||||
"color": {
|
||||
"palette": [
|
||||
{
|
||||
"color": "#0f172a",
|
||||
"name": "Base",
|
||||
"slug": "base"
|
||||
},
|
||||
{
|
||||
"color": "#e2e8f0",
|
||||
"name": "Contrast",
|
||||
"slug": "contrast"
|
||||
},
|
||||
{
|
||||
"color": "#3b82f6",
|
||||
"name": "Primary",
|
||||
"slug": "primary"
|
||||
},
|
||||
{
|
||||
"color": "#94a3b8",
|
||||
"name": "Secondary",
|
||||
"slug": "secondary"
|
||||
},
|
||||
{
|
||||
"color": "#22c55e",
|
||||
"name": "Success",
|
||||
"slug": "success"
|
||||
},
|
||||
{
|
||||
"color": "#ef4444",
|
||||
"name": "Danger",
|
||||
"slug": "danger"
|
||||
},
|
||||
{
|
||||
"color": "#eab308",
|
||||
"name": "Warning",
|
||||
"slug": "warning"
|
||||
},
|
||||
{
|
||||
"color": "#06b6d4",
|
||||
"name": "Info",
|
||||
"slug": "info"
|
||||
},
|
||||
{
|
||||
"color": "#1e293b",
|
||||
"name": "Light",
|
||||
"slug": "light"
|
||||
},
|
||||
{
|
||||
"color": "#334155",
|
||||
"name": "Dark",
|
||||
"slug": "dark"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"styles": {
|
||||
"elements": {
|
||||
"button": {
|
||||
"color": {
|
||||
"background": "var:preset|color|primary",
|
||||
"text": "var:preset|color|base"
|
||||
},
|
||||
":hover": {
|
||||
"color": {
|
||||
"background": "#2563eb"
|
||||
}
|
||||
}
|
||||
},
|
||||
"link": {
|
||||
"color": {
|
||||
"text": "var:preset|color|primary"
|
||||
},
|
||||
":hover": {
|
||||
"color": {
|
||||
"text": "#2563eb"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
86
styles/13-mocha.json
Normal file
86
styles/13-mocha.json
Normal file
@@ -0,0 +1,86 @@
|
||||
{
|
||||
"$schema": "https://schemas.wp.org/wp/6.7/theme.json",
|
||||
"version": 3,
|
||||
"title": "Mocha",
|
||||
"settings": {
|
||||
"color": {
|
||||
"palette": [
|
||||
{
|
||||
"color": "#1c1412",
|
||||
"name": "Base",
|
||||
"slug": "base"
|
||||
},
|
||||
{
|
||||
"color": "#e7ddd4",
|
||||
"name": "Contrast",
|
||||
"slug": "contrast"
|
||||
},
|
||||
{
|
||||
"color": "#c49a6c",
|
||||
"name": "Primary",
|
||||
"slug": "primary"
|
||||
},
|
||||
{
|
||||
"color": "#a8998a",
|
||||
"name": "Secondary",
|
||||
"slug": "secondary"
|
||||
},
|
||||
{
|
||||
"color": "#6ec98f",
|
||||
"name": "Success",
|
||||
"slug": "success"
|
||||
},
|
||||
{
|
||||
"color": "#e87e7e",
|
||||
"name": "Danger",
|
||||
"slug": "danger"
|
||||
},
|
||||
{
|
||||
"color": "#e5c07b",
|
||||
"name": "Warning",
|
||||
"slug": "warning"
|
||||
},
|
||||
{
|
||||
"color": "#d19a66",
|
||||
"name": "Info",
|
||||
"slug": "info"
|
||||
},
|
||||
{
|
||||
"color": "#2a201a",
|
||||
"name": "Light",
|
||||
"slug": "light"
|
||||
},
|
||||
{
|
||||
"color": "#45342a",
|
||||
"name": "Dark",
|
||||
"slug": "dark"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"styles": {
|
||||
"elements": {
|
||||
"button": {
|
||||
"color": {
|
||||
"background": "var:preset|color|primary",
|
||||
"text": "var:preset|color|base"
|
||||
},
|
||||
":hover": {
|
||||
"color": {
|
||||
"background": "#a8804f"
|
||||
}
|
||||
}
|
||||
},
|
||||
"link": {
|
||||
"color": {
|
||||
"text": "var:preset|color|primary"
|
||||
},
|
||||
":hover": {
|
||||
"color": {
|
||||
"text": "#a8804f"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
86
styles/14-nebula.json
Normal file
86
styles/14-nebula.json
Normal file
@@ -0,0 +1,86 @@
|
||||
{
|
||||
"$schema": "https://schemas.wp.org/wp/6.7/theme.json",
|
||||
"version": 3,
|
||||
"title": "Nebula",
|
||||
"settings": {
|
||||
"color": {
|
||||
"palette": [
|
||||
{
|
||||
"color": "#0a1628",
|
||||
"name": "Base",
|
||||
"slug": "base"
|
||||
},
|
||||
{
|
||||
"color": "#d4e4f0",
|
||||
"name": "Contrast",
|
||||
"slug": "contrast"
|
||||
},
|
||||
{
|
||||
"color": "#2dd4bf",
|
||||
"name": "Primary",
|
||||
"slug": "primary"
|
||||
},
|
||||
{
|
||||
"color": "#7e9bb0",
|
||||
"name": "Secondary",
|
||||
"slug": "secondary"
|
||||
},
|
||||
{
|
||||
"color": "#4ade80",
|
||||
"name": "Success",
|
||||
"slug": "success"
|
||||
},
|
||||
{
|
||||
"color": "#f472b6",
|
||||
"name": "Danger",
|
||||
"slug": "danger"
|
||||
},
|
||||
{
|
||||
"color": "#fbbf24",
|
||||
"name": "Warning",
|
||||
"slug": "warning"
|
||||
},
|
||||
{
|
||||
"color": "#67e8f9",
|
||||
"name": "Info",
|
||||
"slug": "info"
|
||||
},
|
||||
{
|
||||
"color": "#112240",
|
||||
"name": "Light",
|
||||
"slug": "light"
|
||||
},
|
||||
{
|
||||
"color": "#1a365d",
|
||||
"name": "Dark",
|
||||
"slug": "dark"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"styles": {
|
||||
"elements": {
|
||||
"button": {
|
||||
"color": {
|
||||
"background": "var:preset|color|primary",
|
||||
"text": "var:preset|color|base"
|
||||
},
|
||||
":hover": {
|
||||
"color": {
|
||||
"background": "#14b8a6"
|
||||
}
|
||||
}
|
||||
},
|
||||
"link": {
|
||||
"color": {
|
||||
"text": "var:preset|color|primary"
|
||||
},
|
||||
":hover": {
|
||||
"color": {
|
||||
"text": "#14b8a6"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
86
styles/15-obsidian.json
Normal file
86
styles/15-obsidian.json
Normal file
@@ -0,0 +1,86 @@
|
||||
{
|
||||
"$schema": "https://schemas.wp.org/wp/6.7/theme.json",
|
||||
"version": 3,
|
||||
"title": "Obsidian",
|
||||
"settings": {
|
||||
"color": {
|
||||
"palette": [
|
||||
{
|
||||
"color": "#121212",
|
||||
"name": "Base",
|
||||
"slug": "base"
|
||||
},
|
||||
{
|
||||
"color": "#e0e0e0",
|
||||
"name": "Contrast",
|
||||
"slug": "contrast"
|
||||
},
|
||||
{
|
||||
"color": "#ef4444",
|
||||
"name": "Primary",
|
||||
"slug": "primary"
|
||||
},
|
||||
{
|
||||
"color": "#a3a3a3",
|
||||
"name": "Secondary",
|
||||
"slug": "secondary"
|
||||
},
|
||||
{
|
||||
"color": "#4ade80",
|
||||
"name": "Success",
|
||||
"slug": "success"
|
||||
},
|
||||
{
|
||||
"color": "#fb7185",
|
||||
"name": "Danger",
|
||||
"slug": "danger"
|
||||
},
|
||||
{
|
||||
"color": "#fbbf24",
|
||||
"name": "Warning",
|
||||
"slug": "warning"
|
||||
},
|
||||
{
|
||||
"color": "#f97316",
|
||||
"name": "Info",
|
||||
"slug": "info"
|
||||
},
|
||||
{
|
||||
"color": "#1a1a1a",
|
||||
"name": "Light",
|
||||
"slug": "light"
|
||||
},
|
||||
{
|
||||
"color": "#2a2a2a",
|
||||
"name": "Dark",
|
||||
"slug": "dark"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"styles": {
|
||||
"elements": {
|
||||
"button": {
|
||||
"color": {
|
||||
"background": "var:preset|color|primary",
|
||||
"text": "var:preset|color|base"
|
||||
},
|
||||
":hover": {
|
||||
"color": {
|
||||
"background": "#dc2626"
|
||||
}
|
||||
}
|
||||
},
|
||||
"link": {
|
||||
"color": {
|
||||
"text": "var:preset|color|primary"
|
||||
},
|
||||
":hover": {
|
||||
"color": {
|
||||
"text": "#dc2626"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
9
templates/page-full-width.html
Normal file
9
templates/page-full-width.html
Normal file
@@ -0,0 +1,9 @@
|
||||
<!-- wp:template-part {"slug":"header"} /-->
|
||||
|
||||
<!-- wp:group {"tagName":"main","layout":{"type":"default"}} -->
|
||||
<main class="wp-block-group">
|
||||
<!-- wp:post-content {"align":"full","layout":{"type":"default"}} /-->
|
||||
</main>
|
||||
<!-- /wp:group -->
|
||||
|
||||
<!-- wp:template-part {"slug":"footer"} /-->
|
||||
14
templates/page-hero.html
Normal file
14
templates/page-hero.html
Normal file
@@ -0,0 +1,14 @@
|
||||
<!-- wp:template-part {"slug":"header"} /-->
|
||||
|
||||
<!-- wp:group {"tagName":"main","layout":{"type":"default"}} -->
|
||||
<main class="wp-block-group">
|
||||
<!-- wp:pattern {"slug":"wp-bootstrap/hero-cover"} /-->
|
||||
<!-- wp:group {"layout":{"type":"constrained"}} -->
|
||||
<div class="wp-block-group">
|
||||
<!-- wp:post-content {"layout":{"type":"constrained"}} /-->
|
||||
</div>
|
||||
<!-- /wp:group -->
|
||||
</main>
|
||||
<!-- /wp:group -->
|
||||
|
||||
<!-- wp:template-part {"slug":"footer"} /-->
|
||||
5
templates/page-landing.html
Normal file
5
templates/page-landing.html
Normal file
@@ -0,0 +1,5 @@
|
||||
<!-- wp:group {"tagName":"main","layout":{"type":"default"}} -->
|
||||
<main class="wp-block-group">
|
||||
<!-- wp:post-content {"align":"full","layout":{"type":"default"}} /-->
|
||||
</main>
|
||||
<!-- /wp:group -->
|
||||
25
templates/page-sidebar.html
Normal file
25
templates/page-sidebar.html
Normal file
@@ -0,0 +1,25 @@
|
||||
<!-- wp:template-part {"slug":"header"} /-->
|
||||
|
||||
<!-- wp:group {"tagName":"main","style":{"spacing":{"margin":{"top":"var:preset|spacing|60"}}},"layout":{"type":"constrained"}} -->
|
||||
<main class="wp-block-group" style="margin-top:var(--wp--preset--spacing--60)">
|
||||
<!-- wp:columns {"align":"wide","style":{"spacing":{"blockGap":{"left":"var:preset|spacing|60"}}}} -->
|
||||
<div class="wp-block-columns alignwide">
|
||||
<!-- wp:column {"width":"66.66%"} -->
|
||||
<div class="wp-block-column" style="flex-basis:66.66%">
|
||||
<!-- wp:post-featured-image {"style":{"spacing":{"margin":{"bottom":"var:preset|spacing|60"}}}} /-->
|
||||
<!-- wp:post-title {"level":1} /-->
|
||||
<!-- wp:post-content {"align":"full","layout":{"type":"constrained"}} /-->
|
||||
</div>
|
||||
<!-- /wp:column -->
|
||||
|
||||
<!-- wp:column {"width":"33.33%"} -->
|
||||
<div class="wp-block-column" style="flex-basis:33.33%">
|
||||
<!-- wp:template-part {"slug":"sidebar"} /-->
|
||||
</div>
|
||||
<!-- /wp:column -->
|
||||
</div>
|
||||
<!-- /wp:columns -->
|
||||
</main>
|
||||
<!-- /wp:group -->
|
||||
|
||||
<!-- wp:template-part {"slug":"footer"} /-->
|
||||
93
theme.json
93
theme.json
@@ -215,6 +215,59 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"shadow": {
|
||||
"defaultPresets": false,
|
||||
"presets": [
|
||||
{
|
||||
"name": "Small",
|
||||
"slug": "sm",
|
||||
"shadow": "0 0.125rem 0.25rem rgba(0, 0, 0, 0.075)"
|
||||
},
|
||||
{
|
||||
"name": "Regular",
|
||||
"slug": "md",
|
||||
"shadow": "0 0.5rem 1rem rgba(0, 0, 0, 0.15)"
|
||||
},
|
||||
{
|
||||
"name": "Large",
|
||||
"slug": "lg",
|
||||
"shadow": "0 1rem 3rem rgba(0, 0, 0, 0.175)"
|
||||
}
|
||||
]
|
||||
},
|
||||
"dimensions": {
|
||||
"aspectRatios": [
|
||||
{
|
||||
"name": "16:9",
|
||||
"slug": "16-9",
|
||||
"ratio": "16/9"
|
||||
},
|
||||
{
|
||||
"name": "4:3",
|
||||
"slug": "4-3",
|
||||
"ratio": "4/3"
|
||||
},
|
||||
{
|
||||
"name": "1:1",
|
||||
"slug": "1-1",
|
||||
"ratio": "1/1"
|
||||
},
|
||||
{
|
||||
"name": "3:4",
|
||||
"slug": "3-4",
|
||||
"ratio": "3/4"
|
||||
}
|
||||
]
|
||||
},
|
||||
"custom": {
|
||||
"layout": {
|
||||
"contentSize": "720px",
|
||||
"wideSize": "1140px"
|
||||
},
|
||||
"spacing": {
|
||||
"baseline": "1.5rem"
|
||||
}
|
||||
},
|
||||
"useRootPaddingAwareAlignments": true
|
||||
},
|
||||
"styles": {
|
||||
@@ -450,6 +503,26 @@
|
||||
"name": "home-sidebar",
|
||||
"postTypes": ["page"],
|
||||
"title": "Blog with Sidebar"
|
||||
},
|
||||
{
|
||||
"name": "page-landing",
|
||||
"postTypes": ["page"],
|
||||
"title": "Landing Page (No Header/Footer)"
|
||||
},
|
||||
{
|
||||
"name": "page-full-width",
|
||||
"postTypes": ["page"],
|
||||
"title": "Full Width"
|
||||
},
|
||||
{
|
||||
"name": "page-hero",
|
||||
"postTypes": ["page"],
|
||||
"title": "Page with Hero"
|
||||
},
|
||||
{
|
||||
"name": "page-sidebar",
|
||||
"postTypes": ["page", "post"],
|
||||
"title": "Page with Sidebar"
|
||||
}
|
||||
],
|
||||
"templateParts": [
|
||||
@@ -458,11 +531,31 @@
|
||||
"name": "header",
|
||||
"title": "Header"
|
||||
},
|
||||
{
|
||||
"area": "header",
|
||||
"name": "header-centered",
|
||||
"title": "Header - Centered"
|
||||
},
|
||||
{
|
||||
"area": "header",
|
||||
"name": "header-transparent",
|
||||
"title": "Header - Transparent"
|
||||
},
|
||||
{
|
||||
"area": "footer",
|
||||
"name": "footer",
|
||||
"title": "Footer"
|
||||
},
|
||||
{
|
||||
"area": "footer",
|
||||
"name": "footer-minimal",
|
||||
"title": "Footer - Minimal"
|
||||
},
|
||||
{
|
||||
"area": "footer",
|
||||
"name": "footer-columns",
|
||||
"title": "Footer - Multi-Column"
|
||||
},
|
||||
{
|
||||
"area": "uncategorized",
|
||||
"name": "sidebar",
|
||||
|
||||
27
views/base.html.twig
Normal file
27
views/base.html.twig
Normal file
@@ -0,0 +1,27 @@
|
||||
<!doctype html>
|
||||
<html {{ language_attributes() }}>
|
||||
<head>
|
||||
<meta charset="{{ charset }}">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
{{ wp_head() }}
|
||||
</head>
|
||||
<body {{ body_class() }}>
|
||||
{{ wp_body_open() }}
|
||||
|
||||
<a class="wp-bootstrap-skip-link" href="#main-content">{{ __('Skip to main content') }}</a>
|
||||
|
||||
{% block header %}
|
||||
{% include 'partials/header.html.twig' %}
|
||||
{% endblock %}
|
||||
|
||||
<main id="main-content" class="{% block main_class %}py-4{% endblock %}">
|
||||
{% block content %}{% endblock %}
|
||||
</main>
|
||||
|
||||
{% block footer %}
|
||||
{% include 'partials/footer.html.twig' %}
|
||||
{% endblock %}
|
||||
|
||||
{{ wp_footer() }}
|
||||
</body>
|
||||
</html>
|
||||
17
views/components/card-post-grid.html.twig
Normal file
17
views/components/card-post-grid.html.twig
Normal file
@@ -0,0 +1,17 @@
|
||||
<article class="card h-100">
|
||||
{% if post.thumbnail %}
|
||||
<a href="{{ post.url }}">
|
||||
<img src="{{ post.thumbnail }}" class="card-img-top card-thumbnail"
|
||||
alt="{{ post.title|e('html_attr') }}"
|
||||
loading="lazy">
|
||||
</a>
|
||||
{% endif %}
|
||||
<div class="card-body">
|
||||
<h3 class="card-title h6">
|
||||
<a href="{{ post.url }}" class="text-decoration-none text-body">{{ post.title }}</a>
|
||||
</h3>
|
||||
<p class="card-text text-body-secondary small">
|
||||
<time datetime="{{ post.date_iso }}">{{ post.date }}</time>
|
||||
</p>
|
||||
</div>
|
||||
</article>
|
||||
21
views/components/card-post.html.twig
Normal file
21
views/components/card-post.html.twig
Normal file
@@ -0,0 +1,21 @@
|
||||
<article class="card mb-4 border-0 border-bottom rounded-0 pb-4">
|
||||
{% if post.thumbnail %}
|
||||
<a href="{{ post.url }}">
|
||||
<img src="{{ post.thumbnail }}" class="card-img-top rounded" alt="{{ post.title|e('html_attr') }}" loading="lazy">
|
||||
</a>
|
||||
{% endif %}
|
||||
<div class="card-body px-0">
|
||||
<h2 class="card-title h4">
|
||||
<a href="{{ post.url }}" class="text-decoration-none text-body">{{ post.title }}</a>
|
||||
</h2>
|
||||
<div class="text-body-secondary small mb-2">
|
||||
<time datetime="{{ post.date_iso }}">{{ post.date }}</time>
|
||||
<span class="mx-1">·</span>
|
||||
<a href="{{ post.author.url }}" class="text-body-secondary text-decoration-none">{{ post.author.name }}</a>
|
||||
</div>
|
||||
<p class="card-text">{{ post.excerpt|raw }}</p>
|
||||
<a href="{{ post.url }}" class="btn btn-outline-primary btn-sm">
|
||||
{{ post.read_more }}
|
||||
</a>
|
||||
</div>
|
||||
</article>
|
||||
11
views/components/post-loop.html.twig
Normal file
11
views/components/post-loop.html.twig
Normal file
@@ -0,0 +1,11 @@
|
||||
{% if posts|length > 0 %}
|
||||
{% for post in posts %}
|
||||
{% include 'components/card-post.html.twig' with {'post': post} only %}
|
||||
{% endfor %}
|
||||
|
||||
{% include 'partials/pagination.html.twig' %}
|
||||
{% else %}
|
||||
<div class="alert alert-secondary" role="alert">
|
||||
{{ __('No posts were found.') }}
|
||||
</div>
|
||||
{% endif %}
|
||||
16
views/pages/404.html.twig
Normal file
16
views/pages/404.html.twig
Normal file
@@ -0,0 +1,16 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container text-center py-5">
|
||||
<h1 class="display-1 fw-bold text-body-secondary">404</h1>
|
||||
<h2 class="mb-3">{{ __('Page not found') }}</h2>
|
||||
<p class="lead text-body-secondary mb-4">
|
||||
{{ __('The page you are looking for does not exist, or it has been moved. Please try searching using the form below.') }}
|
||||
</p>
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6">
|
||||
{% include 'partials/search-form.html.twig' %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
12
views/pages/archive.html.twig
Normal file
12
views/pages/archive.html.twig
Normal file
@@ -0,0 +1,12 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container">
|
||||
<h1 class="mb-2">{{ archive.title|raw }}</h1>
|
||||
{% if archive.description %}
|
||||
<div class="lead text-body-secondary mb-4">{{ archive.description|raw }}</div>
|
||||
{% endif %}
|
||||
|
||||
{% include 'components/post-loop.html.twig' %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
18
views/pages/full-width.html.twig
Normal file
18
views/pages/full-width.html.twig
Normal file
@@ -0,0 +1,18 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container-fluid px-0">
|
||||
<article>
|
||||
{% if post.thumbnail %}
|
||||
<img src="{{ post.thumbnail }}" class="w-100 mb-4" alt="{{ post.title|e('html_attr') }}">
|
||||
{% endif %}
|
||||
<div class="container">
|
||||
<h1 class="mb-4">{{ post.title }}</h1>
|
||||
|
||||
<div class="post-content">
|
||||
{{ post.content|raw }}
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
{% endblock %}
|
||||
21
views/pages/hero.html.twig
Normal file
21
views/pages/hero.html.twig
Normal file
@@ -0,0 +1,21 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block main_class %}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<section class="bg-primary text-white py-5 mb-5{% if post.thumbnail %} position-relative overflow-hidden{% endif %}">
|
||||
{% if post.thumbnail %}
|
||||
<div class="hero-overlay position-absolute top-0 start-0 w-100 h-100" style="background-image: url('{{ post.thumbnail|e('html_attr') }}');"></div>
|
||||
{% endif %}
|
||||
<div class="container position-relative py-5 text-center">
|
||||
<h1 class="display-4 fw-bold">{{ post.title }}</h1>
|
||||
</div>
|
||||
</section>
|
||||
<div class="container">
|
||||
<article>
|
||||
<div class="post-content">
|
||||
{{ post.content|raw }}
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
{% endblock %}
|
||||
20
views/pages/index.html.twig
Normal file
20
views/pages/index.html.twig
Normal file
@@ -0,0 +1,20 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container">
|
||||
<h1 class="mb-4">{{ __('Blog') }}</h1>
|
||||
|
||||
{% if layout == 'sidebar' %}
|
||||
<div class="row">
|
||||
<div class="col-lg-8">
|
||||
{% include 'components/post-loop.html.twig' %}
|
||||
</div>
|
||||
<div class="col-lg-4">
|
||||
{% include 'partials/sidebar.html.twig' %}
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
{% include 'components/post-loop.html.twig' %}
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
18
views/pages/landing.html.twig
Normal file
18
views/pages/landing.html.twig
Normal file
@@ -0,0 +1,18 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block header %}{% endblock %}
|
||||
{% block footer %}{% endblock %}
|
||||
|
||||
{% block main_class %}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container py-5">
|
||||
<article>
|
||||
<h1>{{ post.title }}</h1>
|
||||
|
||||
<div class="post-content">
|
||||
{{ post.content|raw }}
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
{% endblock %}
|
||||
24
views/pages/page-sidebar.html.twig
Normal file
24
views/pages/page-sidebar.html.twig
Normal file
@@ -0,0 +1,24 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-lg-8">
|
||||
<article>
|
||||
<h1 class="mb-4">{{ post.title }}</h1>
|
||||
{% if post.thumbnail %}
|
||||
<img src="{{ post.thumbnail }}" class="img-fluid rounded mb-4"
|
||||
alt="{{ post.title|e('html_attr') }}">
|
||||
{% endif %}
|
||||
|
||||
<div class="post-content">
|
||||
{{ post.content|raw }}
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
<div class="col-lg-4">
|
||||
{% include 'partials/sidebar.html.twig' %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
20
views/pages/page.html.twig
Normal file
20
views/pages/page.html.twig
Normal file
@@ -0,0 +1,20 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container">
|
||||
<article class="py-4">
|
||||
{% if post.thumbnail %}
|
||||
<figure class="mb-4">
|
||||
<img src="{{ post.thumbnail }}" class="img-fluid rounded"
|
||||
alt="{{ post.title|e('html_attr') }}">
|
||||
</figure>
|
||||
{% endif %}
|
||||
|
||||
<h1>{{ post.title }}</h1>
|
||||
|
||||
<div class="post-content">
|
||||
{{ post.content|raw }}
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
{% endblock %}
|
||||
15
views/pages/search.html.twig
Normal file
15
views/pages/search.html.twig
Normal file
@@ -0,0 +1,15 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container">
|
||||
<h1 class="mb-4">
|
||||
{{ __('Search results for: %s')|format('<em>' ~ search_query|e('html') ~ '</em>')|raw }}
|
||||
</h1>
|
||||
|
||||
{% include 'partials/search-form.html.twig' %}
|
||||
|
||||
<div class="mt-4">
|
||||
{% include 'components/post-loop.html.twig' %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
50
views/pages/single.html.twig
Normal file
50
views/pages/single.html.twig
Normal file
@@ -0,0 +1,50 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container">
|
||||
<article class="py-4">
|
||||
<header class="mb-4">
|
||||
<h1>{{ post.title }}</h1>
|
||||
{% include 'partials/meta.html.twig' %}
|
||||
</header>
|
||||
|
||||
{% if post.thumbnail %}
|
||||
<figure class="mb-4">
|
||||
<img src="{{ post.thumbnail }}" class="img-fluid rounded post-thumbnail"
|
||||
alt="{{ post.title|e('html_attr') }}"
|
||||
loading="lazy">
|
||||
</figure>
|
||||
{% endif %}
|
||||
|
||||
<div class="post-content">
|
||||
{{ post.content|raw }}
|
||||
</div>
|
||||
|
||||
{% if post.tags|length > 0 %}
|
||||
<div class="mt-4 mb-4">
|
||||
{% for tag in post.tags %}
|
||||
<a href="{{ tag.url }}" class="badge bg-secondary text-decoration-none me-1">
|
||||
{{ tag.name }}
|
||||
</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% include 'partials/post-navigation.html.twig' %}
|
||||
{% include 'partials/comments.html.twig' %}
|
||||
</article>
|
||||
|
||||
{% if more_posts is defined and more_posts|length > 0 %}
|
||||
<section class="py-5 border-top">
|
||||
<h2 class="h4 mb-4">{{ __('More posts') }}</h2>
|
||||
<div class="row row-cols-1 row-cols-md-3 g-4">
|
||||
{% for post in more_posts %}
|
||||
<div class="col">
|
||||
{% include 'components/card-post-grid.html.twig' with {'post': post} only %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</section>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
39
views/partials/comment-item.html.twig
Normal file
39
views/partials/comment-item.html.twig
Normal file
@@ -0,0 +1,39 @@
|
||||
<div class="comment d-flex gap-3 mb-4{% if depth > 0 %} ms-5{% endif %}" id="comment-{{ comment.id }}">
|
||||
<div class="flex-shrink-0">
|
||||
<img src="{{ comment.avatar_url }}" alt="{{ comment.author }}"
|
||||
class="rounded-circle" width="40" height="40" loading="lazy">
|
||||
</div>
|
||||
<div class="flex-grow-1">
|
||||
<div class="d-flex align-items-center gap-2 mb-1">
|
||||
<strong class="small">
|
||||
{% if comment.author_url %}
|
||||
<a href="{{ esc_url(comment.author_url) }}" class="text-decoration-none text-body" rel="nofollow">
|
||||
{{ comment.author }}
|
||||
</a>
|
||||
{% else %}
|
||||
{{ comment.author }}
|
||||
{% endif %}
|
||||
</strong>
|
||||
<time class="text-body-secondary small" datetime="{{ comment.date_iso }}">
|
||||
{{ comment.date }}
|
||||
</time>
|
||||
{% if comment.edit_url %}
|
||||
<a href="{{ comment.edit_url }}" class="text-body-secondary small">{{ __('Edit') }}</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="comment-content small">
|
||||
{{ comment.content|raw }}
|
||||
</div>
|
||||
{% if comment.reply_url %}
|
||||
<div class="mt-1">
|
||||
{{ comment.reply_url|raw }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if comment.children|length > 0 %}
|
||||
{% for child in comment.children %}
|
||||
{% include 'partials/comment-item.html.twig' with {'comment': child, 'depth': depth + 1} only %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
19
views/partials/comments.html.twig
Normal file
19
views/partials/comments.html.twig
Normal file
@@ -0,0 +1,19 @@
|
||||
{% if comments is defined and (comments.is_open or comments.count > 0) %}
|
||||
<section class="comments-section border-top pt-5 mt-5" id="comments">
|
||||
<h2 class="h4 mb-4">{{ comments.title }}</h2>
|
||||
|
||||
{% if comments.list|length > 0 %}
|
||||
<div class="comment-list mb-4">
|
||||
{% for comment in comments.list %}
|
||||
{% include 'partials/comment-item.html.twig' with {'comment': comment, 'depth': 0} only %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if comments.is_open %}
|
||||
<div class="comment-form mt-4">
|
||||
{{ comments.form|raw }}
|
||||
</div>
|
||||
{% endif %}
|
||||
</section>
|
||||
{% endif %}
|
||||
21
views/partials/dark-mode-toggle.html.twig
Normal file
21
views/partials/dark-mode-toggle.html.twig
Normal file
@@ -0,0 +1,21 @@
|
||||
<button type="button" class="wp-bootstrap-dark-mode-toggle ms-2"
|
||||
data-bs-theme-toggle
|
||||
aria-label="{{ __('Switch to dark mode') }}"
|
||||
data-label-dark="{{ __('Switch to dark mode') }}"
|
||||
data-label-light="{{ __('Switch to light mode') }}"
|
||||
aria-pressed="false">
|
||||
<svg class="wp-bootstrap-sun-icon" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="display:none;" aria-hidden="true">
|
||||
<circle cx="12" cy="12" r="5"/>
|
||||
<line x1="12" y1="1" x2="12" y2="3"/>
|
||||
<line x1="12" y1="21" x2="12" y2="23"/>
|
||||
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64"/>
|
||||
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78"/>
|
||||
<line x1="1" y1="12" x2="3" y2="12"/>
|
||||
<line x1="21" y1="12" x2="23" y2="12"/>
|
||||
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36"/>
|
||||
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22"/>
|
||||
</svg>
|
||||
<svg class="wp-bootstrap-moon-icon" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
||||
<path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/>
|
||||
</svg>
|
||||
</button>
|
||||
44
views/partials/footer-columns.html.twig
Normal file
44
views/partials/footer-columns.html.twig
Normal file
@@ -0,0 +1,44 @@
|
||||
<footer class="bg-dark text-light mt-auto">
|
||||
<div class="container py-5">
|
||||
<div class="row">
|
||||
<div class="col-lg-4 mb-4 mb-lg-0">
|
||||
<h5 class="fw-bold">{{ site.name }}</h5>
|
||||
<p class="text-body-secondary">{{ site.description }}</p>
|
||||
<p class="text-body-secondary small">{{ __('A modern WordPress theme built with Bootstrap 5.') }}</p>
|
||||
</div>
|
||||
<div class="col-lg-4 mb-4 mb-lg-0">
|
||||
<h5 class="fw-bold">{{ __('Navigation') }}</h5>
|
||||
{% if footer_menu|length > 0 %}
|
||||
<nav aria-label="{{ __('Footer navigation') }}">
|
||||
<ul class="list-unstyled">
|
||||
{% for item in footer_menu %}
|
||||
<li class="mb-1">
|
||||
<a href="{{ item.url }}" class="text-body-secondary text-decoration-none">
|
||||
{{ item.title }}
|
||||
</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</nav>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="col-lg-4">
|
||||
<h5 class="fw-bold">{{ __('About') }}</h5>
|
||||
<p class="text-body-secondary small">
|
||||
{{ __('This theme is proudly built with Bootstrap 5 and WordPress Full Site Editing.') }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<hr class="my-4">
|
||||
<div class="row align-items-center">
|
||||
<div class="col-md-6">
|
||||
<p class="text-body-secondary small mb-0">© {{ current_year }} {{ site.name }}</p>
|
||||
</div>
|
||||
<div class="col-md-6 text-md-end">
|
||||
<p class="text-body-secondary small mb-0">
|
||||
{{ __('Powered by %s')|format('<a href="https://wordpress.org" rel="nofollow" class="text-body-secondary">WordPress</a>')|raw }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
8
views/partials/footer-minimal.html.twig
Normal file
8
views/partials/footer-minimal.html.twig
Normal file
@@ -0,0 +1,8 @@
|
||||
<footer class="bg-body-tertiary mt-auto">
|
||||
<div class="container py-4">
|
||||
<hr class="mb-4">
|
||||
<p class="text-body-secondary text-center small mb-0">
|
||||
© {{ current_year }} {{ site.name }}. {{ __('All rights reserved.') }}
|
||||
</p>
|
||||
</div>
|
||||
</footer>
|
||||
36
views/partials/footer.html.twig
Normal file
36
views/partials/footer.html.twig
Normal file
@@ -0,0 +1,36 @@
|
||||
<footer class="bg-body-tertiary mt-auto">
|
||||
<div class="container py-5">
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<h5 class="fw-bold">{{ site.name }}</h5>
|
||||
<p class="text-body-secondary">{{ site.description }}</p>
|
||||
</div>
|
||||
<div class="col-md-6 text-md-end">
|
||||
{% if footer_menu|length > 0 %}
|
||||
<nav aria-label="{{ __('Footer navigation') }}">
|
||||
<ul class="list-unstyled">
|
||||
{% for item in footer_menu %}
|
||||
<li>
|
||||
<a href="{{ item.url }}" class="text-body-secondary text-decoration-none">
|
||||
{{ item.title }}
|
||||
</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</nav>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="row align-items-center">
|
||||
<div class="col-md-6">
|
||||
<p class="text-body-secondary small mb-0">© {{ current_year }} {{ site.name }}</p>
|
||||
</div>
|
||||
<div class="col-md-6 text-md-end">
|
||||
<p class="text-body-secondary small mb-0">
|
||||
{{ __('Powered by %s')|format('<a href="https://wordpress.org" rel="nofollow" class="text-body-secondary">WordPress</a>')|raw }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
60
views/partials/header-centered.html.twig
Normal file
60
views/partials/header-centered.html.twig
Normal file
@@ -0,0 +1,60 @@
|
||||
<header>
|
||||
<nav class="navbar navbar-expand-lg bg-body-tertiary" aria-label="{{ __('Primary navigation') }}">
|
||||
<div class="container flex-column">
|
||||
<a class="navbar-brand fw-bold mb-2" href="{{ site.url }}">
|
||||
{{ site.name }}
|
||||
</a>
|
||||
{% if site.description %}
|
||||
<p class="text-body-secondary small mb-2">{{ site.description }}</p>
|
||||
{% endif %}
|
||||
|
||||
<button class="navbar-toggler" type="button"
|
||||
data-bs-toggle="collapse" data-bs-target="#navbarMain"
|
||||
aria-controls="navbarMain" aria-expanded="false"
|
||||
aria-label="{{ __('Toggle navigation') }}">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
|
||||
<div class="collapse navbar-collapse justify-content-center" id="navbarMain">
|
||||
<ul class="navbar-nav mb-2 mb-lg-0">
|
||||
{% for item in menu %}
|
||||
{% if item.children|length > 0 %}
|
||||
<li class="nav-item dropdown">
|
||||
<a class="nav-link dropdown-toggle{{ item.active ? ' active' : '' }}"
|
||||
href="{{ item.url }}" role="button"
|
||||
data-bs-toggle="dropdown" aria-expanded="false">
|
||||
{{ item.title }}
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
{% for child in item.children %}
|
||||
<li>
|
||||
<a class="dropdown-item{{ child.active ? ' active' : '' }}"
|
||||
href="{{ child.url }}"
|
||||
{% if child.active %}aria-current="page"{% endif %}
|
||||
{% if child.target %}target="{{ child.target }}"{% endif %}>
|
||||
{{ child.title }}
|
||||
</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</li>
|
||||
{% else %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link{{ item.active ? ' active' : '' }}"
|
||||
href="{{ item.url }}"
|
||||
{% if item.active %}aria-current="page"{% endif %}
|
||||
{% if item.target %}target="{{ item.target }}"{% endif %}>
|
||||
{{ item.title }}
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
{% if dark_mode %}
|
||||
{% include 'partials/dark-mode-toggle.html.twig' %}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
65
views/partials/header-offcanvas.html.twig
Normal file
65
views/partials/header-offcanvas.html.twig
Normal file
@@ -0,0 +1,65 @@
|
||||
<header>
|
||||
<nav class="navbar navbar-expand-lg bg-body-tertiary" aria-label="{{ __('Primary navigation') }}">
|
||||
<div class="container">
|
||||
<a class="navbar-brand fw-bold" href="{{ site.url }}">
|
||||
{{ site.name }}
|
||||
</a>
|
||||
|
||||
<button class="navbar-toggler" type="button"
|
||||
data-bs-toggle="offcanvas" data-bs-target="#navbarOffcanvas"
|
||||
aria-controls="navbarOffcanvas"
|
||||
aria-label="{{ __('Toggle navigation') }}">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
|
||||
<div class="offcanvas offcanvas-end" tabindex="-1" id="navbarOffcanvas"
|
||||
aria-labelledby="navbarOffcanvasLabel">
|
||||
<div class="offcanvas-header">
|
||||
<h5 class="offcanvas-title" id="navbarOffcanvasLabel">{{ site.name }}</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="offcanvas"
|
||||
aria-label="{{ __('Close') }}"></button>
|
||||
</div>
|
||||
<div class="offcanvas-body">
|
||||
<ul class="navbar-nav ms-auto mb-2 mb-lg-0">
|
||||
{% for item in menu %}
|
||||
{% if item.children|length > 0 %}
|
||||
<li class="nav-item dropdown">
|
||||
<a class="nav-link dropdown-toggle{{ item.active ? ' active' : '' }}"
|
||||
href="{{ item.url }}" role="button"
|
||||
data-bs-toggle="dropdown" aria-expanded="false">
|
||||
{{ item.title }}
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
{% for child in item.children %}
|
||||
<li>
|
||||
<a class="dropdown-item{{ child.active ? ' active' : '' }}"
|
||||
href="{{ child.url }}"
|
||||
{% if child.active %}aria-current="page"{% endif %}
|
||||
{% if child.target %}target="{{ child.target }}"{% endif %}>
|
||||
{{ child.title }}
|
||||
</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</li>
|
||||
{% else %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link{{ item.active ? ' active' : '' }}"
|
||||
href="{{ item.url }}"
|
||||
{% if item.active %}aria-current="page"{% endif %}
|
||||
{% if item.target %}target="{{ item.target }}"{% endif %}>
|
||||
{{ item.title }}
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
{% if dark_mode %}
|
||||
{% include 'partials/dark-mode-toggle.html.twig' %}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
57
views/partials/header-transparent.html.twig
Normal file
57
views/partials/header-transparent.html.twig
Normal file
@@ -0,0 +1,57 @@
|
||||
<header class="position-absolute w-100" style="z-index: 1030;">
|
||||
<nav class="navbar navbar-expand-lg navbar-dark" aria-label="{{ __('Primary navigation') }}">
|
||||
<div class="container">
|
||||
<a class="navbar-brand fw-bold" href="{{ site.url }}">
|
||||
{{ site.name }}
|
||||
</a>
|
||||
|
||||
<button class="navbar-toggler" type="button"
|
||||
data-bs-toggle="collapse" data-bs-target="#navbarMain"
|
||||
aria-controls="navbarMain" aria-expanded="false"
|
||||
aria-label="{{ __('Toggle navigation') }}">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
|
||||
<div class="collapse navbar-collapse" id="navbarMain">
|
||||
<ul class="navbar-nav ms-auto mb-2 mb-lg-0">
|
||||
{% for item in menu %}
|
||||
{% if item.children|length > 0 %}
|
||||
<li class="nav-item dropdown">
|
||||
<a class="nav-link dropdown-toggle{{ item.active ? ' active' : '' }}"
|
||||
href="{{ item.url }}" role="button"
|
||||
data-bs-toggle="dropdown" aria-expanded="false">
|
||||
{{ item.title }}
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
{% for child in item.children %}
|
||||
<li>
|
||||
<a class="dropdown-item{{ child.active ? ' active' : '' }}"
|
||||
href="{{ child.url }}"
|
||||
{% if child.active %}aria-current="page"{% endif %}
|
||||
{% if child.target %}target="{{ child.target }}"{% endif %}>
|
||||
{{ child.title }}
|
||||
</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</li>
|
||||
{% else %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link{{ item.active ? ' active' : '' }}"
|
||||
href="{{ item.url }}"
|
||||
{% if item.active %}aria-current="page"{% endif %}
|
||||
{% if item.target %}target="{{ item.target }}"{% endif %}>
|
||||
{{ item.title }}
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
{% if dark_mode %}
|
||||
{% include 'partials/dark-mode-toggle.html.twig' %}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
57
views/partials/header.html.twig
Normal file
57
views/partials/header.html.twig
Normal file
@@ -0,0 +1,57 @@
|
||||
<header>
|
||||
<nav class="navbar navbar-expand-lg bg-body-tertiary" aria-label="{{ __('Primary navigation') }}">
|
||||
<div class="container">
|
||||
<a class="navbar-brand fw-bold" href="{{ site.url }}">
|
||||
{{ site.name }}
|
||||
</a>
|
||||
|
||||
<button class="navbar-toggler" type="button"
|
||||
data-bs-toggle="collapse" data-bs-target="#navbarMain"
|
||||
aria-controls="navbarMain" aria-expanded="false"
|
||||
aria-label="{{ __('Toggle navigation') }}">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
|
||||
<div class="collapse navbar-collapse" id="navbarMain">
|
||||
<ul class="navbar-nav ms-auto mb-2 mb-lg-0">
|
||||
{% for item in menu %}
|
||||
{% if item.children|length > 0 %}
|
||||
<li class="nav-item dropdown">
|
||||
<a class="nav-link dropdown-toggle{{ item.active ? ' active' : '' }}"
|
||||
href="{{ item.url }}" role="button"
|
||||
data-bs-toggle="dropdown" aria-expanded="false">
|
||||
{{ item.title }}
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
{% for child in item.children %}
|
||||
<li>
|
||||
<a class="dropdown-item{{ child.active ? ' active' : '' }}"
|
||||
href="{{ child.url }}"
|
||||
{% if child.active %}aria-current="page"{% endif %}
|
||||
{% if child.target %}target="{{ child.target }}"{% endif %}>
|
||||
{{ child.title }}
|
||||
</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</li>
|
||||
{% else %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link{{ item.active ? ' active' : '' }}"
|
||||
href="{{ item.url }}"
|
||||
{% if item.active %}aria-current="page"{% endif %}
|
||||
{% if item.target %}target="{{ item.target }}"{% endif %}>
|
||||
{{ item.title }}
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
{% if dark_mode %}
|
||||
{% include 'partials/dark-mode-toggle.html.twig' %}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
11
views/partials/meta.html.twig
Normal file
11
views/partials/meta.html.twig
Normal file
@@ -0,0 +1,11 @@
|
||||
<div class="text-body-secondary small mb-3">
|
||||
<time datetime="{{ post.date_iso }}">{{ post.date }}</time>
|
||||
<span class="mx-1">·</span>
|
||||
<a href="{{ post.author.url }}" class="text-body-secondary text-decoration-none">{{ post.author.name }}</a>
|
||||
{% if post.categories is defined and post.categories|length > 0 %}
|
||||
<span class="mx-1">·</span>
|
||||
{% for cat in post.categories %}
|
||||
<a href="{{ cat.url }}" class="text-body-secondary text-decoration-none">{{ cat.name }}</a>{% if not loop.last %}, {% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</div>
|
||||
26
views/partials/pagination.html.twig
Normal file
26
views/partials/pagination.html.twig
Normal file
@@ -0,0 +1,26 @@
|
||||
{% if pagination and pagination.pages is defined and pagination.pages|length > 1 %}
|
||||
<nav aria-label="{{ __('Page navigation') }}" class="my-5">
|
||||
<ul class="pagination justify-content-center">
|
||||
<li class="page-item{{ pagination.prev_url is null ? ' disabled' : '' }}">
|
||||
<a class="page-link" href="{{ pagination.prev_url ?? '#' }}"
|
||||
{% if pagination.prev_url is null %}tabindex="-1" aria-disabled="true"{% endif %}>
|
||||
{{ pagination.prev_text }}
|
||||
</a>
|
||||
</li>
|
||||
{% for page in pagination.pages %}
|
||||
<li class="page-item{{ page.is_current ? ' active' : '' }}">
|
||||
<a class="page-link" href="{{ page.url }}"
|
||||
{% if page.is_current %}aria-current="page"{% endif %}>
|
||||
{{ page.number }}
|
||||
</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
<li class="page-item{{ pagination.next_url is null ? ' disabled' : '' }}">
|
||||
<a class="page-link" href="{{ pagination.next_url ?? '#' }}"
|
||||
{% if pagination.next_url is null %}tabindex="-1" aria-disabled="true"{% endif %}>
|
||||
{{ pagination.next_text }}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
{% endif %}
|
||||
22
views/partials/post-navigation.html.twig
Normal file
22
views/partials/post-navigation.html.twig
Normal file
@@ -0,0 +1,22 @@
|
||||
{% if post_navigation is defined and post_navigation|length > 0 %}
|
||||
<nav class="border-top border-bottom py-4 my-4" aria-label="{{ __('Post navigation') }}">
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
{% if post_navigation.previous is defined %}
|
||||
<small class="text-body-secondary d-block mb-1">{{ __('Previous') }}</small>
|
||||
<a href="{{ post_navigation.previous.url }}" class="text-decoration-none">
|
||||
← {{ post_navigation.previous.title }}
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="col-6 text-end">
|
||||
{% if post_navigation.next is defined %}
|
||||
<small class="text-body-secondary d-block mb-1">{{ __('Next') }}</small>
|
||||
<a href="{{ post_navigation.next.url }}" class="text-decoration-none">
|
||||
{{ post_navigation.next.title }} →
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
{% endif %}
|
||||
11
views/partials/search-form.html.twig
Normal file
11
views/partials/search-form.html.twig
Normal file
@@ -0,0 +1,11 @@
|
||||
<form role="search" method="get" action="{{ site.url }}" class="mb-4">
|
||||
<div class="input-group">
|
||||
<input type="search" class="form-control" name="s"
|
||||
placeholder="{{ __('Search...') }}"
|
||||
value="{{ search_query is defined ? search_query : '' }}"
|
||||
aria-label="{{ __('Search') }}">
|
||||
<button class="btn btn-primary" type="submit">
|
||||
{{ __('Search') }}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
44
views/partials/sidebar.html.twig
Normal file
44
views/partials/sidebar.html.twig
Normal file
@@ -0,0 +1,44 @@
|
||||
<aside aria-label="{{ __('Blog sidebar') }}">
|
||||
{% if sidebar.recent_posts is defined and sidebar.recent_posts|length > 0 %}
|
||||
<div class="mb-4">
|
||||
<h3 class="sidebar-heading h6 text-uppercase fw-semibold">
|
||||
{{ __('Recent Posts') }}
|
||||
</h3>
|
||||
<ul class="list-unstyled">
|
||||
{% for post in sidebar.recent_posts %}
|
||||
<li class="mb-2">
|
||||
<a href="{{ post.url }}" class="text-decoration-none">{{ post.title }}</a>
|
||||
<br>
|
||||
<small class="text-body-secondary">{{ post.date }}</small>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
{% endif %}
|
||||
|
||||
<div class="mb-4">
|
||||
<h3 class="sidebar-heading h6 text-uppercase fw-semibold">
|
||||
{{ __('Search') }}
|
||||
</h3>
|
||||
{% include 'partials/search-form.html.twig' %}
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
{% if sidebar.tags is defined and sidebar.tags|length > 0 %}
|
||||
<div class="mb-4">
|
||||
<h3 class="sidebar-heading h6 text-uppercase fw-semibold">
|
||||
{{ __('Tags') }}
|
||||
</h3>
|
||||
<div>
|
||||
{% for tag in sidebar.tags %}
|
||||
<a href="{{ tag.url }}" class="badge bg-secondary text-decoration-none me-1 mb-1">
|
||||
{{ tag.name }}
|
||||
</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</aside>
|
||||
Reference in New Issue
Block a user