Article Using LESS

Scripted customizations often output HTML content. When rendering CSS to help with the layout and styling of that content, Verint Community provides support for LESS, a processed extension to CSS.

What is LESS?

LESS is a set of extensions to cascading style sheets (CSS) that make defining styling metadata easier by introducing nesting, variables, functions, and more. LESS is processed by Verint Community and output as standard CSS to web clients (LESS is not natively understood by web browsers). Verint Community uses dotLess, which is a port of the less.js implementation of the LESS language.

Nesting

In CSS, context-specific style rules are defined as:

.content-fragment.my-widget .field-list .field-item .name { color: #333; }
.content-fragment.my-widget .field-list .field-item .input { color: #333; }

But with LESS, they can be nested to simplify the child selectors:

.content-fragment.my-widget .field-list .field-item {
    .name { color: #333; }
    .input { color: #333; }
}

Variables

In CSS, similar values often are repeated which makes updates difficult:

.content-fragment.my-widget .field-list .field-item .name { color: #333; }
.content-fragment.my-widget .field-list .field-item .input { color: #333; }

In LESS, these can be abstracted into a variable so the value can be set in a single location:

@foreground-color: #333;
.content-fragment.my-widget .field-list .field-item .name { color: @foreground-color; }
.content-fragment.my-widget .field-list .field-item .input { color: @foreground-color; }

Functions

Functions in LESS enable descriptive adjustments to style data:

@foreground-color: #33;
.content-fragment.my-widget .field-list .field-item {
    .name { color: lighten(@foreground-color, 10%); }
    .input { color: @foreground-color; }
}

LESS Language Documentation

For documentation on the LESS language, see:

How can I use LESS?

In Themes, LESS files included in the "Style Sheets" node under the theme in Theme Studio are automatically rendered. LESS files can be created as embedded files in any scriptable customization, however, and included in HTML output by using core_v2_widget.GetExecutedFileUrl('NAME_OF_LESS_FILE') and rendering it directly into a <link /> tag or by using the core_v2_page.AddLink() API, for example:

$core_v2_page.AddLink('stylesheet', $core_v2_widget.GetExecutedFileUrl('style.less'), "%{ Position = 'AfterTheme' }")

Because LESS is processed, it is important to use core_v2_widget.GetExecutedFileUrl() to resolve the LESS to standard CSS. 

LESS is a syntax-sensitive language. When errors occur while processing LESS, the error message will be returned as the content of the processed file, the message will be logged as an "Unknown" error in the exceptions log (Administration > Monitoring > Exceptions), and, for themes, errors are also sent as system notifications to administrators of the community.

Community LESS Functions

When using LESS, you can make use of the base LESS language features as well as Verint Community-specific functions that make integrating with community functionality easier. 

Theme Configuration Functions

Instead of defining local variables, it is often beneficial to define dynamic configuration options to end-users to adjust styling options. When defined by a theme, configuration options can be read within LESS files using functions prefixed with -evo-themeconfig, for example, -evo-themeconfig-color:

.content-fragment.my-widget {
    color: -evo-themeconfig-color('foregroundColor', '#000');
}

This would set the color of text in the widget to the color defined by the theme configuration property "foregroundColor". If "foregroundColor" was defined by the theme (or the data type was not color), the default color, #000, would be used.

Theme configuration, other than -evo-themeconfig-embeddedurl, can be read from all scriptable customizations, not just themes.

Theme Palette Functions

LESS files can make use of theme palettes to retrieve configured values for a specific palette type, paletted, and value ID using functions prefixed with -evo-themepalette.

Theme File Functions

LESS files within a theme can reference other embedded files within the theme using the -evo-themefile-url function. For example:

@import "-evo-themefile-url('supplementary.less')";

.my-style-rule {
    background-image: url(-evo-themefile-url('image.png'));
}

This would include and process the embedded file "supplementary.less" from the theme and set the background image of elements classified as "my-style-rule" to the URL of the "image.png" file embedded in the theme.

Note that the -evo-themefile-url function can only be used within a theme. Other scriptable customizations cannot use it within their embedded LESS files.

Widget Configuration Functions

Similar to theme configuration functions, widget configuration functions provide access to retrieve configuration data from the currently executing scripted customization. Widget configuration functions are prefixed -evo-widgetconfig.

When executing scripts within a theme, the -evo-widgetconfig-X and -evo-themeconfig-X functions will return the same results.

Widget File Functions

LESS files embedded within the currently executing scriptable customization can be referenced using the -evo-widgetfile-url function. For example,

@import "-evo-widgetfile-url('supplementary.less')";

.my-style-rule {
    background-image: url(-evo-widgetfile-url('image.png'));
}

This would include and process the embedded file "supplementary.less" from the current scripted customization and set the background image of elements classified as "my-style-rule" to the URL of the "image.png" file embedded in the scripted customization.

Widget Palette Functions

LESS files can make use of theme palette selections made by widget configuration options using functions prefixed with -evo-widgetpalette

Best Practices

  • Make use of configuration options and palette selections to expose styling customization to end users and use the Verint Community LESS functions to retrieve those values.
  • Apply generic styling (applying to multiple/all widgets) to Themes and any widget-specific styling should be defined within the widget that makes use of it. This keeps the widget markup and styling together and ensures easier upgrades.
  • If your LESS is complex, consider breaking it into multiple files with @import directives referencing the sub-components.