Skip to content

Commit 9dbefe0

Browse files
committed
Merge remote-tracking branch 'upstream/develop' into MQE-1957
2 parents ea22499 + 1605bd0 commit 9dbefe0

5 files changed

+399
-1
lines changed

docs/how-to/how-to-add-appearance.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,6 @@ _Use _module.less for import statements_
229229

230230
An example module for this topic is available for download in the [pagebuilder-examples repository](https://github.com/magento-devdocs/pagebuilder-examples/tree/master/Example/PageBuilderBannerAppearance).
231231

232-
## Conclusion
232+
## Final thoughts
233233

234234
Using appearances to extend Page Builder's native content types represents one of Page Builder's best practices for creating a variety of new content building blocks based on existing content types.
Lines changed: 249 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,249 @@
1+
# How to use attributes to apply CSS styling
2+
3+
Attributes in Page Builder give you a way to add a variety of interactive CSS styling options for your content types. For example, Page Builder's Heading content type provides a number of built-in styling options from its form. The Heading form gives users options to set different heading types, text alignments, border properties, margins, and paddings. It also lets users apply multiple static CSS classes.
4+
5+
But what if you want to give users more interactive styling options? For example, maybe you want to add Heading color options. Or Heading text style options. Using attributes is the way to do it.
6+
7+
## Install the example module
8+
9+
To help you get started with using attributes, we created an example module that you can clone and install from [magento-devdocs/PageBuilderStylingWithAttributes](https://github.com/magento-devdocs/PageBuilderStylingWithAttributes). The instructions for installing the module are provided from the README file on the repo.
10+
11+
The example module extends the Heading content type because we wanted to focus on learning about attributes instead of sifting through the the additional code that comes with creating a new custom content type.
12+
13+
The following screenshot shows what the Heading content type form looks like after installing the example module. Specifically, you should see three new Heading fields: `Heading Colors`, `Heading Styles`, and `Heading Opacity`.
14+
15+
![How to add an appearance](../images/heading-extension-using-attributes-and-style.png)
16+
17+
_Extended Heading form with color and text style options using attributes_
18+
19+
The example module provides all the code used here to describe the attribute-based styling. It also provides some "bonus code" that shows how to use a `<style>` node to give users an option for setting Heading text opacity. But wait, that's not all! We also added a custom converter for the opacity style to ensure that users can enter the opacity as a percentage.
20+
21+
## Steps for styling with attributes
22+
23+
This general steps to follow when using attributes to apply CSS styling are shown here, followed by detailed instructions for each step:
24+
25+
![How to style content types using attributes](../images/how-to-style-using-attributes.svg)
26+
27+
_Steps for styling content type elements with attributes_
28+
29+
## Step 1: Add fields for user input
30+
31+
First, you need to add fields to your content type's form so that users have a way of selecting or entering styling options. In our Heading extension example, we add two fields: `heading_color` for selecting a color for the Heading text and `heading_style` for selecting text styles. The XML code for these fields is shown here:
32+
33+
```xml
34+
<!-- pagebuilder_heading_form.xml form extension -->
35+
36+
<?xml version="1.0" encoding="UTF-8"?>
37+
<form xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
38+
<fieldset name="general">
39+
<field name="heading_color" sortOrder="25" formElement="select" component="Magento_PageBuilder/js/form/element/visual-select">
40+
<argument name="data" xsi:type="array">
41+
<item name="config" xsi:type="array">
42+
<item name="default" xsi:type="string">brand-black</item>
43+
</item>
44+
</argument>
45+
<settings>
46+
<dataType>text</dataType>
47+
<label translate="true">Heading Colors</label>
48+
<elementTmpl>Magento_PageBuilder/form/element/visual-select</elementTmpl>
49+
<notice translate="true">Select from one of the approved Acme brand colors.</notice>
50+
</settings>
51+
<formElements>
52+
<select>
53+
<settings>
54+
<options class="BrandColorSource"/>
55+
</settings>
56+
</select>
57+
</formElements>
58+
</field>
59+
<field name="heading_style" sortOrder="26" formElement="select" component="Magento_PageBuilder/js/form/element/visual-select">
60+
<argument name="data" xsi:type="array">
61+
<item name="config" xsi:type="array">
62+
<item name="default" xsi:type="string">style-default</item>
63+
</item>
64+
</argument>
65+
<settings>
66+
<dataType>text</dataType>
67+
<label translate="true">Heading Styles</label>
68+
<elementTmpl>Magento_PageBuilder/form/element/visual-select</elementTmpl>
69+
</settings>
70+
<formElements>
71+
<select>
72+
<settings>
73+
<options class="TextStyleSource"/>
74+
</settings>
75+
</select>
76+
</formElements>
77+
</field>
78+
</fieldset>
79+
</form>
80+
```
81+
82+
The names of these fields (`heading_color` and `heading_style`) are particularly important because you will use them as the names of your attributes in your content type configuration file in step 2.
83+
84+
_Select fields added to the native Heading form_
85+
86+
## Step 2: Add configuration attributes for field names
87+
88+
Attributes have a `name` and a `source`. The `name` must correspond to the name of the input field in the form. The `source` defines the attribute name that is added to the DOM for targeting your CSS classes. In our Heading extension, we added two `<attributes>` with names corresponding to the previously defined Heading fields (`heading_color` and `heading_style`). The XML code for these attributes is shown here:
89+
90+
```xml
91+
<!-- heading.xml config extension -->
92+
93+
<?xml version="1.0"?>
94+
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_PageBuilder:etc/content_type.xsd">
95+
<type name="heading">
96+
<appearances>
97+
<appearance name="default">
98+
<elements>
99+
<element name="main">
100+
<attribute name="heading_color" source="data-heading-color"/>
101+
<attribute name="heading_style" source="data-heading-style"/>
102+
</element>
103+
</elements>
104+
</appearance>
105+
</appearances>
106+
</type>
107+
</config>
108+
```
109+
110+
_Element attributes for main mapped to the extended Heading form fields_
111+
112+
In this example, the `source` values (`data-heading-color` and `data-heading-style`) are rendered in the DOM for the Heading's main element, as shown here:
113+
114+
```html
115+
<h2 data-content-type="heading" data-appearance="default" data-heading-color="brand-green" data-heading-style="style-italic" data-element="main" style="border-style: none; border-width: 1px; border-radius: 0px; opacity: 1;">My Heading Text</h2>
116+
```
117+
118+
The values for these attributes are set by the user from the form fields. In this example, the user selected `brand-green` from the `heading_color` selector field and `style-italic` from the `heading_style` selector field. This adds the attributes and their values to the DOM where they can be targeted with CSS classes from our content type's `_default.less` files (from the adminhtml and frontend areas). These classes are created in step 3.
119+
120+
## Step 3: Add attribute-based CSS classes
121+
122+
The CSS styles in your `_default.less` files for both your `adminhtml` and `frontend` areas of your module should be attribute-based as shown here in our extended Heading example:
123+
124+
```scss
125+
/*-- adminhtml _default.less attribute-based classes */
126+
/*-- the frontend _default.less is the same, but without the .pagebuilder-stage wrapper */
127+
128+
& when (@media-common = true) {
129+
// Heading Colors
130+
.pagebuilder-stage {
131+
[data-heading-color='brand-black'] {
132+
color: #333333;
133+
}
134+
[data-heading-color='brand-blue'] {
135+
color: #007ab9;
136+
}
137+
[data-heading-color='brand-green'] {
138+
color: #009900;
139+
}
140+
[data-heading-color='brand-red'] {
141+
color: #990000;
142+
}
143+
[data-heading-color='brand-purple'] {
144+
color: #990099;
145+
}
146+
}
147+
// Heading Styles
148+
[data-heading-style='style-default'] {
149+
font-weight: normal;
150+
font-style: normal;
151+
}
152+
[data-heading-style='style-bold'] {
153+
font-weight: bold;
154+
}
155+
[data-heading-style='style-italic'] {
156+
font-style: italic;
157+
}
158+
[data-heading-style='style-quotes'] {
159+
&:before {
160+
content: '\201C';
161+
}
162+
&:after {
163+
content: '\201D';
164+
}
165+
}
166+
}
167+
```
168+
169+
_Attribute-based styles for the config attributes (source)_
170+
171+
Again, the values for these attributes are set by the user in the content type's form fields. This makes it easy to target your content type's elements in the DOM based on what the user selected in the form.
172+
173+
## Step 4: Add Knockout attribute bindings to HTML templates
174+
175+
In order for your attribute selectors to be rendered in the DOM as described in step 2, you must ensure that you add Knockout attributes to your content type's HTML templates. Knockout attribute bindings look like this:
176+
177+
```json
178+
attr="data.main.attributes"
179+
```
180+
181+
The `main` node refers to the element defined in the configuration file and `attributes` refer to all the `<attributes>` defined for the `main` element.
182+
183+
The Knockout `attr` binding ensures that all the attributes defined for an element in your content type's configuration are rendered in the DOM for that element as described in step 2.
184+
185+
These Knockout bindings are applied to the Heading's `master.html` template (as well as the `preview.html` template) as shown here:
186+
187+
```html
188+
<!-- Heading master.html -->
189+
190+
<h1 if="data.main.heading_type() == 'h1'" attr="data.main.attributes" ko-style="data.main.style" css="data.main.css" html="data.main.html"></h1>
191+
<h2 if="data.main.heading_type() == 'h2'" attr="data.main.attributes" ko-style="data.main.style" css="data.main.css" html="data.main.html"></h2>
192+
<h3 if="data.main.heading_type() == 'h3'" attr="data.main.attributes" ko-style="data.main.style" css="data.main.css" html="data.main.html"></h3>
193+
<h4 if="data.main.heading_type() == 'h4'" attr="data.main.attributes" ko-style="data.main.style" css="data.main.css" html="data.main.html"></h4>
194+
<h5 if="data.main.heading_type() == 'h5'" attr="data.main.attributes" ko-style="data.main.style" css="data.main.css" html="data.main.html"></h5>
195+
<h6 if="data.main.heading_type() == 'h6'" attr="data.main.attributes" ko-style="data.main.style" css="data.main.css" html="data.main.html"></h6>
196+
```
197+
198+
_Attribute bindings for Heading's data.main config element_
199+
200+
## Discussion
201+
202+
Page Builder provides three XML configuration nodes you can use to to provide users with styling options for content type elements:
203+
204+
- `<attribute>` - styles a content type element using an attribute-based CSS class.
205+
- `<style>` - styles content type elements using specific CSS properties.
206+
- `<css>` - styles content types using one or more static CSS classes.
207+
208+
The `<attribute>` and `<style>` nodes can be used multiple times within a content type element. But the `<css>` node can only be used once per element. The `<css>` node was designed to be used only once per element because its purpose is to map user-entered CSS classes from the form to the template, where it adds those classes to the `class` attribute in the DOM.
209+
210+
The following code snippet is from Page Builder's native `heading.xml` configuration file (Magento/PageBuilder/view/adminhtml/pagebuilder/content_type/heading.xml), showing multiple `<style>` nodes, two `<attribute>` nodes and one `<css>` node for the `main` element:
211+
212+
```xml
213+
<!-- snippet from heading.xml -->
214+
215+
<element name="main">
216+
<style name="text_align" source="text_align"/>
217+
<style name="border" source="border_style" converter="Magento_PageBuilder/js/converter/style/border-style"/>
218+
<style name="border_color" source="border_color"/>
219+
<style name="border_width" source="border_width" converter="Magento_PageBuilder/js/converter/style/border-width"/>
220+
<style name="border_radius" source="border_radius" converter="Magento_PageBuilder/js/converter/style/remove-px"/>
221+
<style name="display" source="display" converter="Magento_PageBuilder/js/converter/style/display" preview_converter="Magento_PageBuilder/js/converter/style/preview/display"/>
222+
<style name="margins" storage_key="margins_and_padding" reader="Magento_PageBuilder/js/property/margins" converter="Magento_PageBuilder/js/converter/style/margins"/>
223+
<style name="padding" storage_key="margins_and_padding" reader="Magento_PageBuilder/js/property/paddings" converter="Magento_PageBuilder/js/converter/style/paddings"/>
224+
<attribute name="name" source="data-content-type"/>
225+
<attribute name="appearance" source="data-appearance"/>
226+
<tag name="heading_type"/>
227+
<html name="heading_text" converter="Magento_PageBuilder/js/converter/html/tag-escaper"/>
228+
<css name="css_classes"/>
229+
</element>
230+
```
231+
232+
### `<style>` nodes
233+
234+
The `<style>` nodes map to the same-named fields defined in the `pagebuilder_base_form.xml`. These nodes define the inline `style` properties added to the Heading's DOM element. Adding a `<style>` node to a config element provides a way to style your content type using a specific CSS property (such as `opacity`) from within the content type's form.
235+
236+
### `<attribute>` nodes
237+
238+
The `<attribute>` nodes map to the same-named fields defined in the `pagebuilder_heading_form.xml`. These nodes define the custom attributes added to the Heading's DOM element. Adding an `<attribute>` node to a config element provides a way to style your content type using attribute-based CSS classes from within the content type's form.
239+
240+
### `<css>` nodes
241+
242+
The `<css>` node maps to the `css_classes` field from the `pagebuilder_base_form.xml` and adds its values (CSS classes) to the `class` attribute of the Heading's DOM element (h1 through h6).
243+
244+
{: .bs-callout .bs-callout-info }
245+
The `<tag>` and `<html>` nodes are beyond the scope of this topic, but they map to the Heading's `heading_type` selector field and `heading_text` input field from the (`pagebuilder_heading_form.xml`) form.
246+
247+
## Final thoughts
248+
249+
Using custom attributes represents one of Page Builder's best practices for adding powerful content styling options to forms. You can add attributes to both existing content types (as shown with the Heading extension) and custom content types. The CSS styling options are only limited by the CSS specs your targeted browsers support. Have fun!
Loading
Loading

0 commit comments

Comments
 (0)