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 his dashboard and select individual settings for each instance as provided by the particular widget.

Widget dimensions

The widget-displaying area is 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 by the developer in its configuration file. Default dimensions 2х2 must be supported by all widgets.

Depending on the current screen resolution and the device type, the actual size of a 1х1 widget can vary from 160х160px to 240х240px. Thus, the longer side of a 2х1 or 2х2 sized widget may reach 480px.

Two widget types

A widget can be created for a particular application (app widget) or may not be connected to any application (system widget).

System widgets can be added to the dashboard by all Webasyst users. App widgets are available only to the users who have access to the corresponding apps. An app widget can additionally check current user's access rights level, and show or hide certain content depending on the result.

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

Widget file structure

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

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

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

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) displayed in the list of widgets available for adding to a user's dashboard.
  • Main PHP class lib/***.widget.php containing widget's operation logic. For system widgets, the file name must have the form [widget_id].widget.php (with class name of the form [widget_id]Widget). For app widgets it must have the form [app_id][Widget_id].widget.php (with class name [app_id][Widget_id]Widget). Widget's main PHP class must extend system class waWidget.

Example of configuration file widget.php:

<?php

return array(
    'name' => 'My widget',
    'size' => array('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(array(
            '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 array(
    'unit' => array(
        'title' => /*_wp*/('Degrees'),
        'control_type' => waHtmlControl::RADIOGROUP,
        'options'      => array(
            'C' => /*_wp*/('Celsius'),
            'F' => /*_wp*/('Fahrenheit'),
        ),
        'value' => 'C',
    ),
    'city' => array(
        'title' => /*_wp*/('City'),
        'control_type' => waHtmlControl::INPUT,
        'placeholder' => $city
    ),
    'source' => array(
        'value'        => '',
        'title'        => /*_wp*/('Weather source'),
        'description'  => '',
        'control_type' => waHtmlControl::RADIOGROUP,
        'options'      => array(
           /* 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 placed in directory /locale/. Translation file names: for app widgets — [APP_ID]_widget_[WIDGET].*, for system widgets — widget_[WIDGET].*. 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 the example below:

'name' => 'My widget',

Auto content update

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

Common JavaScript controller

Take into account that a user may add any number of your widget's instances to the dashboard.

In some complex cases several widget instances may be powered by one common controller; e.g., "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 important 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 for displaying on a TV). In this case JavaScript storages containing all controllers (DashboardControllers) and widgets (DashboardWidgets) are flushed. You must take this situation into account to prevent a widget from re-launching itself after it was 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 many information at once.
  • One key element. If a widget is intended for displaying several key metrics, it is recommended to display only one of those metrics per widget instance. Should you need to display several metrics at once, visually emphasize their hierarchy and importance. If a widget supports displaying of several equally important metrics, then we recommend that a metric selection is made available in widget settings screen so that a user can add multiple widget instances to the 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., must be displayed by a widget without padding at its borders.
  • No scrolling. Scrolling is disabled for all widgets' content to ensure correct scrolling for the entire dashboard.
  • Neighbor widgets. A widget must harmonically appear among other widgets and should not attempt to influence the way other widgets operate. Test your own widget with other widgets also added to the dashboard.
  • 2x2. This is the required dimension option which must be supported by a widget and which is auto-selected for a widget immediately upon adding to the dashboard.

Widget template markup

Use basic HTML tags h1, h2, h3, and Webasyst framework's CSS tools. The visual appearance of those 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 New!

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 the dashboard and open the dashboard in a browser at a URL of the form http://www.YOURDOMAIN.com/webasyst/?tv. You will see it appear 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 samples, which you can use to create your own widgets. Copy the provided code samples to file Default.html of your widget. All these snippets have been adapted to and tested with all 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('[`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.