How to Create Widgets in Laravel?, Asynchronous and Reloadable

How to Create Widgets in Laravel?,  Asynchronous and Reloadable

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:

  1. resources/views/widgets/recent_posts.blade.php is an empty view.

Add "--plain" option if you do not need a view.

  1. 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.

Related posts

Write a comment