Reusable Contao content element that renders a flexible two-slot layout wrapper.
Designed as a macro-layout element: it defines structural layout areas, while actual content is managed through Contao articles, frontend modules or HTML.
The bundle is theme-agnostic: it outputs clean HTML hooks. Styling is handled in your project CSS.
- Content element: Layout Preset
- Frontend module: VTXM Toggle Navigation
- Two slots:
- Slot A
- Slot B
- Slot types:
- Article
- Frontend module
- HTML
- Layout modes:
- left-right
- right-left
- top-bottom
- bottom-top
- Layout ratios:
- 50-50
- 60-40
- 40-60
- 70-30
- 30-70
- Presets:
- default
- about
- contact
- spotlight
- Options:
- divider
- mobile stacking
- alignment
- Supports CSS ID / class
- Supports the Contao headline field
- Exposes Contao visibility and scheduled publishing fields
- Slot type selectors use subpalettes so only relevant slot fields are shown
- Includes real recursion guards for article and module rendering
- Integrates the shared Toggle Only navigation shell from
frontend-assets
- Add a new content element of type Layout Preset
- Optionally add a headline using the standard Contao headline field
- Choose:
- preset
- layout mode
- layout ratio
- alignment
- divider
- mobile stacking
- Configure Slot A and Slot B:
- Article: select page + article
- Module: select frontend module
- HTML: enter custom HTML/RTE content
Slot fields are shown through Contao subpalettes. Select the slot type first; the backend then shows only the fields needed for that type.
For article slots, the article list depends on the selected page. Selecting a page triggers a backend reload and refreshes the dependent article selector immediately, including before the element is saved for the first time.
Internally, slot type selector values are stored with Layout Preset-specific namespaced values:
vtxm_layout_preset_slot_articlevtxm_layout_preset_slot_modulevtxm_layout_preset_slot_html
The backend labels remain Article, Module and HTML. The namespaced stored values prevent Contao's global tl_content selector palette resolution from matching core or third-party palettes such as article.
Recommended structure:
layout-preset= macro layout / split layoutcontent-grid= micro layout / grid containercontent-elements= reusable content blocksarticle-insert= article include module
The frontend module VTXM Toggle Navigation provides the Contao integration for the shared VTXM Toggle Only navigation. It renders only the wrapper shell, accessibility attributes and template contract. Navigation data still comes from a regular Contao Navigation frontend module.
Runtime dependency:
frontend-assets/css/vtxm-components.cssfrontend-assets/js/vtxm-components.js
This bundle does not ship or duplicate the shared navigation CSS or JavaScript.
Backend setup:
- Create a standard Contao frontend module of type Navigation and configure its root page, levels, protected pages and visibility as usual.
- Create a frontend module of type VTXM Toggle Navigation.
- Select the standard Navigation module in Navigation module.
- Select one of the fixed visual presets and adjust the toggle, dialog and close labels if needed.
- Place the VTXM Toggle Navigation module in the page layout or render it through Contao's normal module mechanisms.
Module composition:
- The wrapper module renders
mod_vtxm_toggle_navigation.html5. - The selected Navigation module remains responsible for page tree resolution.
- During this render path, the selected Navigation module is cloned in memory
and its
navigationTplis set tonav_vtxm_dialog, while itscustomTplis set tomod_vtxm_navigation_inner. - The internal module wrapper emits only the generated navigation list output, so source module headlines, skip links, wrapper markup and stored custom module templates do not alter the VTXM rendering contract.
- The stored source Navigation module configuration is not changed.
- Missing, invalid, invisible or non-navigation source modules render no broken trigger/dialog markup.
Backend fields:
vtxmNavigationModule: required source module select, limited to standard Contao modules with typenavigation.vtxmNavigationPreset: required fixed preset select.vtxmToggleLabel: required trigger label, defaultMenu.vtxmDialogTitle: required dialog title, defaultNavigation.vtxmCloseLabel: required close label, defaultClose.
Available presets:
contained-lightcontained-darkeditorial-lighteditorial-dark
Template contract:
- Root:
.vtxm-nav,.vtxm-nav--toggle-only,[data-vtxm-nav]and exactly one preset class. - Header:
.vtxm-nav-header,.vtxm-nav-header__inner,.vtxm-nav-header__brandandbutton.vtxm-nav-header__toggle. - Trigger:
[data-vtxm-nav-toggle],aria-controlsandaria-haspopup="dialog". - Dialog:
.vtxm-nav-dialog,[data-vtxm-nav-dialog], uniqueidandaria-labelledby. - Close hooks:
[data-vtxm-nav-close]on the backdrop and close button. - Navigation hooks from
nav_vtxm_dialog.html5:.vtxm-nav-dialog__list,.vtxm-nav-dialog__itemand.vtxm-nav-dialog__link.
Progressive enhancement:
The dialog is not rendered hidden server-side and does not receive modal-only
semantics such as role="dialog" or aria-modal="true" from PHP. Without
JavaScript, the navigation content remains visible after the header. When
vtxm-components.js initializes, it resolves the dialog through
aria-controls, applies modal semantics, closes the enhanced dialog into its
initial state, manages focus, handles Escape and locks scroll while open.
First-version limitations:
- No brand text or brand link fields.
- No arbitrary visual controls beyond the four fixed presets.
- No custom submenu behavior; nested levels are rendered as Contao supplies them.
- Styling and JavaScript behavior belong to
frontend-assetsor project CSS.
This bundle does not include styling by design.
Use project CSS to define:
- spacing
- ratios
- divider styling
- responsive behavior
- preset-specific visuals
CSS ID / class values from the backend are passed to the root wrapper.
The element also exposes Contao's standard visibility fields:
- invisible
- start
- stop
These fields control the Layout Preset content element itself through Contao's normal content element handling.
When an article is used as a slot source, the selected source article may remain unpublished. This allows hidden articles to act as internal content containers. The Layout Preset renders only published content elements from that source article.
The element prevents recursive rendering loops for article and module slots.
Example:
- Layout Preset renders Article A
- Article A contains another Layout Preset
- That Layout Preset tries to render Article A again
In this case, rendering is stopped for the recursive article and the affected slot returns empty output. Recursive frontend module references are handled the same way.
Invalid article or module IDs also return empty output. They do not throw frontend errors.
Article slot rendering intentionally does not check whether the source article itself is published. Only published content elements inside the selected article are rendered.
Root classes:
.layout-preset.preset--default.preset--about.preset--contact.preset--spotlight.mode--left-right.mode--right-left.mode--top-bottom.mode--bottom-top.ratio--50-50.ratio--60-40.ratio--40-60.ratio--70-30.ratio--30-70.align--start.align--center.has-divider.is-stack-mobile
Inner hooks:
.layout-preset__headline.layout-preset__inner.layout-preset__area.layout-preset__area--a.layout-preset__area--b
Toggle navigation hooks:
.vtxm-nav.vtxm-nav--toggle-only.vtxm-nav--contained-light.vtxm-nav--contained-dark.vtxm-nav--editorial-light.vtxm-nav--editorial-dark[data-vtxm-nav].vtxm-nav-header.vtxm-nav-header__inner.vtxm-nav-header__brand.vtxm-nav-header__toggle[data-vtxm-nav-toggle].vtxm-nav-dialog[data-vtxm-nav-dialog].vtxm-nav-dialog__backdrop.vtxm-nav-dialog__panel.vtxm-nav-dialog__header.vtxm-nav-dialog__title.vtxm-nav-dialog__close[data-vtxm-nav-close].vtxm-nav-dialog__nav.vtxm-nav-dialog__list.vtxm-nav-dialog__item.vtxm-nav-dialog__link
layout_preset.html5
mod_vtxm_toggle_navigation.html5
mod_vtxm_navigation_inner.html5
nav_vtxm_dialog.html5
Add the package definition to your Contao project composer.json or install it via your configured repository setup.
Example package reference:
{
"repositories": [
{
"type": "package",
"package": {
"name": "vtxm-h/layout-preset",
"version": "1.0.9",
"type": "contao-bundle",
"license": "MIT",
"dist": {
"url": "https://github.com/vtxm-h/layout-preset/archive/refs/tags/v1.0.9.zip",
"type": "zip"
},
"autoload": {
"psr-4": {
"Vendor\\LayoutPresetBundle\\": "src/"
}
},
"require": {
"php": "^8.0",
"contao/core-bundle": "^4.13",
"contao/manager-plugin": "^2.0",
"vtxm-h/contao-dca-helpers": "^1.0"
},
"extra": {
"contao-manager-plugin": "Vendor\\LayoutPresetBundle\\ContaoManager\\Plugin"
}
}
}
]
}Install:
composer require vtxm-h/layout-presetContao 4.13 PHP 8.0+
Existing Layout Preset rows that still store the legacy slot selector values article, module or html are migrated by the bundle migration Migrate Layout Preset slot selector values. It widens slotAType and slotBType to varchar(32), changes their default to the namespaced article value and updates only tl_content records with type='layout_preset'.
Rows belonging to other content element types are not changed.
MIT