Widgets

Contents...

A widget is an element of the Webasyst dashboard used for displaying some visual content within a limited rectangle area. A user may add several instances of any widget to their dashboard and select individual settings for each instance if provided by a particular widget.

Widget dimensions

The widget-displaying area may be selectable by a user and can have one of the following dimension options: 2х2, 2х1, 1х1. The dimension options supported by a widget are specified in its main configuration file. Default dimensions 2х2 must be supported by all widgets.

Depending on a current screen resolution and a device type, the actual size of a 1х1 widget can vary from 160х160px to 240х240px. Thus, the greater dimension of a 2х1 or 2х2 sized widget may be as large as 480px.

Two widget types

A widget can be developed for a particular app (an app widget) or may not be associated with any app (a system widget).

System widgets can be added to the dashboard by any Webasyst users. App widgets are available only to the users who have access to the corresponding apps, with a user’s access rights taken into account.

System widgets are stored in the wa-widgets/ directory. App widgets are stored inside their appropriate apps’ directories wa-apps/[app_id]/widgets/.

Widget’s file structure

The file structure of a widget is similar to that of an app or a plugin:

wa-apps/[app_id]/widgets/[widget_id]/ or wa-widgets/[widget_id]/ (file structure of both widget types is identical).

Symbol is shown for the directories which must be protected from direct file access by means of the Deny from all directory in the .htaccess file.

Required widget files:

  • Main configuration file lib/config/widget.php containing widget’s name (name), its selectable dimension options (size), and the path to widget’s icon file (img).
  • Main PHP class lib/***.widget.php containing widget’s operation logic. For system widgets, the file name must match pattern [widget_id].widget.php (with the class name like [widget_id]Widget). For app widgets it must match pattern [app_id][Widget_id].widget.php (with class name like [app_id][Widget_id]Widget). Widget’s main PHP class must extend system class waWidget.

Example of configuration file widget.php:

<?php

return [
    'name' => 'My widget',
    ’size' => ['2x2', '2x1', '1x1'],
    'img'  => 'img/my.png'
];

Example of main widget class:

<?php

class myWidget extends waWidget
{
    //Main widget class containing its operation logic
    public function defaultAction()
    {
        //Retrieving all widget settings values
        $settings = $this->getSettings();
        //or the value of only one settings field
        $some_setting = $this->getSettings(’some_setting');

        //Use method display() to assign values to HTML template variables
        $this->display([
            'var1' => $value1,
            'var2' => $value2,
            //...
        ]);
    }
}

Widget settings: settings.php

A widget may offer a set of settings fields to a user, which will be applied to the current widget instance added to the dashboard. In other words, each widget instance can have its own settings values. To make settings available to a user, create file lib/config/settings.php with the list of all settings fields. Webasyst will automatically generate the settings screen and will ensure correct saving of all entered or selected values. The requirements to the content of the widget settings configuration file are identical to those described for plugin settings files.

The values of settings fields for the current widget instance can be obtained in the widget’s PHP class using method getSettings().

Example of widget settings configuration file:

<?php
return [
    'unit' => [
        'title' => /*_wp*/('Degrees'),
        'control_type' => waHtmlControl::RADIOGROUP,
        'options'      => [
            'C' => /*_wp*/('Celsius'),
            'F' => /*_wp*/('Fahrenheit'),
        ],
        'value' => 'C',
    ],
    'city' => [
        'title' => /*_wp*/('City'),
        'control_type' => waHtmlControl::INPUT,
        'placeholder' => $city
    ],
    ’source' => [
        'value'        => '',
        'title'        => /*_wp*/('Weather source'),
        'description'  => '',
        'control_type' => waHtmlControl::RADIOGROUP,
        'options'      => [
            /* see Webasyst stock News widget for example of custom setting option list: /wa-widgets/news/lib/news.widget.php > getSettingsConfig() method */
        ],
    ],
];

HTML templates

By default, widget contents are displayed using template file templates/Default.html.

Localization

Widget localization is implemented in the same way as app localization. Translation files *.po and *.mo must be located in the /locale/ directory. Translation file names: for app widgets — [app_id]_widget_[widget_id>].*, for system widgets — widget_[widget_id].*. Below is shown how localization keys must be used in widget source files:

  • _w(’string') — in PHP files
  • [`string`] — in Smarty templates

Widget name specified in the name element in configuration file widget.php is translated automatically. It is not required to call function _w() in that file, simply specify the localization key as shown in this example:

'name' => 'My widget',

Automatic content update

If a widget is supposed to periodically update its content with user input, i.e. without the need to refresh a browser page or any other interaction with the widget, then the widget developer must ensure such auto update in the widget’s source code.

Common JavaScript controller

Remember that a user may add any number of widget’s instances to a dashboard.

In some cases several widget instances may be powered by one common controller; e.g., in the Clock widget (its source code is available on GitHub).

When developing a widget and a similar common controller for all its instances, be sure to think well about its auto-start functionality. Especially if the controller is supposed to be called periodically.

It is essential to ensure that your widget keeps working correctly after the dashboard switchover. Every account administrator has the option to switch from the personal dashboard editing mode to the static dashboard editing mode intended for display on a TV screen). In this case JavaScript storages containing all controllers (DashboardControllers) and widgets (DashboardWidgets) are flushed. You must properly handle this situation to prevent a widget from re-launching itself after it has been deleted.

Design

Simple yet informative design is the most difficult part of the widget development.

Recommendations

  • Less means better. A widget must solve only one relatively simple problem and should not attempt to show too much information at once.
  • One key element. If a widget is supposed to display several key metrics, it is recommended to display only one of them per widget instance. Should you need to display several metrics at once, visually emphasize their hierarchy and importance. If a widget supports the display of several equally important metrics then we recommend that a metric selection is made available in the widget settings so that a user can add multiple widget instances to a dashboard, each with its own data displayed.
  • Variable width and height. With different dimension options (2х2, 2х1, 1х1), a widget may appear differently and thus display or hide some of its visual content depending on the selected size.
  • Padding only for text. Text content should be placed inside a container with CSS class block to ensure correct padding from widget borders. Graphical content; e.g., color background, images, charts, maps, videos, etc., shouldbe displayed without padding.
  • No scrolling. Scrolling is disabled for all widgets’ content to ensure correct scrolling of the entire dashboard page.
  • Neighbor widgets. A widget must be harmonically displayed among other widgets and should not attempt to influence the way they operate. Test your own widget with other widgets also added to a dashboard.
  • 2x2. This is the required dimension option which must be supported by a widget and which is auto-selected when a widget has just been added to a dashboard.

Widget template markup

Use basic HTML tags h1, h2, h3, and Webasyst framework’s CSS tools. The visual appearance of these basic elements inside widgets has been adapted to be correctly displayed by widget instances with different dimension options: 2х2, 2х1, 1х1.

Depending on the selected dimension option, widget content is wrapped in a container with one of the following CSS classes: .widget-2x2, .widget-2x1, .widget-1x1.

If a widget has several auxiliary displaying classes, we recommend specifying them as inline styles directly in template file Default.html inside <style> ... </style> tag.

TV mode /?tv

Each widget must correctly appear both on light and on dark background.

Light background is used for the user’s personal dashboard (on the backend home page); dark background is used for static dashboards intended for displaying on a TV screen.

For testing purposes, add your widget to a dashboard and open the dashboard in a browser at a URL like https://www.yourdomain.com/webasyst/?tv. You will see in the dark TV mode.

In the TV mode, CSS class tv is applied to the body element, which allows specifying individual CSS rules for each of the two modes (normal and TV).

Widget template samples

Below are shown several typical template examples, which you can use to create your own widgets. Copy the provided code snippets to file Default.html of your widget. All these snippets have been adapted to and tested with all available dimension options: 2х2, 2х1, 1х1.

Text widget

<div class="block">
    <h6 class="heading">[`Top science`]</h6>
    <h4>New species of ancient human discovered</h4>
    <p>A huge haul of bones found in a small, dark chamber at the back of a cave in South Africa may be the remnants of a new species of ancient human relative. Explorers discovered the bones after squeezing through a fissure high in the rear wall of the Rising Star cave, 50km from Johannesburg, before descending down a long, narrow chute to the chamber floor 40 metres beneath the surface. </p>
</div>

A metric and its change dynamics

<div style="width: 100%; height: 100%; position: absolute;">
    <!-- some nice background graph here -->
</div>
<div class="block top-padded align-center" style="position: relative;">
    <h6 class="heading">[`KPI name`]</h6>
    <h1>100K</h1>
    <h4 style="color: green;">+10%</h4>
</div>

Multiple metrics

<div class="block align-center">
    <h6 class="heading">{sprintf_wp('Snow in %s', 'La Grave')}</h6>
    <h2 style="color: #49a2e0; margin: 5px 0;">+42 cm</h2>
    <h5 style="color: #49a2e0; text-transform: uppercase;">[`Powder day!`]</h5>
</div>

<div class="align-center">
    <div style="width: 40%; display: inline-block;">
        <span class="hint nowrap uppercase">[`Min °C`]</span>
        <h5 class="gray nowrap">–8</h5>
    </div>
    <div style="width: 40%; display: inline-block;">
        <span class="hint nowrap uppercase">[`Wind`]</span>
        <h5 class="gray nowrap">15 NW</h5>
    </div>
</div>

Table

<style>
    .w-sochi-table .medal-icon { font-size: 3em; line-height: 0; padding-bottom: 10px; }
    .w-sochi-table .country-name { padding-left: 10px; }
</style>
<div class="block">
    <h6 class="heading">[`Sochi 2014 table`]</h6>
</div>
<table class="zebra w-sochi-table">
    <tr class="white">
        <td></td>
        <td class="medal-icon" style="color: gold;">•</td>
        <td class="medal-icon" style="color: silver;">•</td>
        <td class="medal-icon" style="color: #cc9966;">•</td>
    </tr>
    <tr>
        <td class="country-name">Russia</td>
        <td class="min-width align-center bold">13</td>
        <td class="min-width align-center">11</td>
        <td class="min-width align-center">9</td>
    </tr>
    <tr>
        <td class="country-name">Norway</td>
        <td class="min-width align-center bold">11</td>
        <td class="min-width align-center">5</td>
        <td class="min-width align-center">10</td>
    </tr>
    <tr>
        <td class="country-name">Canada</td>
        <td class="min-width align-center bold">10</td>
        <td class="min-width align-center">10</td>
        <td class="min-width align-center">5</td>
    </tr>
    <tr>
        <td class="country-name">USA</td>
        <td class="min-width align-center bold">9</td>
        <td class="min-width align-center">7</td>
        <td class="min-width align-center">12</td>
    </tr>
</table>

Media widget

<div style="width: 100%; height: 100%;">
    <!-- easily embed video streams, photos, slideshows -->
    <video autoplay muted loop height="100%">
        <source src="//player.vimeo.com/external/123062208.sd.mp4?s=ddb28ce90de1b7e072d0122d77c02583" type="video/mp4">
    </video>
</div>

Widget examples

Before developing your own widget, look at all the widgets developed by Webasyst: weather, clock, sales, and others.