brunolobo/widgets
Composer 安装命令:
composer require brunolobo/widgets
包简介
Pacote de widgets originalmente criado por Arrilot, otimizado para uso no Pacto por Brunolobo.
关键字:
README 文档
README
Pacote de Widgets originalmente criado pelo Arrilot e adaptado por Brunolobo para uso no PactoCRM
Instalação
composer require brunolobo/widgets
Para Laravel >= 5.5, apenas isso. Para Laravel < 5.5, continue lendo.
- Registrar o service provider no
app.php
<?php 'providers' => [ ... Brunolobo\Widgets\ServiceProvider::class, ], ?>
- Adicionar os facades também.
<?php 'aliases' => [ ... 'Widget' => Brunolobo\Widgets\Facade::class, 'AsyncWidget' => Brunolobo\Widgets\AsyncFacade::class, ], ?>
Uso
Considere que vamos criar um widget para exibir as últimas notícias na página.
Primeiro de tudo é criar um novo Widget com o comando artisan.
php artisan make:widget RecentNews
Este comando gera 2 arquivos:
resources/views/widgets/recent_news.blade.phpé uma view vazia.
Adicione a opção "--plain" se você não precisa de uma view.
app/Widgets/RecentNewsé uma classe de Widget.
<?php namespace App\Widgets; use Brunolobo\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, ]); } }
Nota: Você pode usar seus próprios .stubs se precisar. Publique os arquivos de configuração para mudar os paths.
O último passo é chamar o widget. Você tem algumas formas de fazer isso.
@widget('recentNews')
ou
{{ Widget::run('recentNews') }}
ou então
{{ Widget::recentNews() }}
Não existe diferença entre os comandos, use conforme a sua preferência.
Passando variaveis para o widget
Pelo array de configuração
Imagine que vamos mostrar 5 notícias no widget de notícias, mas em alguns lugares exibiremos 10. Isso é facilmente conseguido com o uso da variável $config:
class RecentNews extends AbstractWidget { ... protected $config = [ 'count' => 5 ]; ... } ... @widget('recentNews') // shows 5 @widget('recentNews', ['count' => 10]) // shows 10
['count' => 10] é um array de configuração que é acessado por $this->config.
O array ed configuração está disponível em todo widget.
Nota: Campos do array de configuração não especificados na criação do widget não serão atualizados:
class RecentNews extends AbstractWidget { ... protected $config = [ 'count' => 5, 'foo' => 'bar' ]; ... } @widget('recentNews', ['count' => 10]) // $this->config['foo'] continua sendo 'bar'
Nota 2: Você pode querer (mas provavelmente não deve) criar seu próprio BaseWidget e herdar a partir dele. Tudo bem. A única barreira neste caso é merger as configurações padrão entre pai e filho. Neste caso faça o seguinte:
-
Não adicione a linha
protected $config = [...]no filho. -
Adicione conforme abaixo:
public function __construct(array $config = []) { $this->addConfigDefaults([ 'child_key' => 'bar' ]); parent::__construct($config); }
Diretamente
Você pode passar parâmetros diretamente para o metodo run().
@widget('recentNews', ['count' => 10], 'date', 'asc') ... public function run($sortBy, $sortOrder) { } ...
O método run() é resolvido via Service Container, então a injeção no método está disponível.
Namespaces
Por padrão o pacote tenta encontrar seu widget no namespace App\Widgets.
Você pode alterar isso publicando a configuração do pacote (php artisan vendor:publish --provider="Brunolobo\Widgets\ServiceProvider") e setando a propriedade default_namespace.
Ainda que usar o namespace padrão seja muito conveniente, em alguns casos você pode desejar mais flexibilidade. Por exemplo, se você tem dezenas de widgets faz sentido telos em diferentes 'pastas namespaced'.
Sem problema, você tem várias formas de chamar esses widgets:
- Passar o nome completo a partir do
default_namespace(basicallyApp\Widgets) para o métodorun().
@widget('News\RecentNews', $config)
- Usar notação de ponto.
@widget('news.recentNews', $config)
- FQCN também é uma opção.
@widget('\App\Http\Some\Namespace\Widget', $config)
Widgets assíncronos
Em alguns casos é necessário carregar o widget com AJAX.
Isso é conseguido de forma extremamente simples!
O que você precisa é mudar o facade ou diretiva blade - Widget:: => AsyncWidget::, @widget => @asyncWidget.
Os parâmetros do widget são encriptados e enviados por ajax por debaixo dos panos. Então espere que os dados sejam encodados com json_encoded() e json_decoded() para desencodar.
Nota: Você pode desligar a encriptação para um determinado widget setando a variável
public $encryptParams = false;nele. No entanto esta ação deixa os parâmetros do widget publicamente acessíveis, então tenha certeza de não deixar nenhum ponto de vulnerabilidade. Por exemplo, se você passar o user_id como parâmetro com a encriptação desligada, é interessante acrescentar outra variável de controle dentro do widget.
Nota: Você pode setar
use_jquery_for_ajax_callsparatrueno arquivo de configuração para usar chamadas ajax caso queira.
Por padrão, nada é exibido até que a chamada ajax tenha finalizado.
Isto pode ser customizado com a adição do método placeholder() na classe do widget.
public function placeholder() { return 'Carregando...'; }
Nota: Se você precisa fazer alguma coisa com o pacote de rotas para carregar assincronamente o widget (se você roda em uma subpasta http://site.com/app/) você precisa copiar Brunolobo\Widgets\ServiceProvider para a pasta app, modificar de acordo com suas necessidades e registrar no Laravel.
Widgets recarregáveis
Você pode ir além e atualizar o widget automaticamente a cada N segundos.
Basta setar a propriedade $reloadTimeout do widget e está feito.
class RecentNews extends AbstractWidget { /** * The number of seconds before each reload. * * @var int|float */ public $reloadTimeout = 10; }
Tanto widgets sync quanto async tornam-se recarregáveis.
Você deve usar essa função com cuidado, pois pode facilmente sobrecarregar seu aplicativo caso as chamadas ajax tenham tempo muito curto. Considere usar web sockets também mas eles são mais difíceis de configurar.
Container
Os widgets necessitam de alguma interação DOM então todos concentram suas saídas em um containet html.
Este container é definido pelo método AbstractWidget::container() e também pode ser customizado.
/** * 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="brunolobo-widget-container"', ]; }
Nota: Não são suportados widgets em cascata.
Cache
Também existe uma forma simples de fazer o cache do widget. Basta setar a propriedade $cacheTime no widget e pronto.
class RecentNews extends AbstractWidget { /** * The number of minutes before cache expires. * False means no caching at all. * * @var int|float|bool */ public $cacheTime = 60; }
O cache é desligado por padrão.
Uma cache key é criada pelo widget para controle. Você pode sobrescrever o método cacheKey se julgar necessário.
Widget groups (extra)
Em alguns casos o Blade é perfeito para setar a posição e ordem dos widgets. No entanto, algumas vezes você pode ter um comportamento diferente:
// 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() }}
position() pode ser omitido.
Widget::group('sidebar')->addWidget('files');
é igual a
Widget::group('sidebar')->position(100)->addWidget('files');
Você pode configurar um separador que irá aparecer entre os widgets de um grupo.
Widget::group('sidebar')->setSeparator('<hr>')->...;
Você pode encapsular cada widget de um grupo usando o método wrap method como abaixo:
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>"; })->...;
Removendo widgets de um grupo
Existem algumas formas de remover um ou mais widgets de um grupo depois que eles já estiverem adicionados.
- Remover um widget pelo unique
id
$id1 = Widget::group('sidebar')->addWidget('files'); $id2 = Widget::group('sidebar')->addAsyncWidget('files'); Widget::group('sidebar')->removeById($id1); // Agora só o segundo wodget está no grupo
- Remover todos os widgets com nome específico.
Widget::group('sidebar')->addWidget('files'); Widget::group('sidebar')->addAsyncWidget('files'); Widget::group('sidebar')->removeByName('files'); // Widget group está vazio
- Remover todos os widgets de uma posição específica.
Widget::group('sidebar')->position(42)->addWidget('files'); Widget::group('sidebar')->position(42)->addAsyncWidget('files'); Widget::group('sidebar')->removeByPosition(42); // Widget group está vazio
- Remover todos os widgets de uma vez.
Widget::group('sidebar')->addWidget('files'); Widget::group('sidebar')->addAsyncWidget('files'); Widget::group('sidebar')->removeAll(); // Widget group está vazio
Checando o estado de um grupo
Widget::group('sidebar')->isEmpty(); // bool
Widget::group('sidebar')->any(); // bool
Widget::group('sidebar')->count(); // int
brunolobo/widgets 适用场景与选型建议
brunolobo/widgets 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 71 次下载、GitHub Stars 达 0, 最近一次更新时间为 2018 年 01 月 26 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「pactocrm」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 brunolobo/widgets 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 brunolobo/widgets 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
统计信息
- 总下载量: 71
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 1
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2018-01-26