Migrate an existing design to the new build
This chapter provides a short migration guide to the conversion of an existing design for CX version 1.3 or lower to the new design build. For basic information on the new design build, please consider the corresponding Wiki page on GitHub.
As a first step of the migration, it is required to set up the project structure. It’s recommended that you start with the Scaffold Design instead of creating the structure all by yourself. Also consider reading this chapter before you start with the migration.
Content Elements
Now you can start the migration by transforming the content elements. This step will be explained on an example:
<div class="content-element image-wrapper" data-bsi-element="image">
<div class="row">
<div class="flex">
<div class="element">
<div class="image">
<img data-bsi-element-part="image" src="{{ src ?: baseUrl|raw ~ "/img/placeholder.jpg" }}" alt="" />
</div>
<div class="image-legend" data-bsi-element-part="plain-text">{{ legend ?: "Lorem ipsum image description" }}</div>
</div>
</div>
</div>
</div>
element.image.label=Image
element.image.description=with description
element.image.icon=image
element.image.parts.image.label=Image
element.image.parts.plain-text.label=Description
The content elements are usually organized in Twig files inside a content-elements folder.
While the corresponding properties are placed in a single design.properties file.
In the new build process, it’s recommended to keep it all together in a single folder and separated from any other content element.
So take a look on the existing content elements from the scaffold design.
They are all nicely organized in separate folders.
So create a new folder for your own element:
.
└───image
index.js (1)
placeholder.jpg (2)
template.twig (3)
styles.less (4)
| 1 | This file will contain the content element specification. |
| 2 | Feel free to place any content element related assets here. |
| 3 | The Twig template for our content element. |
| 4 | Any content element related Stylesheets. This can also be a LESS or SASS file. |
Create the index.js and template.twig files inside this folder and feel free to add any related assets too.
In our example, we add the placeholder.jpg here.
Now we can create the template.twig:
<div class="content-element image-wrapper" data-bsi-element="image">
<div class="row">
<div class="flex">
<div class="element">
<div class="image">
<img data-bsi-element-part="image" src="{{ url ?: bsi_cx_asset('./placeholder.jpg') }}" alt="" />
</div>
<div class="image-legend" data-bsi-element-part="plain-text">{{ legend ?: "Lorem ipsum image description" }}</div>
</div>
</div>
</div>
</div>
index.js file.require('./styles.less'); (1)
const {cx, Icon} = require('@bsi-cx/design-build'); (2)
module.exports = cx.contentElement
.withElementId('image')
.withLabel('Image')
.withDescription('with description')
.withIcon(Icon.IMAGE)
.withFile(require('./template.twig'))
.withParts(
cx.part.image
.withLabel('Image'),
cx.part.plainText
.withLabel('Description'));
| 1 | Include any related stylesheets right at the beginning of your content element specification. |
| 2 | Be sure you use require() instead of import. |
| Be aware, that there are some advanced features available with the new design build. For example referenced content element parts, which can be useful in complex content elements. |
Once you have finished creating your content element, you can include them in your design specification.
The design specification is contained in the design.js file and replaces the design.properties.
You find the design.js at the root folder of your template.
require('./styles/styles.scss'); (1)
const {cx, Design} = require('@bsi-cx/design-build');
/**
* @type {Design}
*/
module.exports = cx.design
.withTitle('BSI - Landingpage') (2)
.withAuthor('BSI Business Systems Integration AG') (3)
.withDate('14.04.2022')
.withContentElementGroups(
cx.contentElementGroup
.withGroupId('content')
.withLabel('Content')
.withContentElements(
require('./content-elements/content/image'), (4)
require('./content-elements/content/text')));
| 1 | You can also include global stylesheets (CSS, LESS or SASS) here. |
| 2 | Title of this template, corresponds to the template.name from the design.properties file. |
| 3 | The author of this template, corresponds to the template.author from the design.properties file. |
| 4 | This is our transformed content element.
The path points to the folder.
Since it contains an index.js, it’s not required to mention the filename here. |
Styles
If your content element uses any [styles], you must transform them to a Java Script styles definition:
design.properties format.style.element-width.label=Element width
style.element-width.class.element-with-unset.label=None
style.element-width.class.element-width-full.label=Full
style.element-width.class.element-width-left-right.label=Label left, field right
The transformation to the new format is pretty straightforward:
const {cx} = require('@bsi-cx/design-build');
module.exports = cx.style
.withIdentifier('element-width')
.withLabel('Element width')
.withCssClasses(
cx.cssClass
.withLabel('None')
.withCssClass('element-with-unset'),
cx.cssClass
.withLabel('Full')
.withCssClass('element-width-full'),
cx.cssClass
.withLabel('Label left, field right')
.withCssClass('element-width-left-right'));
It’s recommended to place the style definition in a separate Java Script file.
If your style is exclusively for one element, you can place the file right next to the element definition.
Otherwise, you should put it in the configs/styles folder inside your template root.
To use a style in your content element, simply reference the file:
const {cx, Icon} = require('@bsi-cx/design-build');
module.exports = cx.contentElement
.withElementId('image')
.withLabel('Image')
.withDescription('with description')
.withIcon(Icon.IMAGE)
.withFile(require('./template.twig'))
.withStyleConfigs(require('../../../configs/styles/fade-out')) (1)
.withParts(
cx.part.image
.withLabel('Image'),
cx.part.plainText
.withLabel('Description'));
| 1 | Just pass the style definition to the builder using withStyleConfigs() and require(). |
Design and Preview Templates
To bundle your design and preview templates, create a new preview.twig and design.twig file inside the template root folder.
To prevent code duplication, it’s recommended to create a _layout.twig template and extend it in your design.twig and preview.twig.
Take a look at the following example:
_layout.twig template.<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<title>{{ properties.title }}</title>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<link rel="stylesheet" href="{{ bsi_cx_css_href() }}"/> (1)
</head>
<body class="d-flex flex-column min-vh-100">
{% apply spaceless %}
<header id="header" data-bsi-dropzone="header">
{% block header %}{% endblock %}
</header>
<main id="content" data-bsi-dropzone="content">
{% block content %}{% endblock %}
</main>
<footer id="footer" data-bsi-dropzone="footer">
{% block footer %}{% endblock %}
</footer>
{% endapply %}
<script src="{{ bsi_cx_js_module_runtime_href() }}" data-bsi-remove-if="draft" defer="defer"></script> (2)
<script src="{{ bsi_cx_js_module_href('main') }}" data-bsi-remove-if="draft" defer="defer"></script> (3)
{{ bsi_cx_js_module_missing_chunks_import() }} (4)
</body>
</html>
| 1 | Use the bsi_cx_css_href() Twig helper to include your stylesheets.
More options can be found here. |
| 2 | You can skip this line if you don’t have any Java Script modules configured. |
| 3 | Use the bsi_cx_js_module_href() Twig helper to include a Java Script module.
You can skip this line if you don’t have any Java Script modules configured. |
| 4 | This imports all missing chunks, related to Java Script modules. You can skip this line if you don’t have any Java Script modules configured. More information on including Java Script in your design can be found here. |
Now you can extend the blocks from the _layout.twig in your design.twig and preview.twig.
The following example illustrates this step for the design.twig:
design.twig extends the _layout.twig.{% extends '_layout.twig' %}
{% block header %}
{% include './content-elements/header/banner/template.twig' %}
{% endblock %}
{% block content %}
{% include './content-elements/content/title-h1/template.twig' %}
{% include './content-elements/content/text/template.twig' %}
{% endblock %}
{% block footer %}
{% include './content-elements/footer/two-col/template.twig' %}
{% endblock %}
Java Script
You have two options to include your Java Script code:
-
Place them in the
staticfolder inside your templates root and include them withbsi_cx_asset(). -
Create a module in the
modulesfolder and take full advantage of all modern Java Script.
Stylesheets
Your global can place your global stylesheets directly in the styles folder, located at your template root.
You can also place any content element specific styles here instead of moving them to the specific content element’s own folder.
To bundle your stylesheets, you must reference them in your design.js:
require('./styles/styles.scss');
Properties
The new design build uses Java Script files instead of YAML.
The properties.js file is a CommonJS module, that exports a simple Java Script object {}.
Feel free to organize your properties as you wish.
To access the properties inside your stylesheets and templates, you can use the bsiProperty() helper.
Take a look at the following example:
styles:
primary-color: '#ed4546'
secondary-color: '#efefef'
const {css} = require('@bsi-cx/design-build');
module.exports = {
styles: {
'primary-color': css.color('#ed4546'),
'secondary-color': css.color('#efefef')
}
};
Use the css helper to get the most out your properties.
More information on this feature can be found here.
|
{% set color = properties.styles['primary-color'] ?: '#ff00ff' %}
bsiProperty() helper inside your templates.@color: bsiProperty('styles.primary-color');
Build Configuration
In order to compile, it’s required to add your template to the build configuration in the webpack.config.js file at the project root folder.
webpack.config.js build configuration file.const path = require('path');
const {BuildConfig, ModuleConfig, WebpackConfigBuilder, Version, DesignType} = require('@bsi-cx/design-build');
module.exports = WebpackConfigBuilder.fromConfigs(
new BuildConfig()
.withName('landingpage') (1)
.withVersion('1.0.1-alpha') (2)
.withTargetVersion(Version.CX_1_3) (3)
.withDesignType(DesignType.LANDINGPAGE) (4)
.withRootPath(path.resolve(dirname, 'templates', 'landingpage')) (5)
.withPropertiesFilePath(path.resolve(dirname, 'properties.js')) (6)
.withModules(
new ModuleConfig() (7)
.withPath('main.js')
.withName('main')));
| 1 | The name of this template. |
| 2 | The current version of this template, optional but recommended. |
| 3 | The target BSI CX version. The build is capable of converting a design to the required format of various CX versions. |
| 4 | What type of design is your template? |
| 5 | The path to your template root folder. This is where your design.js is located. |
| 6 | The path to your properties.js file. |
| 7 | Configure your Java Script modules here. |