imanghafoori/laravel-widgetize

一个简洁而强大的包,为您的Laravel应用提供更好的结构和缓存机会。

v2.2.51 2024-06-11 20:34 UTC

README

Laravel Widgetize

widgetize_header

Maintainability Quality Score Latest Stable Version Awesome Laravel Monthly Downloads Coverage Status tests Imports

🎀🎀 "更干净的代码" ➕ "易于缓存" 🎀🎀

用❤️为每位聪明的Laravel开发者打造

更多阅读

这个页面可能一开始看起来很长且无聊,但请耐心点!!!

我相信如果你读完了,你不会失望的。所以,让我们开始... 🏇

安装:⬇️

composer require imanghafoori/laravel-widgetize

🔌 (对于Laravel <=5.4) 接下来,你必须将服务提供者添加到 config/app.php 🔌

'providers' => [
    // for laravel 5.4 and below
    Imanghafoori\Widgets\WidgetsServiceProvider::class,
];

发布你的配置文件

php artisan vendor:publish

🔥 然后你将像火一样燃烧!🔥

php artisan make:widget MySexyWidget

生成的小部件文件中包含许多文档,因此无需记住或阅读此页面的其余部分。你可以直接开始使用。

概览

此包可以帮助你

  • 页面局部缓存

  • 清理你的控制器代码

  • 压缩HTML

  • 轻松提供页面局部缓存以供varnish或nginx进行ESI缓存

  • 与laravel-debugbar包集成

  • 将小部件渲染为HTML或JSON

何时使用此包?

这个概念(这个设计模式)在您想要创建包含多个部分(侧边栏、菜单、轮播图等)的高页面的情况下特别有用,每个小部件都需要独立的SQL查询和PHP逻辑来为其模板提供数据。无论如何,安装它几乎没有开销,因为出人意料的是,它只是一个小的抽象类。当然,您可以使用它来 重构您的庞大数据代码,将其驯服成可管理的部分,或 将性能提升4-5倍!💫

什么是小部件?

您可以将小部件想象成是一个部分(它知道如何为自己提供数据。)

您可以在blade文件中包含 @widget('myWidget'),它会变成 HTML!!!

因此,您可以在我们的Laravel应用程序中将 @include('myPartial') 替换为 @widget('myWidget')

💎 技术特性

🔹 1. 可选地 缓存每个小部件的输出。(这提供了强大、灵活且易于使用的缓存机会)您可以为页面上的每个部分设置不同的缓存配置。类似于 ESI 标准。

🔹 2. 可选地 压缩小部件的输出

🔹 3. 以HTML标题属性的形式显示小部件的调试信息。

🔹 4. php artisan make:widget 命令

🔹 5. 它帮助您为每个小部件拥有一个专属的表示类,以清理您的视图。

🔹 6. 它扩展了路由外观的 Route::jsonWidgetRoute::widget

当您在视图中编写 @widget('SomeWidget') 时会发生什么

鉴于我们已经禁用了widgetize配置文件中的缓存...

1 - 它首先查找 "SomeWidget" 类以获取配置。

2 - 然后调用小部件的控制器方法并从中获取一些数据。

3 - 使用这些数据,它 "编译"(换句话说,“渲染”)blade文件($template)。(生成一些HTML)

4 - (如果为小部件启用了缓存)它将生成的HTML副本放入缓存中,以供将来使用。

5 - 最后,它返回最终的HTML。(或可能是JSON)

"小部件" 与 "视图组合器"

您可能认为“视图组合器”已经完成了这项工作,那么为什么还需要“小部件”?

1- 视图组合器最糟糕的事情是您永远不知道哪个组合器被附加到 @include 上,更不用说您的团队成员了。

2- 您无法从视图中传递数据到 compose() 方法。它们接收一个 \Illuminate\View\View 对象,因此它们不能被重用来公开JSON数据。widgetize旨在为widget-控制器提供完全的自由和可重用性。

public function compose(View $view)
{
    $view->with('count', $this->users->count());
}

3- 它们没有内置的缓存。

💡 示例代码

如何生成一个小部件?

您可以使用: php artisan make:widget MyWidget 来创建您的小部件类。

示例小部件类

namespace App\Widgets;

class MyWidget
{
    // The data returned here would be available in widget view file automatically.
    public function data($my_param=5)
    {
        // It's the perfect place to query the database for your widget...
        return Product::orderBy('id', 'desc')->take($my_param)->get();

    }
}

App\Widgets\MyWidgetView.blade.php

<ul>
  @foreach($data as $product)
    <li>
      {{ $product->title }}
    </li>
  @endforeach
  
  Note that it is perfectly ok to use an other widget here 
  @widget('AnOtherWidget')
</ul>

好的,现在完成了!我们有一个现成的小部件。让我们使用它...

然后如何使用这个小部件?

在正常的工作日视图(中间端)

<html>
    <head></head>
    <body>
        <h1>Hello {{ auth()->user()->username }} </h1> <!-- not cached -->

        @widget('RecentProductsWidget') <!-- Here we send request to back-end to get HTML -->
        
    <body>
</html>

在您的blade文件中思考 @widget() 的另一种方式

All of us, more or less have some ajax experience. One scenario is to lazy load a page partial after
the page has been fully loaded.
You can think of @widget() as an ajax call from "middle-end" to the "back-end" to load a piece of HTML
into the page.

什么是槽?

槽帮助您在槽内定位您的HTML或blade代码,允许父小部件进行排列,并提高小部件的可重用性。

如何定义一个槽?

要使用槽,您应该使用 @slotWidget 而不是 @widget,然后关闭指令 @endSlotWidget,然后在其中定义您的槽。看看语法

@slotWidget('MyWidget')
    @slot('message')
        <h1>Hello {{ auth()->user()->username }} </h1>
    @endSlot
@endSlotWidget

此外,您还可以传递您的数据

@slotWidget('MyWidget', [$a, $b])
...

如何使用槽?

App\Widgets\MyWidgetView.blade.php

<div class="message">
    {!! $slots['message'] !!}
</div>

📖 文档

🌍 全局配置

您可以在 "config/widgetize.php" 文件中设置变量,以全局设置一些配置供您的小部件使用,并在需要时按小部件覆盖它们。有关更多信息,请参阅 config/widgetize.php 文件中的docblocks。

🚙 每个小部件配置

public $template (字符串)

如果未设置,默认情况下,它指向 app/Widgets 文件夹,并查找 'widgetNameView.blade.php'(这意味着如果您的小部件是 app/Widgets/home/recentProducts.php,则默认视图为 app/Widgets/home/recentProductsView.blade.php)。无论如何,您都可以覆盖它,使其指向 views 文件夹中的任何部分。(例如:public $template='home.footer' 将查找 resource/views/home/footer.blade.php)因此,整个小部件都位于一个文件夹中。

| app\Widgets\Homepage\RecentProductsWidget.php

| app\Widgets\Homepage\RecentProductsWidgetView.blade.php

public $controller (字符串)

如果您不想在您的 widget 类中放置 data 方法,可以设置 public $controller = App\Some\Class\MyController::class 并在专用类中放置您的 public data 方法(而不是在 widget 类中)。

或者您也可以这样引用

public $controller = [\App\Some\Class\MyRepo::class, 'myMethod'];

public $controller = '\App\Some\Class\MyRepo@myMethod';

public $presenter (字符串)

如果您不想在您的 widget 类中放置 present 方法,可以设置 public $presenter = App\Some\Class\MyPresenter::class 并在专用类中放置您的 public present 方法。控制器返回的数据首先通过您的 presenter,然后传递到视图。(所以如果您指定了 presenter,您的视图文件将从 presenter 获取数据,而不是从控制器。)

public $cacheLifeTime (整数)

如果您想覆盖全局缓存寿命(该寿命在您的配置文件中设置)。

public $cacheTags (数组)

您可以设置标签 public $cacheTags = ['tag1','tag2'] 以针对一组小部件并刷新它们的缓存。使用辅助函数

expire_widgets(['someTag', 'tag1']);

这将导致所有具有 'someTag' 或 'tag1' 的小部件被刷新。

注意:标记功能与所有 Laravel 缓存驱动程序一起工作,包括 'file' 和 'database'。

public $cacheView

如果您想使视图实时,但控制器结果被缓存,请将其设置为 false。默认值为 true

public function cacheKey

如果您想显式定义用于存储小部件 html 结果的缓存键,可以实施此方法。

    public function cacheKey($args)
    {
        return 'user_widget_'.$args['user_id'];
    }

public function extraCacheKeyDependency

请注意,如果您的最终小部件 HTML 输出取决于 PHP 的超级全局变量并且您想缓存它,则它们必须包含在小部件的缓存键中。

namespace App\Widgets;

class MyWidget
{

    public function data()
    {
        $id = request('order_id'); // here we are using a request parameter to fetch database...
        return Product::where('order_id', $id)->get();
    }
    

    public function extraCacheKeyDependency()
    {
        // so the value of this parameter should be considered for caching.
        return request()->get('order_id');
    }
    
}

您可能想查看源代码并阅读注释以获取更多信息。

提示:如果您决定使用其他模板引擎而不是 Blade,那将不会有问题。

📖 稳定的设计模式

您可以在以下文章中找到更多信息:这是一篇 3 分钟的阅读。

单一职责原则

Q&A

Q&A:如何仅从 URL 暴露小部件 HTML 内容?

Route::widget('/some-url', 'MyWidget', 'MyRouteName1'); // <-- exposes HTML
// or
Route::jsonWidget('/my-api','MyWidget', 'MyRouteName2'); // <-- exposes json

/some-url/{a}/{b}GET 请求将看到小部件。ab 参数将传递给小部件控制器。

jsonWidget 将暴露小部件控制器返回的缓存数据。

Q&A:如何从路由引用小部件控制器?

这样,您还可以将数据作为 json 暴露给客户端应用程序。

Route::get('/api/products/{id}', '\App\Widgets\MyWidget@data');

* 在您想要引用 Http\Controller 文件夹之外类的情况下,重要的事情是,在 App 前面放置 \\

🙋 贡献

如果您发现一个问题,或者有更好的方法来做某事,请随时打开一个问题或拉取请求。如果您在开源项目中使用 laravel-widgetize,请创建一个拉取请求,以提供它的 URL 作为 README.md 文件中的示例应用程序。

❗ 安全性

如果您发现任何与安全性相关的问题,请使用 security tab 而不是使用问题跟踪器。

⭐ 您的星星让我们做得更多 ⭐

一如既往,如果您觉得这个包很有用,并且想鼓励我们维护和改进它。只需按下星标按钮,表明您的意愿。

星标历史

Star History Chart

更多作者作品

Laravel Microscope

💎 自动在您的 Laravel 应用中查找错误。

Laravel middlewarize

💎 您可以将中间件应用于任何方法调用。

Laravel HeyMan

💎 允许您编写表达式的代码来进行授权、验证和认证。

Laravel Terminator

💎 一个最小化但功能强大的包,为您提供重构控制器的机会。

Laravel AnyPass

💎 仅在本地环境中允许您使用任何密码登录。

Great spirits have always encountered violent opposition from mediocre minds.

"Albert Einstein"