Widgets
Widgets are used to provide reusable view parts by means of a view class. Please refer to the Yii-Guide for more information about widgets.
This guide describes the usage of some HumHubs base widget types.
JsWidgets
JsWidgets in HumHub are used to connect your Yii Widget with a javascript widget.
Custom JsWidget are extended from humhub\widgets\JsWidget
and can facilitate the following features:
- Transfer options from PHP to your javascript widget
- Manage your widget initialization through the
init
field - Reloadable widget
- Widget event binding
Info: Refer to the Javascript Widget part for more information about writing javascript modules.
A very basic JsWidget:
SimpleWidget.php
namespace humhub\modules\devtools\widgets;
use Yii;
use humhub\widgets\JsWidget;
use yii\helpers\Url;
class SimpleWidget extends JsWidget implements Reloadable
{
public $jsWidget = 'example.SimpleWidget';
/**
* This will automatically initialize the widget
*/
public $init = true;
/**
* Used to add HTML attributes to the root of your widget
*/
public function getAttributes()
{
return [
'class' => 'my-widget'
]
}
/**
* Used to add data-* options to your widget
*/
public function getData()
{
return [
'some-url' : Url::to(['/some/route'])
]
}
}
example.SimpleWidget.js
humhub.module('example.SimpleWidget', function(module, require, $) {
var Widget = require('ui.widget').Widget;
var SimpleWidget = Widget.extend();
SimpleWidget.prototype.init = function() {
console.log(this.options.someUrl)
};
module.export = SimpleJsWidget;
});
JsWidget rendering
The example above does not overwrite the humhub\widgets\JsWidget::run()
function and therefore uses the default
rendering of the JsWidget class, which can be used for very simple widgets. The default rendering mechanism uses renders
a simple HTML tag defined by humhub\widgets\JsWidget::container
and humhub\widgets\JsWidget::content
and furthermore
uses the humhub\widgets\JsWidget::getOptions()
function for fetching the HTML attributes and widget data-* options.
In the following example we manipulate the default rendering to render a simple list:
class SimpleWidget extends JsWidget implements Reloadable
{
public $jsWidget = 'example.SimpleWidget';
public $init = true;
public $id = 'iamUnique'
public $container = 'ul';
public $myOption = 300;
public function run()
{
$this->content = Html::tag('li', 'My List Item');
return parent::render();
}
public function getAttributes()
{
return [
'class' => 'my-widget-list'
]
}
public function getData()
{
return [
'some-important-option' : $this->myOption
]
}
}
This will result in the following output:
<ul id="iamUnique" class="my-widget-list" data-ui-widget="example.SimpleWidget" data-ui-init data-some-important-option="300">
<li>My List Item</li>
</ul>
Fore more complex cases you may want to use a custom view as follows:
public function run()
{
return $this->render('myWidget', [
'model' => $this->model,
'options' => $this->getOptions();
])
}
myWidget.php
<?= Html::beginTag('div', $options) ?>
// Some complex widget content...
<?= Html::endTag('div') ?>
Note: The
getOptoins()
function assembles all html attributes and data-* options of your widget, which always should be added to the root node of your widget.
JsWidget initialization
The initialization is managed by the humhub\widgets\JsWidget::init
field, which either accepts a boolean or array.
Please refer to Widget Initialization for the javascript part of your
initialization logic.
When setting your init
field to true or add a value, your widget will be initialized once detected in the frontend,
otherwise your widget may be initialized by an action trigger or manually within your javascript module.
By providing a non boolean value as init
value you can add serialized data which will be used as first parameter of
your SimpleWidget.prototype.init
function.
Reloadable JsWidgets
Often you want to reload your widget in order to update parts of your view. This can be achieved by implementing the
humhub\widgets\Reloadable]] interface and providing a reload-url in your
getReloadUrl()` as in the following example
class ReloadableWidget extends JsWidget implements Reloadable
{
//...
public function getReloadUrl()
{
return ['/mymodule/widget/reload', 'id' => $this->id];
}
}
class WidgetController extends Controller
{
public function actionReload($id)
{
return JsonResponse::output(ReloadableWidget::widget(['id' => $id]));
}
}
Now you will be able to reload your widget with myWidget.reload()
or a reload
button action.
Widget Stacks
HumHub uses Widget-Stacks to assemble multiple entries of a base widget as a naviagation or list.
Stacked widget are derived from humhub\widgets\BaseStack
and will fire an onInit
and onRun
event by default,
which can be subscribed by other modules to inject widget items. This mechanism can be used for example for sidebars.
Example of stack used as sidebar:
<?php
// Render the sidebar with two default item
echo \humhub\core\space\widgets\Sidebar::widget(['widgets' => [
[\humhub\core\activity\widgets\Stream::class, ['streamAction' => '/space/space/stream', 'contentContainer' => $space], ['sortOrder' => 10]],
[\humhub\core\space\widgets\Members::class, ['space' => $space], ['sortOrder' => 20]]
]]);
?>
config.php
// Subscribe to the onInit event of the sidebar
'events' => [
// Wait for TopMenu Initalization Event
['class' => 'DashboardSidebarWidget', 'event' => 'onInit', 'callback' => ['ExampleModule', 'onDashboardSidebarInit']],
],
//...
Events.php
// This handler function will inject a custom widget to the stack
public static function onDashboardSidebarInit($event) {
$event->sender->addWidget('application.modules.example.widgets.MyCoolWidget', [], ['sortOrder' => 1]);
}