What is Widget Object
Widget object is a convenience tool to help us render HTML blocks, you can consider it as a backend web component.
Create A Widget
First, add a template file in /templates/sidebar/news.php
, this is a news widget.
<ul class="nav news">
<?php foreach ($articles as $article): ?>
<li>
<a href="<?php echo $article->link; ?>">
<?php echo $article->title; ?>
</a>
</li>
<?php endforeach; ?>
</ul>
Now we can use this widget in anywhere, remember add data when rendering it:
use Windwalker\Core\Widget\Widget;
$news = new Widget('sidebar.news');
$news->render(array('articles' => $articles));
// In PHP 5.4, you can use instantiation object access
$news = (new Widget('sidebar.news'))->render(['articles' => $articles]);
It will be useful to render widgets in View prepareData()
, then we can print theses widgets to view template:
class SakurasHtmlView extends HtmlView
{
protected function prepareData($data)
{
$data->items = $this->repository->getItems();
$data->categories = $this->repository['Categories']->getItems();
$data->news = (new Widget('sidebar.news'))->render(array('articles' => $data->items));
$data->pagination = (new Widget('_global.pagination.pagination'))->render(array('pages' => $this->repository->getPagination()));
$data->categories = (new Widget('sidebar.categories'))->render(array('categories' => $data->categories));
$data->banner = (new Widget('sidebar.banner'))->render(array('banner' => $data->banner));
}
}
Templating
By default, widget will find templates from these paths:
- {ROOT}/src/{package}/Templates/{Locale}
- {ROOT}/src/{package}/Templates
- {ROOT}/templates
- {ROOT}/vendor/windwalker/core/src/Core/Resources/Templates
You can add your custom path to Widget:
use Windwalker\Utilities\Queue\PriorityQueue;
$widget->addPath('/my/widget/path', PriorityQueue::HIGH);
Widget also use Windwalker Renderer to render page, you need to add priority to set the ordering of this path.
Set Package
By default, Widget will auto guess current package, but you can set custom package to direct to different template paths.
// Add package name, Widget will auto resolve package
$news = new Widget('sidebar.news', 'php', 'package_name');
// OR add package object
$news = new Widget('sidebar.news', 'php', $package);
Add Path to Global
Add your path to global RendererHelper that Widget will always contain this path:
\Windwalker\Core\Renderer\RendererHelper::addGlobalPath('/my/widget/path', PriorityQueue::ABOVE_NORMAL);
Add Shared Variables
$widget = new Widget('flower.sakura');
$widget->set('foo', 'bar');
echo $widget->render($data1);
echo $widget->render($data2);
Override Built-in Widgets Templates
Windwalker has some built-in widgets, it contains: messages
, pagination
, error pages
.
There is an example to override messages template. The global message template is located at
{ROOT}/vendor/windwalker/core/src/Core/Resources/Templates/windwalker/message/default.php
So we can add a custom template at:
{ROOT}/templates/windwalker/message/default.php
Now all messages in Windwalker will select your template since the new file path is priority to origin file.
Override other widgets please see: Pagination and Error Handling
Use Edge and Twig
Similar to View, Windwalker Widget support Blade and Twig engine, you may just create it by newing it:
use Windwalker\Core\Widget\WidgetHelper;
// Use constant
WidgetHelper::createWidget('sidebar.news', WidgetHelper::EDGE);
// Use string
WidgetHelper::createWidget('sidebar.news', 'twig');
See also: Blade Templating and Twig Documentation
Render by WidgetHelper
Use WidgetHelper to quickly render page.
use Windwalker\Core\Widget\WidgetHelper;
$html = WidgetHelper::render('foo.bar', $data, WidgetHelper::EDGE);
Create Custom Widget Class
Create custom Widget class to quickly render specific template.
use Windwalker\DataMapper\DataMapper;
class NewsWidget extends Widget
{
/**
* Optional property to set engine.
*/
protected $renderer = 'edge';
/**
* Optional property to find template.
*/
protected $layout = 'sidebar.news';
/**
* Optional property to locate package.
*/
protected $package = 'flower';
protected function prepareData($data)
{
$data->items = (new DataMapper('articles'))->limit(10, 20)->find();
}
}
echo (new NewsWidget())->render();
Render Widget in Template
WidgetHelper instance has been inject to global renderer variables, we can use it to quickly render widget.
In php template
<?php echo $widget->render('sidebar.news', $data, 'edge'); ?>
In Blade or Edge
{!! $widget->render('sidebar.news', $data, 'edge') !!}
OR
@widget('sidebar.news', $data, 'edge')
Twig
{{ widget.render('sidebar .news', data, 'edge') | raw }}
If you found a typo or error, please help us improve this document.