Basic principle
Blocks build on the interplay between base and view templates. The base template defines the overarching page layout with everything that stays the same on every page — such as header, footer, navigation, or included scripts. The view template is the template of a specific page — it integrates the base template via{{ extends }} and fills individual areas with page-specific content.
A block is a named area within a template that is opened with {{ block "name" }} and closed with {{ /block }}. It is both a structural and a content building block. In the base template, it defines which areas a page has and where they are located, including default content that is displayed as long as a view template does not explicitly override this block. In the view template, it fills exactly these areas with page-specific content.
Overriding blocks
A view template addresses a block by redefining it with the same name. There are three options here:- The default content is completely replaced:
- With
append— the new content is inserted after the default content:
- With
prepend— the new content is inserted before the default content:
append and prepend are useful when the default content of a block is generally fine but should be supplemented with additional content on individual pages.
Using blocks in templates
Blocks cannot be defined or overridden in every template type. It depends on the role a template plays in the system:- Base templates (layout templates) are the only place where blocks are defined. They determine which areas of a page exist and what default content these have.
- View templates (page templates) and email templates can override or extend blocks of a base template. Both integrate a base template via
{{ extends }}. An important restriction applies here: a template with{{ extends }}may consist exclusively of block instructions. No HTML, no code, no include may be located outside of a block.
| Block | Typical content |
|---|---|
header | Header area of the page |
content_main | Main content of the page |
footer | Footer area of the page |
scripts | JavaScript at the end of the page |
Blocks and other constructs
In the template system, there are several ways to structure and reuse code. Blocks are just one of several tools. Blocks reserve named placeholders in the layout that a view template can later fill with page-specific content. They work from top to bottom — the base template provides the framework, the view template fills it. Blocks are the link between layout and page content. Includes integrate a separate template file at a specific location — similar to a building block that can be used in multiple places. A breadcrumb or an error message are typical examples — the code is written once and integrated wherever it is needed. Unlike blocks, includes can accept variables and are therefore flexible in their parameters. Modules such as$wsBasket or $wsProducts provide data. They are not template building blocks but server-side data sources that you access in the template.
In practice, all three work together. A block defines the area of the page, includes are integrated within the block — these access the required data via modules.
Permitted content
HTML and template syntax
Within a block, the following are permitted:- Any HTML
- Variable declarations (
{{ var ... }}) and outputs ({{= ... }}) - Control structures such as
{{ if }},{{ foreach }},{{ switch }} - Includes (
{{ include ... }}) - Module access (
$wsBasket.items,$wsCheckout.sum.total, etc.)
JavaScript and CSS
Blocks such ashead or scripts can contain <style> tags, <link> elements, and <script> blocks without restrictions, including inline JavaScript. Template logic within <script> tags is also possible, for example to pass server-side computed values into JavaScript:
Forms
Forms are fully permitted within blocks. This includes all common form elements (input fields, buttons, hidden fields, security mechanisms).Nesting
Blocks can be nested arbitrarily deeply. This makes sense when a larger area of the layout should be divided into several independently overridable sub-areas. The base template defines the outer structure, and each inner block can be specifically overridden in the view template:sidebar or only main without having to touch the outer content block.
Best practices
When blocks make sense
Blocks are the right tool when an area appears on multiple pages but should look different depending on the page — for example, the footer, which appears in full on normal pages with navigation, links, and contact information but is reduced to a compact variant on the login or checkout page.When another construct makes sense
If an area should look identical on multiple pages and is never overridden, an include is the better choice. The product preview in a category list, a breadcrumb bar, or an alert banner are not overridden — they are integrated. Blocks would therefore not be the right choice here.The right scope for a block
A block should correspond to a clearly delimitable page area. Large enough to be sensibly overridable, but small enough not to change too much at once. A single block for the entire page is too large; a block per HTML element is too little. As a guideline: if you can clearly name a block and explain what it is responsible for, it is well used.Naming blocks
The name of a block must be unique. No base template may have two blocks with the same name. The name should describe the purpose of the area (e.g.,header, content_main, scripts) and be self-explanatory. Generic names such as block1 or area say nothing about what is inside and make maintenance more difficult.
Business logic in blocks
A block outputs content; it does not make decisions. Price calculations, access rights, or data transformations belong in the corresponding module or in a specialized include. Blocks that contain such logic are difficult to read, hardly testable, and cannot be reused.Avoiding hard-to-maintain structures
Deep nesting of blocks should be limited to what is necessary. The deeper the nesting, the harder it is to follow which block is actually output in the end. A rule of thumb: if a block becomes very long, parts of it belong in includes. And if the nesting becomes hard to grasp, that is a signal to simplify the structure.Examples
Simple block
An empty block in the base template. It exists only as an extension point and has no default content. A view template can fill it, but doesn’t have to.Block with static content
A block with fixed content that is displayed on all pages as long as no view template overrides it.Block with variable access
All data provided by the system — such as product name or description — can be accessed directly within a block. This makes it possible, for example, to dynamically fill page title and meta description per product.Block with conditional output
Blocks can contain template logic — for example, to display content only under certain conditions.Block containing another block
In the base template, blocks can be nested within one another. Each inner block (heresidebar and main) is independently overridable.
Negative example
A view template that uses{{ extends }} may consist exclusively of block instructions. Code or HTML outside of a block is invalid and leads to errors.
