Как правильно оформлять виджеты плагина

Для начала важно понять, что виджеты бывают двух видов — шаблонные и исполняемые.

Шаблонные виджеты — это файлы-шаблоны, которые могут включаться в другие шаблоны. Исполняемые виджеты — это те, где нужно выполнение PHP-кода. Это может быть обращение к базе данных, какая-то обработка и пр.

Шаблонные виджеты

Как уже писал, шаблонные виджеты просто вставляются в другие шаблоны. Например, это могут быть счетчики, какие-то javascript-коды и т.д.

Оформляются они как обычные файлы шаблона, только именуются специальным образом и лежат в определенном месте. Допустим, у нас есть плагин Dummy и мы хотим создать для него шаблонный виджет под названием Foo. Для этого нужно создать файл widget.foo.tpl в папке /plugins/dummy/templates/skin/default/widgets/. И этот шаблон можно потом подключать такой командой:
$config['widgets'][] = array(
    'name' => 'foo.tpl',  // шаблонный виджет
    'group' => 'right',
    'plugin' => 'dummy',
);

Можно создать шаблонный виджет для конкретного скина, тогда путь к нему должен содержать имя этого скина. Например тот же шаблонный виджет для скина Synio будет лежать в папке /plugins/dummy/templates/skin/synio/widgets/.

Исполняемые виджеты

Исполняемые виджеты должны оформляться в виде PHP-класса, который наследуется от родительского класса Widget и их код выглядит примерно так:
class PluginDummy_WidgetFoo extends Widget {
    public function Exec() {
        // Здесь код плагина
    }
}

И этот код должен находится в файле /plugins/dummy/classes/widgets/WidgetFoo.class.php — это виджет Foo плагина Dummy.
$config['widgets'][] = array(
    'name' => 'foo',  // исполняемый виджет
    'group' => 'right',
    'plugin' => 'dummy',
);

Чтобы исполняемый виджет мог чего-то вывести на страницу, ему нужен шаблон. Но тут все просто — для исполняемого виджета Foo создается шаблон, который оформляется точно так же, как и шаблонный виджет выше, т.е. в файле /plugins/dummy/templates/skin/default/widgets/widget.foo.tpl

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

В версии 0.9.7.1 и выше это можно сделать, определив в описании виджета группу, а потом задав эту группу в коде шаблона. Например, если мы хотим, чтобы виджет плагина выводился в группе виджетов «right», мы можем в файле конфигурации плагина /plugins/dummy/config/config.php записать:
$config['widgets'][] = array(
    //'id' => 'asd',
    'name' => 'foo',  // шаблонный виджет
    'wgroup' => 'right',
    'priority' => 'top',
    'plugin' => 'dummy',
);

А в самом шаблоне, где эти виджеты надо выводить, запишем:
{wgroup group="right"}

И в этом месте страницы будут выведены все виджеты (как виджеты приложения, так и виджеты активных плагинов), у которых в параметрах стоит 'wgroup' => 'right'. Конечно, при этом будут учитываться и условия вывода виджетов, если они заданы, но это уже тема для другой статьи.

Дополнение для версии 1.1.+
В версии 1.1 и выше рекомендуется задавать идентификатор виджета при его определении в конфиге, вот так:
$config['widgets']['foo'] = array(
    'name' => 'foo',  // шаблонный виджет
    'wgroup' => 'right',
    'priority' => 'top',
    'plugin' => 'dummy',
);
Т.е. не пустые квадратные скобки, а с идентификатором.

Похожие статьи


20 комментариев

0
У меня такая проблема. Пдагин simpletpl.
1. Создаю файл simpletpl/widgets/WidgetSimpleTopicsTop.class.php
2. вот его код
class PluginSimpletpl_WidgetSimpleTopicsTop extends Widget {
	public function Exec() {
		$sDate=date("Y-m-d H:00:00",time()-Config::Get('plugin.simpletpl.topic_time_top'));
		$aTopics=$this->Topic_GetTopicsRatingByDate($sDate,Config::Get('plugin.simpletpl.count_top_topics'));
		$this->Viewer_Assign('simpletpl_aTopicsTop',$aTopics);
		$this->Viewer_Assign('simpletpl_iCountSlide',ceil(count($aTopics)/2));
	}
}

3.Далее в шаблоне пытаюсь вывести его:
{widget name="simpleTopicsTop"}

4. В итоге ошибка
Fatal error: Class 'BlockSimpleTopicsTop' not found in Z:\home\altocms\www\engine\modules\viewer\plugs\function.widget_exec.php on line 86
0
Добавил в текст, как это можно сделать. Добавлю, что подразумевалось больше вариантов, но я проверил сейчас — для виджета плагина только один работает. В следующих версиях их обязательно будет больше.
0
Ясно. Но я подожду. Этот вариант не очень удобен для меня
0
Я к примеру попробовал создать допольнительный виджет к модулю Topic вывод самого читаемого. Так и не понял как сделать, по выше описанному мануалу, вариант с созданием виджета для встроенного модуля не канает
0
Очень похоже на БЭМ, не так-ли?
0
Честно говоря, работая с виджетами я про БЭМ даже не думал
0
А если подумать?
Вроде идея толковая, виджетами можно красиво и удобно нарезать и меню и тебю…
0
А есть ли функция вывода виджета прямо из экшена, аналог AddBlock в ЛС? (если есть то стоило бы упомянуть для полноты)
0
Да, есть в модуле Viewer:
public function AddWidget($sGroup, $sName, $aParams = array(), $iPriority = 0)
0
Вадим, хоть убей не работают у меня виджеты… делаю все по инструкции. Можно посмотреть где-нибудь рабочий пример?
0
yadi.sk/d/I3frHcU56vrAx
Это рабочий пример плагина с двумя виджетами, только что проверил
0
Ну тогда не
И этот код должен находится в файле /plugins/dummy/widgets/WidgetFoo.class.php — это виджет Foo плагина Dummy.
а
/plugins/dummy/classes/widgets/WidgetFoo.class.php
0
А ведь верно, извини, глаз замылился
0
А еще сначала удивился такому решению)) Хорошо что это была всего лишь опечатка. Спасибо за помощь
0
Во время переименовывания своих блоков в виджеты, у меня возник только один вопрос, а зачем создали практически аналогичную сущность виджетов. В чем их принципиальное отличие от блоков?
0
Вопрос в том, что в том же ЛС, да и у нас будет шаблон на наследованиях, где повсеместно используются так называемые smarty блоки. Чтобы избежать путаницы — они заблаговременно и постепенно мигрируют в виджеты. В виджетах также расширенные настройки отображения блоков. Но пока работает и устаревшая логика блоков для совместимости.
+3
Во-первых, термин «блок», на мой взгляд, весьма неудачен. Есть понятие «блоки» у Смарти, и они не имеют ничего общего с ЛС-блоками. А еще есть «блочные хуки», которые не имеют ничего общего ни с ЛС-блоками, ни со Смарти-блоками. Поэтому я давно предлагал ЛС-блоки называть виджетами (как, вообще-то, подобные вещи обычно и называются в сайтостроении), чтобы не создавать путаницы.

Во-вторых, виджеты все же не есть «аналогичная сущность», они весьма отличаются от ЛС-блоков, как и сама система их организации. Если кратко:

1. В ЛС сначала создаются правила, а потом к этим правилам привязываются ЛС-блоки. В Альто мы не виджеты к правилам привязываем, а правила к виджетам, т.е. для каждого конкретного виджета задается где, когда и при каких условиях он будет выводится. Я считаю, что такой подход интуитивно более понятный.

2. В Альто более логично (ИМХО) определяется тип виджета: если есть соответствующий класс, то это исполняемый виджет, если класса нет, но есть шаблон — это шаблонный виджет.

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

В общем, это только на поверхностный взгляд кажется, что просто переименовали, на самом деле все гораздо глубже и ширше. Есть только один недостаток во всем этом — отсутствие нормальной документации с описаниями и примерами. Но я исправляюсь — пишу.
0
Добрый день. Можно передавать параметры в код виджета? Интересует, например, при выводе виджета на странице с топиком передать в него ID автора топика, чтобы вывести доп. информацию. Сейчас приходится вычленять все это через название экшена/эвента и дальше обрабатывать.
0
В вашем случае можно сделать так:
class PluginDummy_WidgetFoo extends Widget {

    public function Exec() {
        // Получаем шаблонную переменную из вьюера
        $oTopic = E::ModuleViewer()->getTemplateVars('oTopic');
        if ($oTopic) {
            // Получаем автора топика
            $oUser = $oTopic->getUser();
            // Получаем доп. информацию, вызывая метод getSomeInfo() модуля Foo плагина Other
            $xSomeInfo = E::Module('PlugineOther\Foo')->getSomeInfo($oUser->getId);
            // Передаем значение в шаблон для вывода
            E::ModuleViewer()->Assign('xSomeInfo', $xSomeInfo);
        }
    }
}
0
Шикарно. Спасибо
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.