Виджеты

Содержание...

Виджет — это элемент панели управления Webasyst, отображающий некоторую полезную информацию в пределах небольшой прямоугольной области. На панель управления пользователь может добавить несколько экземпляров любого виджета и задать для каждого экземпляра свой набор настроек (список настроек предоставляет виджет).

Размеры виджета

Прямоугольная область виджета определяется на усмотрение пользователя и может быть одной из трех следующих вариантов — 2х2, 2х1 и 1х1. Варианты, поддерживаемые виджетом, перечисляются в его конфигурационном файле. Размер по умолчанию — 2х2, его поддержка виджетом обязательна.

В зависимости от разрешения экрана и типа устройства физический размер блока виджета 1х1 может быть от 160х160 до 240х240 пикселей по горизонтали и по вертикали, следовательно, большее ребро размеров 2х1 и 2х2 может достигать 480 пикселей.

Два типа виджетов

Виджет может быть разработан для конкретного приложения (виджет приложения) или же быть не привязанным ни к какому приложению (системный виджет).

Возможность добавления на панель управления системных виджетов есть у всех пользователей бекенда Вебасиста. Доступ к виджетам приложения — только у пользователей, у которых есть доступ к самому приложению (плюс дополнительно каждый виджет может проверять права доступа внутри своего приложения и отображать либо скрывать нужную информацию).

Системные виджеты размещаются в директории wa-widgets/. Виджеты приложений размещаются в директориях wa-apps/[app_id]/widgets/.

Файловая структура виджета

Файловая структура виджета схожа с файловой структурой приложения или плагина:

wa-apps/[APP_ID]/widgets/[WIDGET]/ или wa-widgets/[WIDGET]/ (файловая структура для обоих типов виджетов одинаковая).

Замочком помечены подкаталоги, которые рекомендуется закрыть с помощью директивы Deny from all в файле .htaccess.

Обязательные файлы виджета:

Пример конфигурационного файла widget.php:

<?php

return array(
    'name' => 'My widget',
    'size' => array('2x2', '2x1', '1x1'),
    'img'  => 'img/my.png'
);

Пример основного класса виджета:

<?php

class myWidget extends waWidget
{
    // Основной метод класса, определяющий логику работы виджета
    public function defaultAction()
    {
        //Получаем значения всех настроек виджета
        $settings = $this->getSettings();
        //или значение только одного поля
        $some_setting = $this->getSettings('some_setting');
        
        //Используйте вызов метода display() для присвоения значений переменным HTML-шаблона
        $this->display(array(
            'var1' => $value1,
            'var2' => $value2,
            //...
        ));       
    }
}

Настройки виджета — settings.php

Виджет может предоставлять пользователю некоторый набор настроек, которые будут применяться к каждому отдельному экземпляру виджета, добавленному на панель управления (другими словами, каждый экземпляр может иметь свои собственные настройки). Для объявления настроек виджета достаточно создать файл lib/config/settings.php и перечислить в нем список настроек и интерфейсов их редактирования — Webasyst автоматически покажет форму настроек и обеспечит сохранение данных формы. Правила формирования этого файла аналогичны тем, которые описаны для файлов настроек плагинов.

Содержимое полей настроек в основном PHP-классе виджета можно получать с помощью метода класса getSettings().

Пример файла настроек виджета:

<?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/Default.html.

Локализация

Локализация виджетов реализуется аналогично локализации приложений. Файлы переводов *.po и *.mo следует разместить в папке /locale/. Имена файлов переводов: для виджетов приложений — [APP_ID]_widget_[WIDGET].*, для системных виджетов — widget_[WIDGET].*. Подключать ключи в коде и в шаблонах необходимо следующим образом:

Название виджета (элемент name в конфигурационном файле widget.php) переводится автоматически — использовать в файле вызов функции _w() не нужно — достаточно просто указать ключ строки локализации, как показано в примере:

'name' => 'My widget',

Автообновление

Если функциональность виджета предполагает автоматическое обновление содержимого без участия пользователя (без обновления страницы панели управления и какого-либо взаимодействия с виджетом), разработчик виджета должен сам позаботиться об этом.

Общий JavaScript-контроллер

При разработке виджета необходимо учитывать, что пользователь может разместить сколько угодно экземпляров виджета на свою приборную панель.

Бывают сложные конструкции виджетов, когда несколько экземпляров виджета управляются единым контроллером, например, как в виджете «Часы» (исходный код виджета опубликован на Гитхабе).

При разработке подобного виджета и контроллера к нему следует продумать момент автозапуска, особенно если контроллер вызывается циклично.

Проблемное место: следует учитывать возможность переключения панели управления (у каждого администратора аккаунта есть возможность переключения режима редактирования персональной панели управления на режим редактирования статической панели управления для отображения на ТВ). В этом случае будут очищены JavaScript-хранилища, в которых хранятся все контроллеры (DashboardControllers) и виджеты (DashboardWidgets). Нужно предусмотреть ситуацию, чтобы контроллер не пытался запускать сам себя, если его удалили.

Дизайн

Простой но содержательный дизайн — самая сложная часть разработки виджета.

Рекомендации по разработке дизайна виджета:

Верстка шаблона виджета

Используйте базовые HTML-теги h1, h2, h3 и CSS-инструментарий фреймворка. Внешний вид для этих базовых элементов внутри виджетов адаптирован таким образом, чтобы целостно смотреться для виджетов разного размера: 2х2, 2х1, 1х1.

В зависимости от размера виджет «оборачивается» в классы .widget-2x2, .widget-2x1, .widget-1x1.

Если у виджета всего несколько дополнительных классов для отображения, рекомендуется оформлять их как inline-стили непосредственно в шаблоне Default.html внутри <style> ... </style>.

Телевизионный режим — /?tv New!

Каждый виджет должен поддерживать отображение и на светлом, и на темном фоне.

Светлый фон используется при отображении персональной панели управления пользователя (главной странице бекенда), темный — для статических панелей управления, предназначенных для отображения на телевизоре.

Добавьте ваш виджет на панель управления и откройте панель управления по адресу http://www.YOURDOMAIN.ru/webasyst/?tv — вы увидите панель управления в телевизионном «темном режиме».

В телевизионном режиме на тег body добавляется класс <body class="tv">, что позволяет определить индивидуальное отображение (CSS) виджета для каждого режима отдельно.

Заготовки шаблонов для виджетов

Несколько типовых заготовок, которые вы можете использовать для создания собственных виджетов. Скопируйте предложенные варианты кода в шаблон Default.html вашего виджета. Все приведенные примеры автоматически адаптированы для всех вариантов размеров виджетов 2х2, 2х1, 1х1.

Текстовый виджет

<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>

Метрика и динамика ее изменения

<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>

Несколько метрик

<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>

Таблица

<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>

Медиа-виджет

<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>

Примеры виджетов

В качестве примера виджетов рекомендуем рассмотреть все виджеты разработки Webasyst: курсы валют, погоду, часы, пробки и многие другие.