在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
开源软件名称(OpenSource Name):arrilot/laravel-widgets开源软件地址(OpenSource Url):https://github.com/arrilot/laravel-widgets开源编程语言(OpenSource Language):PHP 100.0%开源软件介绍(OpenSource Introduction):Widgets for LaravelA powerful alternative to view composers. Asynchronous widgets, reloadable widgets, console generator, caching - everything that you can imagine. InstallationRun Laravel >=5.5 uses Package Auto-Discovery, so you don't need to manually add the ServiceProvider and Facades UsageLet's consider that we want to make a list of recent news and reuse it in several views. First of all we can create a Widget class using the artisan command provided by the package. php artisan make:widget RecentNews This command generates two files:
Add "--plain" option if you do not need a view.
<?php
namespace App\Widgets;
use Arrilot\Widgets\AbstractWidget;
class RecentNews 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_news', [
'config' => $this->config,
]);
}
}
The last step is to call the widget. There are several ways to do so. @widget('recentNews') or {{ Widget::run('recentNews') }} or even {{ Widget::recentNews() }} There is no real difference between these. The choice is up to you. Passing variables to widgetVia config arrayLet's carry on with the "recent news" example. Imagine that we usually need to show five news, but in some views we need to show ten. This can be easily achieved by: class RecentNews extends AbstractWidget
{
...
protected $config = [
'count' => 5
];
...
}
...
@widget('recentNews') // shows 5
@widget('recentNews', ['count' => 10]) // shows 10
Config array is available in every widget method so you can use it to configure placeholder and container too (see below)
class RecentNews extends AbstractWidget
{
...
protected $config = [
'count' => 5,
'foo' => 'bar'
];
...
}
@widget('recentNews', ['count' => 10]) // $this->config['foo'] is still 'bar'
public function __construct(array $config = [])
{
$this->addConfigDefaults([
'child_key' => 'bar'
]);
parent::__construct($config);
} Directly (works only for Laravel versions below 7)You can also choose to pass additional parameters to @widget('recentNews', ['count' => 10], 'date', 'asc')
...
public function run($sortBy, $sortOrder) { }
...
NamespacesBy default the package tries to find your widget in the You can override this by publishing package config ( Although using the default namespace is very convenient, in some cases you may wish to have more flexibility. For example, if you've got dozens of widgets it makes sense to group them in namespaced folders. No problem, there are several ways to call those widgets:
@widget('News\RecentNews', $config)
@widget('news.recentNews', $config)
@widget('\App\Http\Some\Namespace\Widget', $config) Asynchronous widgetsIn some situations 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 facade or blade directive - Widget params are encrypted (by default) and sent via ajax call under the hood. So expect them to be
By default nothing is shown until ajax call is finished. This can be customized by adding a public function placeholder()
{
return 'Loading...';
}
Reloadable widgetsYou can go even further and automatically reload widget every N seconds. Just set the class RecentNews extends AbstractWidget
{
/**
* The number of seconds before each reload.
*
* @var int|float
*/
public $reloadTimeout = 10;
} Both sync and async widgets can become reloadable. You should use this feature with care, because it can easily spam your app with ajax calls if timeouts are too low. Consider using web sockets too but they are way harder to set up. ContainerAsync and Reloadable widgets both require some DOM interaction so they wrap all widget output in a html container.
This container is defined by /**
* Async and reloadable widgets are wrapped in container.
* You can customize it by overriding this method.
*
* @return array
*/
public function container()
{
return [
'element' => 'div',
'attributes' => 'style="display:inline" class="arrilot-widget-container"',
];
}
CachingThere is also a simple built-in way to cache entire widget output. Just set $cacheTime property in your widget class and you are done. class RecentNews 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.
A cache key depends on a widget name and each widget parameter.
Override Cache taggingWhen tagging is supported (see the Laravel cache documentation) and to
simplify cache flushing, a tag class RecentNews extends AbstractWidget
{
/**
* Cache tags allow you to tag related items in the cache
* and then flush all cached values that assigned a given tag.
*
* @var array
*/
public $cacheTags = ['news', 'frontend'];
} For this example, if you need to flush : // Clear widgets with the tag news
Cache::tags('news')->flush();
// Clear widgets with the tag news OR backend
Cache::tags(['news', 'frontend'])->flush();
// Flush all widgets cache
Cache::tags('widgets')->flush(); Widget groups (extra)In most cases 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() }}
equals
You can set a separator that will be display between widgets in a group.
You can also wrap each widget in a group using 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 groupThere is a couple of ways to remove widget/widgets from a group after they've been already added.
$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
Widget::group('sidebar')->addWidget('files');
Widget::group('sidebar')->addAsyncWidget('files');
Widget::group('sidebar')->removeByName('files'); // Widget group is empty now
Widget::group('sidebar')->position(42)->addWidget('files');
Widget::group('sidebar')->position(42)->addAsyncWidget('files');
Widget::group('sidebar')->removeByPosition(42); // Widget group is empty now
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
Namespaces for third party packages (extra)In some cases, it may be useful to deliver widgets with your own packages. For example, if your package allows you to manage news, it would be convenient to have immediately configurable widgets, ready for display, directly delivered with your package. To avoid having to use the fqcn each time, you can set a widget namespace into your package provider. This way the widgets from your package can be more easily identified, and especially the syntax will be shorter. To do that, all you have to do is to register the namespace in your package service provider : public function boot()
{
app('arrilot.widget-namespaces')->registerNamespace('my-package-name', '\VendorName\PackageName\Path\To\Widgets');
} After that you can use the namespace in your views : @widget('my-package-name::foo.bar')
// is equivalent to
@widget('\VendorName\PackageName\Path\To\Widgets\Foo\Bar') |
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论