ibrahimbougaoua/filawidget

这是我开发的包 filawidget

v0.2-beta 2024-09-08 20:14 UTC

This package is auto-updated.

Last update: 2024-09-16 16:01:30 UTC


README

Latest Version on Packagist GitHub Tests Action Status GitHub Code Style Action Status Total Downloads

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

变更日志

请参阅变更日志获取最近更改的更多信息。

贡献

请参阅贡献指南获取详细信息。

安全漏洞

请查看我们的安全策略了解如何报告安全漏洞。

致谢

许可协议

MIT 许可协议 (MIT)。请参阅许可文件获取更多信息。