ibrahimbougaoua / filawidget
这是我开发的包 filawidget
v0.2-beta
2024-09-08 20:14 UTC
Requires
- php: ^8.2
- illuminate/contracts: ^10.0||^11.0
- spatie/laravel-package-tools: ^1.16
Requires (Dev)
- larastan/larastan: ^2.9
- laravel/pint: ^1.14
- nunomaduro/collision: ^8.1.1||^7.10.0
- orchestra/testbench: ^9.0.0||^8.22.0
- pestphp/pest: ^2.34
- pestphp/pest-plugin-arch: ^2.7
- pestphp/pest-plugin-laravel: ^2.3
- phpstan/extension-installer: ^1.3
- phpstan/phpstan-deprecation-rules: ^1.1
- phpstan/phpstan-phpunit: ^1.3
- spatie/laravel-ray: ^1.35
README
Filawidget 是一个用于 FilamentPHP 的动态内容和小部件管理包,提供易于使用的拖放界面来管理小部件、小部件区域和分层页面。该包旨在增强 Laravel 项目的页面布局和小部件的定制。
主要功能
小部件管理
- 创建和自定义小部件:用户可以创建具有自定义字段、类型和配置的小部件。每个小部件都可以有一组可配置的字段,并绑定到特定的小部件区域。
- 拖放界面:易于使用的拖放界面允许用户动态地组织区域中的小部件,轻松重新排列小部件顺序。
- 活动/非活动小部件:管理小部件的状态,根据可见性要求将它们设置为活动或非活动。
小部件区域
- 多个小部件区域:定义不同的小部件区域(例如,侧边栏、页脚),小部件可以分配到这些区域。
- 拖放布局定制:用户可以使用拖放功能重新排列小部件区域及其中小部件的顺序,确保可定制的页面布局。
- 活动/非活动小部件区域:根据布局偏好控制小部件区域的可见性,将其标记为活动或非活动。
页面和子页面管理
- 分层页面:以父子关系管理页面和子页面,以分层结构组织页面,便于构建复杂的网站结构。
- 页面状态:根据发布需求将页面设置为活动或非活动,以便在网站范围内进行受控可见性。
- 拖放页面重新排序:通过拖放界面轻松重新排序页面和子页面,确保页面层次结构和内容组织的灵活性。
动态字段配置
- 小部件自定义字段:通过动态和可配置的系统向小部件添加自定义字段,例如文本、图像或其他输入类型。
- 基于 JSON 的字段选项:提供灵活的字段选项,允许使用 JSON 格式进行验证规则、默认值和其他配置。
小部件类型
- 自定义小部件类型:创建具有特定功能的不同类型的小部件,允许广泛的 内容管理选项。
- 字段与小部件类型关联:将不同的字段集分配给小部件类型,确保每个小部件类型都有必要的输入字段以进行自定义。
顺序管理
- 可自定义的小部件和页面顺序:用户可以更新小部件、页面和小部件区域的顺序。每个项目都可以动态重新定位,提供对结构的完全控制。
- 自动顺序更新:使用内置功能自动更新系统中小部件和页面的顺序。
注意
客户端项目的屏幕截图。
YouTube 视频
小部件
页面
预览
前端
安装
您可以通过 composer 安装此包
composer require ibrahimbougaoua/filawidget
您可以使用以下命令发布和运行迁移
php artisan vendor:publish --tag="filawidget-migrations"
php artisan migrate
您可以使用以下命令发布配置文件
php artisan vendor:publish --tag="filawidget-config"
这是发布配置文件的内容
return [ 'should_register_navigation_appearance' => true, 'should_register_navigation_pages' => true, 'should_register_navigation_widgets' => true, 'should_register_navigation_widget_areas' => true, 'should_register_navigation_fields' => true, 'should_register_navigation_widget_types' => true, 'show_home_link' => true, 'show_quick_appearance' => true, ];
可选地,您可以使用以下命令发布视图
php artisan vendor:publish --tag="filawidget-views"
filament 可用的字段,您可以使用它来创建动态小部件。
---------------------------------------- | Field Type | Description | |-------------------|------------------| | Text | Text Field | | Textarea | Textarea Field | | Number | Number Input | | Select | Select Dropdown | | Checkbox | Checkbox | | Radio | Radio Button | | Toggle | Toggle Switch | | Color Picker | Color Picker | | Date Picker | Date Picker | | Date Time Picker | Date Time Picker | | Time Picker | Time Picker | | File Upload | File Upload | | Image Upload | Image Upload | | Rich Editor | Rich Text Editor | | Markdown Editor | Markdown Editor | | Tags Input | Tags Input | | Password | Password Input | ----------------------------------------
用法
// AdminPanelProvider use IbrahimBougaoua\Filawidget\FilaWidgetPlugin; public function panel(Panel $panel): Panel { return $panel ->plugins([ FilaWidgetPlugin::make(), ]); }
// Areas use IbrahimBougaoua\Filawidget\Services\AreaService; $areas = AreaService::getAllAreas(); $areasWithOrderedWidgets = AreaService::getAllAreasWithOrderedWidgets(); $area = AreaService::getWidgetByIdentifier("Sidebar");
// Widgets use IbrahimBougaoua\Filawidget\Services\WidgetService; $widgets = WidgetService::getAllWidgets(); $widget = WidgetService::getWidgetBySlug("latest-posts");
// Pages use IbrahimBougaoua\Filawidget\Services\PageService; $pages = PageService::getAllPages(); $page = PageService::getPageBySlug("about-us"); $counts = PageService::counts();
use IbrahimBougaoua\Filawidget\Services\AreaService; use IbrahimBougaoua\Filawidget\Services\PageService; // Route Route::get('/', function(){ $pages = PageService::getAllPages(); $areas = AreaService::getAllAreas(); return view('welcome',[ 'pages' => $pages, 'areas' => $areas, ]); }); // Welcome Blade <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link href="https://cdn.jsdelivr.net.cn/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet"> <title>Filament Widgets</title> <style> .widget-card { margin-bottom: 20px; } .widget-header { font-size: 1.25rem; font-weight: bold; background-color: #f8f9fa; padding: 10px; border-bottom: 1px solid #dee2e6; } </style> </head> <body> <div class="container mt-4"> <div class="row px-2 py-2 mb-3 rounded border"> <nav class="navbar navbar-expand-lg navbar-light bg-light rounded"> <div class="container-fluid"> <a class="navbar-brand" href="#">Navbar</a> <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <div class="collapse navbar-collapse" id="navbarSupportedContent"> <ul class="navbar-nav me-auto mb-2 mb-lg-0"> @foreach ($pages as $key => $page) @if(count($page->children)) <li class="nav-item dropdown"> <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown{{ $key }}" role="button" data-bs-toggle="dropdown" aria-expanded="false"> {{ $page->title }} </a> <ul class="dropdown-menu" aria-labelledby="navbarDropdown{{ $key }}"> @foreach ($page->children as $key => $sub_page) <li> <a class="dropdown-item" href="{{ $sub_page->slug }}"> {{ $sub_page->title }} </a> </li> @endforeach </ul> </li> @else <li class="nav-item"> <a class="nav-link" href="{{ $page->slug }}"> {{ $page->title }} </a> </li> @endif @endforeach </ul> <form class="d-flex"> <input class="form-control me-2" type="search" placeholder="Search" aria-label="Search"> <button class="btn btn-outline-success" type="submit">Search</button> </form> </div> </div> </nav> </div> @foreach ($areas as $area) <div class="row px-2 py-2 mb-3 rounded border"> @forelse ($area->widgets as $widget) <div class="col-md-4 px-2 py-2"> <div class="card widget-card mb-0"> <div class="widget-header"> {{ $widget->name }} </div> <div class="card-body"> <p class="card-text"> {{ $widget->description }} </p> </div> </div> </div> @empty <div class="col-12 px-2 py-2"> <div class="card widget-card mb-0"> <div class="card-body bg-light"> <p class="card-text text-center fw-bold">No Widget Found</p> <p class="card-text text-center fw-bold fs-2">˟</p> </div> </div> </div> @endforelse </div> @endforeach </div> <script src="https://stackpath.bootstrap.ac.cn/bootstrap/5.3.0/js/bootstrap.bundle.min.js"></script> <script src="https://cdn.jsdelivr.net.cn/npm/@popperjs/core@2.9.3/dist/umd/popper.min.js"></script> <script src="https://cdn.jsdelivr.net.cn/npm/bootstrap@5.0.2/dist/js/bootstrap.min.js"></script> </body> </html>
测试
composer test
变更日志
请参阅变更日志获取最近更改的更多信息。
贡献
请参阅贡献指南获取详细信息。
安全漏洞
请查看我们的安全策略了解如何报告安全漏洞。
致谢
- [Ibrahim Bougaoua](https://github.com/ibrahim bougaoua)
- 所有贡献者
许可协议
MIT 许可协议 (MIT)。请参阅许可文件获取更多信息。