Skip to main content

A Plone 6 theme based on Bootstrap 6 and Barceloneta (Classic UI).

Project description

plonetheme.bootstrap6

[!NOTE] The package name plonetheme.bootstrap6 is a working title and is still open for discussion. The final name may change before any stable release.

A Plone 6.2 Classic UI theme based on Bootstrap 6.

[!WARNING] This theme is under active development and not yet production-ready. It depends on Bootstrap 6, which is currently in alpha and subject to breaking changes without notice. The Bootstrap 6 alpha API — including configuration variables, mixins, and class names — may change in any future alpha or beta release. Do not use this theme in production environments.

PyPI version Bootstrap 6 alpha Development status License: GPL v2

Overview

plonetheme.bootstrap6 is a Diazo-based Plone theme that brings Bootstrap 6 to the Plone Classic UI. Unlike Barceloneta (Bootstrap 5), it uses Bootstrap 6's native @use/@forward Sass module system and its standard breakpoints. Whether this theme becomes the basis for Plone 7's Classic UI is an idea currently under evaluation.

Key characteristics:

  • Bootstrap 6 alpha (docs, twbs/bootstrap#v6-dev) with native @use/@forward Sass module system — no deprecated @import
  • Plone Classic UI compatible — uses the same HTML selectors as Barceloneta (#content-header, #portal-globalnav-wrapper, #portal-column-content, etc.)
  • Dark mode support via Bootstrap 6 color-mode system (@media (prefers-color-scheme: dark))
  • Standard Bootstrap 6 breakpoints (lg: 1024px, xl: 1280px, 2xl: 1536px) — no barceloneta backports
  • CSS custom properties for Plone colors (--plone-link, --plone-state-*) without a vendor prefix (Bootstrap 6 dropped --bs-)

Requirements

Dependency Version
Plone ≥ 6.2
plone.app.theming any
Python ≥ 3.10
Node.js / pnpm for SCSS builds only

Installation

Python package

Add plonetheme.bootstrap6 to your Plone instance's install_requires or buildout eggs:

[instance]
eggs +=
    plonetheme.bootstrap6

Then activate the theme in the Plone control panel under Site Setup → Theming, or via a Generic Setup profile that depends on this package.

Activate via Generic Setup

The included profiles/default profile sets the active theme automatically when applied:

<!-- profiles/default/metadata.xml -->
<dependencies>
    <dependency>profile-plonetheme.bootstrap6:default</dependency>
</dependencies>

SCSS Structure

The theme is built from a set of modular SCSS files inside scss/. Bootstrap 6 requires that its configuration variables are set before the first @use "bootstrap/scss/..." call — this is handled centrally in _bs-forward.scss.

scss/
├── _bs-forward.scss        # Bootstrap 6 config + forward (must be first)
├── _bs5-compat.scss        # Bootstrap 5 → 6 compatibility shim (see below)
├── _noto.scss              # Noto Sans web-font face declarations
├── _plone-colors.scss      # Plone brand colors and state color maps
├── _plone-root.scss        # CSS custom properties emitted on :root
├── _roboto.scss            # Roboto web-font face declarations
├── bootstrap6.scss         # Main entry point (compiled to CSS)
└── plone/
    ├── _scaffolding.scss   # Base layout, skip nav, link colors
    ├── _header.scss        # #content-header, logo, livesearch
    ├── _sitenav.scss       # .navbar-bootstrap6, dropdowns, offcanvas
    ├── _toolbar.scss       # #edit-bar (Classic UI edit toolbar)
    ├── _breadcrumbs.scss   # #above-content-wrapper
    ├── _content.scss       # Column layout, #content, related items
    ├── _portlets.scss      # .portletWrapper, .portlet, navigation portlet
    ├── _forms.scss         # .field, form widgets, login, search
    └── _footer.scss        # #portal-footer-wrapper, doormat, site-actions

Key Bootstrap 6 differences from barceloneta (Bootstrap 5)

Topic Bootstrap 5 (barceloneta) Bootstrap 6 (bootstrap6)
Sass API @import (global namespace) @use / @forward (module-scoped)
Configuration $var !default; before @import @use "config" with ($var: value)
Variable files _variables.scss, _variables-dark.scss _config.scss, _colors.scss, _theme.scss
CSS variable prefix --bs-body-bg --body-bg (no prefix)
Color functions darken() / lighten() color.adjust() via @use "sass:color"
Z-index names $zindex-dropdown, $zindex-offcanvas $zindex-menu, $zindex-drawer
Breakpoint lg / xl / xxl 992px / 1200px / 1400px 1024px / 1280px / 1536px (standard BS6; xxl renamed to 2xl)
Color system HSL oklch
RFS / font-size() mixin present removed

Bootstrap 5 Compatibility Shim

Plone Classic UI templates were written against Bootstrap 5. Several component names changed in Bootstrap 6. The file scss/_bs5-compat.scss bridges the gap so that existing templates render correctly without modification.

[!NOTE] This shim is a transitional measure. It will be removed once the upstream Plone templates have been updated to Bootstrap 6 class names. To remove it, delete the @use "bs5-compat" line in scss/bootstrap6.scss.

Covered components

Dropdown → Menu

Bootstrap 6 renamed the dropdown component to menu.

BS5 class BS6 equivalent Notes
.dropdown .dropdown unchanged (position wrapper)
.dropdown-toggle caret re-added via ::after in shim
.dropdown-menu .menu full style set, uses BS6 CSS variables
.dropdown-item .menu-item hover / active / disabled states
.dropdown-header .menu-header section label
.dropdown-divider .menu-divider horizontal rule
.dropdown-menu-end right-align alias
.dropdown-menu-md-end responsive right-align

JavaScript note: data-bs-toggle="dropdown" must be changed to data-bs-toggle="menu" in templates once the Bootstrap 6 JS bundle is active. The shim covers the CSS side only.

Button color variants

Bootstrap 6 replaced the colour-named button classes with a functional modifier system (btn-solid, btn-outline, …) driven by --theme-* CSS custom properties. The shim re-introduces the old names by setting the --btn-* variables that the base .btn rule reads.

BS5 class BS6 approach Shim
.btn-primary .btn.btn-solid + --theme-*: var(--primary-*)
.btn-secondary .btn.btn-solid + --theme-*: var(--secondary-*)
.btn-success .btn.btn-solid + --theme-*: var(--success-*)
.btn-danger .btn.btn-solid + --theme-*: var(--danger-*)
.btn-warning .btn.btn-solid + --theme-*: var(--warning-*)
.btn-info .btn.btn-solid + --theme-*: var(--info-*)
.btn-light / .btn-dark .btn.btn-subtle / .btn.btn-solid
.btn-outline-{color} .btn.btn-outline + --theme-* ✓ (all 8 variants)

Unchanged classes (btn, btn-sm, btn-lg, btn-link) still exist natively in Bootstrap 6 and do not need the shim.

Directional dropdown containers

Bootstrap 6 removed .dropend / .dropstart / .dropup. Side-opening menus now use data-bs-placement. The shim restores positioning and caret styles for the old class names.

BS5 class Notes
.dropend submenu opens inline-end (right in LTR); right-pointing caret
.dropstart submenu opens inline-start (left in LTR); left-pointing caret
.dropup submenu opens upward

Offcanvas → Drawer

Bootstrap 6 replaced the offcanvas panel with a native <dialog>-based drawer component. Plone Classic UI uses Bootstrap 5 offcanvas for the mobile navigation panel (see #offcanvasNavbar in index.html) and Bootstrap 5 JS controls the .show state.

BS5 class BS6 equivalent Notes
.offcanvas .drawer position, slide-in, visibility toggle via .show
.offcanvas-end .drawer-end slides in from the right
.offcanvas-start .drawer-start slides in from the left
.offcanvas-top .drawer-top slides in from the top
.offcanvas-bottom .drawer-bottom slides in from the bottom
.offcanvas-header .drawer-header header row with close button
.offcanvas-title .drawer-title title text
.offcanvas-body .drawer-body scrollable content area
.offcanvas-backdrop ::backdrop (native) semi-transparent overlay; .show triggers visibility

At the navbar-expand-{bp} breakpoint the offcanvas is shown inline (always visible, no slide-in), matching Bootstrap 5 navbar behaviour.

Modal → Dialog

Bootstrap 6 replaced the .modal component with the native <dialog> element styled via .dialog-*. Mockup's pat-plone-modal pattern (data-pat-plone-modal / .pat-plone-modal) still generates Bootstrap 5 .modal HTML (plain <div> elements, not <dialog>). This shim re-introduces all .modal-* CSS using Bootstrap 6 design tokens.

BS5 class BS6 equivalent Notes
.modal .dialog full-viewport container; .show triggers visibility
.modal-backdrop ::backdrop (native) .show and .backdrop-active supported (Mockup uses the latter)
.modal-dialog no inner wrapper in BS6; replicated for Mockup's <div> structure
.modal-content .dialog directly styled card; uses BS6 --border-color-translucent, --radius-7, --box-shadow-lg
.modal-header .dialog-header title + close button row
.modal-title .dialog-title heading text
.modal-body .dialog-body main content area
.modal-footer .dialog-footer action button row
.modal-sm / .modal-lg / .modal-xl .dialog-sm / .dialog-lg / .dialog-xl width variants
.modal-fullscreen .dialog-fullscreen full-viewport variant
.modal-dialog-centered native (dialog centres via margin: auto) replicated for <div> structure
.modal-dialog-scrollable scrollable body variant
body.modal-open .dialog-open prevents background scroll while open

Mockup note: pat-plone-modal adds .backdrop-active (not .show) to its backdrop element. The shim accepts both.

Responsive utility classes — breakpoint-infix format

Bootstrap 6 moved the breakpoint from an infix to a prefix:

BS5 pattern BS6 pattern Example
.d-{bp}-{val} .{bp}\:d-{val} .d-lg-flex.lg\:d-flex
.flex-{bp}-{dir} .{bp}\:flex-{dir} .flex-lg-row
.align-items-{bp}-{val} .{bp}\:align-items-{val} .align-items-lg-center
.justify-content-{bp}-{val} .{bp}\:justify-content-{val}
.order-{bp}-{n} .{bp}\:order-{n}
.text-{bp}-{align} .{bp}\:text-{align} .text-lg-center
.float-{bp}-{dir} .{bp}\:float-{dir} .float-md-end

The shim regenerates all of the above for breakpoints sm, md, lg, xl.

Navbar expand — .navbar-expand-{bp}

Bootstrap 6 renamed .navbar-expand-lg to .lg\:navbar-expand. The shim restores the old infix class for sm, md, lg, xl, covering the flex layout switch (horizontal nav items, hidden toggler) above the breakpoint. The offcanvas inline-display override is part of the Offcanvas section.

Misc removed / changed classes

BS5 class Status in BS6 Shim behaviour
.text-muted removed maps to var(--fg-3) (subdued foreground token)
.btn-close (no child <svg>) requires child <svg> for × icon adds background-image fallback via :has() for bare <button class="btn-close">
.btn-close-white removed applies filter: invert(1) grayscale(100%) brightness(200%)
.form-select removed (use .form-control on <select>) full styled-select appearance using BS6 form-control tokens

Bootstrap 5 --bs-* CSS custom properties

Bootstrap 6 dropped the --bs- prefix entirely. Mockup components (pat-contentbrowser, pat-relateditems, etc.) reference the old --bs-* names directly in their Svelte styles. The shim emits a set of --bs-* aliases on :root that resolve to the corresponding Bootstrap 6 tokens:

--bs-* alias Resolves to
--bs-body-bg var(--bg-body)
--bs-border-color var(--border-color)
--bs-border-radius var(--radius-3)
--bs-border-style var(--border-style)
--bs-border-width var(--border-width)
--bs-primary var(--primary-base)
--bs-light var(--bg-3)
--bs-light-bg-subtle var(--secondary-bg-subtle)
--bs-btn-padding-y/x var(--btn-input-padding-y/x)
--bs-btn-font-size var(--btn-input-font-size)
--bs-primary-rgb 13, 110, 253 (BS5 default; for rgba() expressions)
--bs-secondary-bg-rgb 233, 236, 239 (BS5 default; for rgba() expressions)

[!NOTE] The --bs-*-rgb variables are intentionally kept at Bootstrap 5 default values (not the Plone brand color) because they are used exclusively for transparency overlays (rgba(var(--bs-primary-rgb), .25)) in Mockup's compiled Svelte output — overriding them would require recompiling Mockup.

What is not covered

BS5 feature Status
.nav-tabs, .nav-pills, .nav-underline unchanged in BS6, no shim needed
collapse still present in BS6

Building CSS

See DEVELOPMENT.md for the full development workflow.

Quick build:

cd path/to/plonetheme.bootstrap6
pnpm install
pnpm build

The compiled CSS lands in src/plonetheme/bootstrap6/theme/css/.

Theming & Customisation

The easiest way to customise bootstrap6 is to create a new theme package that depends on it and override individual SCSS partials. Alternatively, use the Diazo TTW editor in Plone's theming control panel to add extra CSS rules on top.

To change a Bootstrap 6 config variable (e.g. primary color), you need to do it via @use "bootstrap/scss/config" with (...) before any other Bootstrap import — follow the pattern in _bs-forward.scss.

Diazo Theme Rules

The Diazo rules are defined in src/plonetheme/bootstrap6/theme/rules.xml and mirror the structure of plonetheme.barceloneta.

Changelog

See CHANGES.md.

Source Code and Contribution

Please read the Plone contributor agreement before submitting a pull request.

License

GNU General Public License v2. See LICENSE for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

plonetheme_bootstrap6-1.0.0a1.tar.gz (1.2 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

plonetheme_bootstrap6-1.0.0a1-py3-none-any.whl (1.2 MB view details)

Uploaded Python 3

File details

Details for the file plonetheme_bootstrap6-1.0.0a1.tar.gz.

File metadata

  • Download URL: plonetheme_bootstrap6-1.0.0a1.tar.gz
  • Upload date:
  • Size: 1.2 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.9

File hashes

Hashes for plonetheme_bootstrap6-1.0.0a1.tar.gz
Algorithm Hash digest
SHA256 626d4a8518a81282d72d7829d5ff7174c87ba63274d2605d4e0f13dab6665de8
MD5 5d392f372b4b25cfb07fb0d9a08a27c0
BLAKE2b-256 3a0ae396e2083a09d47171c978535863c34279402d16bbbd8cf0d059a6331342

See more details on using hashes here.

File details

Details for the file plonetheme_bootstrap6-1.0.0a1-py3-none-any.whl.

File metadata

File hashes

Hashes for plonetheme_bootstrap6-1.0.0a1-py3-none-any.whl
Algorithm Hash digest
SHA256 b54ef03f5db64921e8da76e74a15c3eace7496f837e02a01459fb76045fe48d5
MD5 1cd28efd93bc2cff8fb9d9074a052cc0
BLAKE2b-256 6268dab9e10dd3f4674f850c64bd031842fb8fb9bfe90164e3aa5e246b2aeef0

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page