Writing Breeze-friendly Module
About
When it comes to third-party modules, Breeze is highly compatible with blank/luma modules out of the box since we use the same page structure, blocks, layout updates, and templates for almost all of the pages.
The only parts that you may need to change are:
- CSS styles — if you use
source/_module.less
entry point for your styles. - Javascript — if you use
requirejs
in your scripts. - Html templates — if you use custom knockout tags (
<each>
,<render>
, etc).
Let’s take a look at directory structure of the Breeze-friendly module.
Directory structure
<module>/view/frontend/
├── layout/
│ ├── breeze_catalog_product_view.xml
│ └── breeze_default.xml
├── templates/
└── web/
├── css/
│ └── breeze/
│ ├── _checkout.less
│ ├── _email.less
│ └── _default.less
├── js/
│ └── breeze/
│ └── component.js
└── template/
└── component.html
Path | Description |
---|---|
layout/breeze_catalog_product_view.xml | Layout instructions for product page. |
layout/breeze_default.xml | Layout instructions for all pages. JS components are registered here. |
web/css/breeze/_checkout.less | Styles for checkout page. |
web/css/breeze/_default.less | Styles for all pages. |
web/css/breeze/_email.less | Styles for email templates. |
web/js/breeze/component.js | Breeze js component. You can put multiple components in a single file. |
web/template/component.html | Knockout template for a view component. |
Let’s review each entry with usage examples.
Layout updates
When writing module for Breeze Frontend you may want to create layout updates
that will affect Breeze-based theme only and will not change anything in blank/luma
themes. Using breeze_
prefixed filename you guarantee
that these instructions will not affect blank/luma based theme:
- breeze_default.xml
- breeze_catalog_category_view.xml
- breeze_catalog_category_layered.xml
- and so on.
The most common use-case for layout update — is a JS component registration.
Remember to use breeze_default.xml
layout update for this case.
Styles
In order to add your own styles to the Breeze-based theme you need to create
<module>/view/frontend/web/css/breeze/_default.less
file. This file will be
automatically included on all store pages.
You can also create <module>/view/frontend/web/css/breeze/_checkout.less
file
for the styles that used at checkout page only.
Here is how your _default.less
may look like:
& when (@critical) {
.selector {
//
}
}
& when not (@critical) {
.selector:hover {
//
}
}
Using @critical
guard is required. Otherwise your styles will be duplicated
in both critical and deferred styles.
Email styles
When you want to add custom styles to the email templates, you need to create
<module>/view/frontend/web/css/breeze/_email.less
file.
- Unlike theme styles, email styles doesn’t support
@critical
guard. - Use
.email-non-inline()
mixin for complex styles that cannot be inlined by Magento.
Example:
.selector {
//
}
.email-non-inline() {
@media @media-sm-down {
.selector {
//
}
}
}
Components
Please read the JS components page before you proceed further.
JS component lifecycle in Breeze is pretty similar to Luma’s components:
- DOM parser finds
data-mage-init
ortext/x-magento-init
instructions. - JS Component is created according to these instructions.
The only difference is that you have to register your component in one of js bundles
using breeze_default.xml
layout update:
<referenceBlock name="breeze.js">
<arguments>
<argument name="bundles" xsi:type="array">
<item name="default" xsi:type="array">
<item name="items" xsi:type="array">
<item name="Vendor_Module/js/component" xsi:type="array">
<item name="path" xsi:type="string">Vendor_Module/js/breeze/component</item>
</item>
</item>
</item>
</argument>
</arguments>
</referenceBlock>
Pay attention to the bundle name in the example above and choose the right one for your component. See the list of available bundles at JS components page.
Now, let’s view a basic example of js/breeze/component.js
file:
define(['uiComponent'], (Component) => {
'use strict';
$.widget('uniqueComponentName', {
component: 'Vendor_Module/js/component', // an alias that's used in the `data-mage-init` instructions.
create: function () {
// this.element - Cash collection. See https://github.com/fabiospampinato/cash
// this.options - object
}
});
Component.extend({
component: 'Vendor_Module/js/component', // an alias that's used in the initialization instructions.
defaults: {
template: 'Vendor_Module/component' // see "Knockout templates" section below
},
create: function () {
// this.element - Cash collection. See https://github.com/fabiospampinato/cash
// this.options - object
}
});
});
Please review Widgets and UI Components pages to get more information about these components.
Knockout templates
Think twice before using knockout templates. We think that they are overused in Luma’s codebase and we will remove their usages from built-in Breeze components in the future. Usually, simple
_.template
is what you need for the majority of the modules.
If your JS component is using KnockoutJS template, you should prerender it. To do that you need to use layout update instructions and our HTML block renderer.
Here is an example that will render knockout or raw html template and will make it visible for view component from the previous example:
<referenceContainer name="before.body.end">
<block class="Swissup\Breeze\Block\HtmlTemplate" name="breeze.Vendor_Module_component" template="Vendor_Module::component.html"/>
</referenceContainer>
See more information at UI Components page.