In this tutorial, I am going to show you how to create a widget in laravel. This is a much powerful alternative to show views in laravel blades with asynchronous, reloadable, console generator, and caching options.
As you know widget system is made easy to manage our websites. Widget help to make more flexible content on the website. Read How to create an API in Laravel with Step-by-Step Guide.
Installation
Simply run this command on the command prompt
composer require arrilot/laravel-widgets
Laravel >=5.5 uses Package Auto-Discovery, so you don't need to manually add the ServiceProvider and Facades
Usage
You can create a view file and controller by using this command.
First of all, we can create a Widget class using the artisan command provided by the package.
php artisan make:widget RecentPosts
This command generates two files:
resources/views/widgets/recent_posts.blade.php
is an empty view.
Add "--plain" option if you do not need a view.
app/Widgets/RecentPosts
is a widget class.
<?php namespace App\Widgets; use Arrilot\Widgets\AbstractWidget; class RecentPosts extends AbstractWidget { /** * The configuration array. * * @var array */ protected $config = []; /** * Treat this method as a controller action. * Return view() or other content to display. */ public function run() { // return view('widgets.recent_posts', [ 'config' => $this->config, ]); } }
The last step is to call the widget. There are several ways to do so.
@widget('recentPosts')
or
{{ Widget::run('recentPosts') }}
or
{{ Widget::recentPosts() }}
Passing variables to widget
You can pass the variables to the widgets by using this way.
class RecentPosts extends AbstractWidget
{
...
protected $config = [
'count' => 5
];
...
}
...
@widget('recentPosts') // shows 5
@widget('recentPosts', ['count' => 10]) // shows 10
Asynchronous widgets
Sometimes we need to show widgets with big data that time, it can be very beneficial to load widget content with AJAX.
Fortunately, this can be achieved very easily! All you need to do is to change the facade or blade directive.
Widget:: => AsyncWidget::, @widget => @asyncWidget
This can be customized by adding a placeholder()
method to the widget class.
public function placeholder()
{
return 'Loading...';
}
Reloadable widgets
You can go even further and automatically reload the widget every (n) second.
class RecentPosts extends AbstractWidget
{
/**
* The number of seconds before each reload.
*
* @var int|float
*/
public $reloadTimeout = 10;
}
Both types of widget sync and async widgets can become reloadable.
Caching
There is also a simple built-in way to cache the entire widget output. Just set $cacheTime property in your widget class and you are done.
class RecentPost extends AbstractWidget
{
/**
* The number of minutes before cache expires.
* False means no caching at all.
*
* @var int|float|bool
*/
public $cacheTime = 60;
}
No caching is turned on by default. You can set it in your widget as you want. A cache key depends on a widget name and each widget parameter. Override the cacheKey method if you need to adjust it.
Widget groups
In most cases, a Blade is a perfect tool for setting the position and order of widgets. However, sometimes you may find useful the following approach.
// add several widgets to the 'sidebar' group anywhere you want (even in controller)
Widget::group('sidebar')->position(5)->addWidget('widgetName1', $config1);
Widget::group('sidebar')->position(4)->addAsyncWidget('widgetName2', $config2);
// display them in a view in the correct order
@widgetGroup('sidebar')
// or
{{ Widget::group('sidebar')->display() }}
You can also wrap each widget in a group using a wrap method like that.
Widget::group('sidebar')->wrap(function ($content, $index, $total) {
// $total is a total number of widgets in a group.
return "<div class='widget-{$index}'>{$content}</div>";
})->...;
Removing widgets from a group
There are several ways to remove widget/widgets from a group after they've been already added.
Remove one widget by its unique id:
$id1 = Widget::group('sidebar')->addWidget('files');
$id2 = Widget::group('sidebar')->addAsyncWidget('files');
Widget::group('sidebar')->removeById($id1); // There is only second widget in the group now
Remove all widgets with a specific name
Widget::group('sidebar')->addWidget('files');
Widget::group('sidebar')->addAsyncWidget('files');
Widget::group('sidebar')->removeByName('files'); // Widget group is empty now
Remove all widgets that are placed in a specific position.
Widget::group('sidebar')->position(42)->addWidget('files');
Widget::group('sidebar')->position(42)->addAsyncWidget('files');
Widget::group('sidebar')->removeByPosition(42); // Widget group is empty now
Remove all widgets at once.
Widget::group('sidebar')->addWidget('files');
Widget::group('sidebar')->addAsyncWidget('files');
Widget::group('sidebar')->removeAll(); // Widget group is empty now
Checking the state of a group
You can check a widgets group contains any widget or not by using these techniques:
Widget::group('sidebar')->isEmpty(); // bool
Widget::group('sidebar')->any(); // bool
Widget::group('sidebar')->count(); // int
Thank you so much.
Write a comment