Виджеты

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

Универсальные виджеты

Виджеты очень похожи на Компоненты. Это такие же элементы страницы, которые имеют свою логику, поддерживают фрагменты и используют алиасы в качестве названий. Ключевым отличием является то, что виджеты используют YAML разметку для описания настроек и привязаны к Административному интерфейсу.

Виджеты находятся в папке плагина в подпаке widgets. Название папки должно совпадать с именем класса виджета и должно быть написано строчными буквами. Виджеты могут использовать свои JS/CSS файлы и фрагменты. Пример:

widgets/
  /form
    /partials
      _form.htm     <=== Widget partial file
    /assets
      /js
        form.js     <=== Widget JavaScript file
      /css
        form.css    <=== Widget StyleSheet file
  Form.php          <=== Widget class

Определение класса

Класс универсального виджета должен расширять Backend\Classes\WidgetBase класс. Как и любой другой класс плагина, он также должен принадлежать пространству имен. Пример:

namespace Backend\Widgets;

use Backend\Classes\WidgetBase;

class Lists extends WidgetBase
{
    protected $defaultAlias = 'list';

    public function widgetDetails()
    {
        return [
            'name'        => 'List Widget',
            'description' => 'Used for building back end lists.'
        ];
    }

    ...

Класс виджета должен содержать метод render() для отображения содержимого. Пример:

public function render()
{
    return $this->makePartial('list');
}

Вы можете использовать переменную $vars, чтобы передать произвольное значение во франмент

public function render()
{
    $this->vars['var'] = 'value';
    return $this->makePartial('list');
}

Вы также можете передать необходимые значения в качестве второго параметра метода makePartial():

public function render()
{
    $this->vars['var'] = $value;
    return $this->makePartial('list', ['var'=>'value']);
}

AJAX

Виджеты могут использовать AJAX как и контроллеры. Обработчики AJAX являются публичными методами класса виджета с названием, начинающимся с on. Единственным отличием является то, что Вы должны использовать getEventHandler() в data-request. Пример:

<a
    href="javascript:;"
    data-request="<?= $this->getEventHandler('onPaginate') ?>"
    title="Next page">Next</a>

Привязка виджетов к контроллерам

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

public function __construct()
{
    parent::__construct();

    $myWidget = new MyWidgetClass($this);
    $myWidget->alias = 'myWidget';
    $myWidget->bindToController();
}

После привязки виджет можно отобразить на странице или фрагменте при помощи его алиаса:

<?= $this->widget->myWidget->render() ?>

Виджеты форм

При помощи виджетов форм Вы можете расширить функциональность административных ./backend-forms. Виджеты этого типа должны быть зарегистрированы в Файле регистрации плагина.

Определение класса

Класс виджета форм должен расширять Backend\Classes\FormWidgetBase класс. Как и любой другой класс плагина, он также должен принадлежать пространству имен. Зарегистрированный виджет может использоваться в файле с описанием полей. Пример:

namespace Backend\Widgets;

use Backend\Classes\FormWidgetBase;

class CodeEditor extends FormWidgetBase
{
    public function widgetDetails()
    {
        return [
            'name'        => 'Code Editor',
            'description' => 'Renders a code editor field.'
        ];
    }

    public function render() {}
}

Регистрация виджета

Плагины могут регистрировать виджеты переопределяя метод registerFormWidgets() внутри Файла регистрации плагина. Метод должен вернуть массив, где ключ - класс виджета, а значение - массив с меткой и кодом. Пример:

public function registerFormWidgets()
{
    return [
        'Backend\FormWidgets\CodeEditor' => [
            'label' => 'Code editor',
            'code'  => 'codeeditor'
        ]
    ];
}

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

Виджеты отчетов

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

Определение класса

Класс виджета отчетов должен расширять Backend\Classes\ReportWidgetBase класс. Как и любой другой класс плагина, он также должен принадлежать пространству имен. Класс виджета должен переопределять метод render() для отображения содержимого. Пример:

plugins/
  rainlab/                    <=== Author name
    googleanalytics/          <=== Plugin name
      reportwidgets/          <=== Report widgets directory
        trafficsources        <=== Widget files directory
          partials
            _widget.htm
        TrafficSources.php    <=== Widget class file

Пример содержимого файла TrafficSources.php:

namespace RainLab\GoogleAnalytics\ReportWidgets;

use Backend\Classes\ReportWidgetBase;

class TrafficSources extends ReportWidgetBase
{
    public function render()
    {
        return $this->makePartial('widget');
    }
}

Фрагменты виджета могут содержать любую HMTL разметку. Весь код должен быть обернут в DIV с классом report-widget. Для отображения заголовков лучше использовать элемент H3. Пример фрагмента:

<div class="report-widget">
    <h3>Traffic sources</h3>

    <div
        class="control-chart"
        data-control="chart-pie"
        data-size="200"
        data-center-text="180">
        <ul>
            <li>Direct <span>1000</span></li>
            <li>Social networks <span>800</span></li>
        </ul>
    </div>
</div>

image

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

<div class="report-widget">
    <h3>Top pages</h3>

    <div class="table-container">
        <table class="table data" data-provides="rowlink">
            <thead>
                <tr>
                    <th><span>Page URL</span></th>
                    <th><span>Pageviews</span></th>
                    <th><span>% Pageviews</span></th>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <td>/</td>
                    <td>90</td>
                    <td>
                        <div class="progress">
                            <div class="bar" style="90%"></div>
                            <a href="/">90%</a>
                        </div>
                    </td>
                </tr>
                <tr>
                    <td>/docs</td>
                    <td>10</td>
                    <td>
                        <div class="progress">
                            <div class="bar" style="10%"></div>
                            <a href="/docs">10%</a>
                        </div>
                    </td>
                </tr>
            </tbody>
        </table>
    </div>
</div>

Свойства виджетов отчетов

Виджеты отчетов могут иметь свойства, которые пользователи могут изменять при помощи Инспектора:

image

Свойства должны быть определены в классе виджета в методе defineProperties(). Пример:

public function defineProperties()
{
    return [
        'title' => [
            'title'             => 'Widget title',
            'default'           => 'Top Pages',
            'type'              => 'string',
            'validationPattern' => '^.+$',
            'validationMessage' => 'The Widget Title is required.'
        ],
        'days' => [
            'title'             => 'Number of days to display data for',
            'default'           => '7',
            'type'              => 'string',
            'validationPattern' => '^[0-9]+$'
        ]
    ];
}

Регистрация виджета

Плагины могут регистрировать виджеты переопределяя метод registerReportWidgets() внутри Файла регистрации плагина. Метод должен вернуть массив, где ключ - класс виджета, а значение - массив с меткой и контекстом. Пример:

public function registerReportWidgets()
{
    return [
        'RainLab\GoogleAnalytics\ReportWidgets\TrafficOverview' => [
            'label'   => 'Google Analytics traffic overview',
            'context' => 'dashboard'
        ],
        'RainLab\GoogleAnalytics\ReportWidgets\TrafficSources' => [
            'label'   => 'Google Analytics traffic sources',
            'context' => 'dashboard'
        ]
    ];
}

Метка определяет название виджета, а контекст - место, где его можно использовать.