mmaurice/modulate-project

Modx Evolution 3.x 的模块生成项目

1.3.5 2024-02-16 11:19 UTC

This package is auto-updated.

Last update: 2024-09-16 12:42:43 UTC


README

Language Language Language

mmaurice/modulatte-project 项目模块包

内容

安装

安装基本模块 Modulatte

root@ssh:~/core/custom/packages/main/#: cd assets/modules
root@ssh:~/core/custom/packages/main/assets/modules/#: create-project mmaurice/modulatte-project modulatte

包文件夹

资源 (resources)

资源目录包含以下子目录:-- scripts - 包含扩展模块功能的必要 JS 脚本 -- styles - 包含扩展模块功能的必要 CSS 样式 -- views - 包含扩展模块功能的必要 BLADE 模板

重要的是要理解,模块的工作机制使用了基本模板,这些模板包含在包 mmaurice\modulatte-support 中。但如果需要扩展某个 blade 模板文件,需要将该文件(包括目录结构)从目录 /vendor/mmaurice/modulatte-support/resource/views/* 复制到模块的目录 /resources/views/*。但有一个细节需要注意,在包的模板中目录 tab 包含所有默认 tab 的基本模板。如果需要为模块中的一个特定 tab 定制模板,需要将文件 /vendor/mmaurice/modulatte-support/resource/views/tab/* 复制到目录 /resources/views/tabs/<tab-name>/*

此外,在目录 resources 中也可以创建其他必要的目录。例如,imagesfontssaasscss 等。

模块代码 (modules)

modules 目录包含模块目录列表。目录名必须大写

在基本实现中,目录包含对模块工作最重要的文件:-- Controllers - 用于放置 tab 控制器逻辑的目录 -- Models - 用于放置 tab 模型的目录 -- Module.php - 模块的基本文件(用于初始化和扩展)

控制器包含初始化 CRUD 模块的基方法:-- index - 显示模块 tab 主界面 -- list - 显示实体列表 -- create - 显示创建实体界面 -- update - 显示编辑实体界面 -- clone - 克隆实体 -- delete - 删除实体

此外,还有以下服务方法:-- actionBar - 用于管理 tab 的 Action Bar 按钮 -- controlBar - 用于管理列表的 Control Bar 按钮 -- groupBar - 用于管理列表的 Group Bar 按钮 -- model - 输出当前模型对象(取决于 tab)

对于更多细节,建议学习模块原始控制器的代码

模型也包含自己的方法层次结构和逻辑。 稍后描述

加载器 (bootstrap.php)

用于预加载模块核心。作为自动加载的替代方案,但未来(在多模块过渡之后)可能会失去意义。

入口点 (index.php)

入口点,用于连接模块加载器,同时在部署时复制到公共模块目录

模块初始化 (initialize.php)

入口点,用于初始化模块加载器

命令

目前不支持命令,但计划在未来创建。

用法

基本应用

简单的应用实现位于模块的 SiteContentModule 目录中 (~/modules/SiteContentModule/)。首先需要创建模块文件。

namespace Modulatte\Module\SiteContentModule;

class Module extends \mmaurice\modulatte\Support\Module
{
    // Наименование модуля
    public function name()
    {
        return 'Справочник ресурсов';
    }

    // Основная иконка модуля
    public function icon()
    {
        return 'fa fa-folder-open';
    }

    // Номер позиции в общем списке модулей
    public function position()
    {
        return 10;
    }

    // Массив табов, которые необходимо скрыть в панели табов. Сами страницы при этом продолжают функционировать (необходимо для иерархических сущностей)
    // Необходимо перечислить slug табов, которые будут скрыты
    public function hideTabs()
    {
        return [];
    }
}

接下来,需要创建一个控制器(MainController - 默认控制器且必须存在),在其中只需要列出以下参数

namespace Modulatte\Module\SiteContentModule\Controllers;

use Modulatte\Module\SiteContentModule\Models\SiteContent;

class MainController extends \mmaurice\modulatte\Support\Controllers\CrudController
{
    // Порядковый номер позиции модуля в табах (не обязательно)
    protected $position = 0;

    // Уникальное наименование модуля (обязательно)
    protected $slug = 'main';

    // Наименование таба (Обязательно)
    protected $name = 'Страны';

    // Релевантная модель (используется расширенная базовая модель Eloquent)
    protected $model = Countries::class;

    // Ограничение в выодаче результатов на страницу пагинации (не обязательно)
    // 0 для отключения. По-умолчанию, 25
    protected $pagination = 25;

    // Набор alias для выводимых в списочном интерфейсе кнопок в controlBar. По-умолчанию: edit, delete
    // Кнопки выводятся в перечисленном порядке. Поддерживается кастомизация. (не обязательно)
    protected $controlButtons = ['edit', 'delete'];
}

该控制器与相关模型协同工作。需要在该目录下创建模型。基本实现可能如下所示

namespace Modulatte\Module\SiteContentModule\Models;

use Illuminate\Http\Request;
use mmaurice\modulatte\Support\Traits\Model\ModuleExtensionTrait;

class SiteContent extends \EvolutionCMS\Models\SiteContent
{
    use ModuleExtensionTrait;

    // Наименование PK-поля
    // (не обязательно, по-умолчанию, id)
    public static function pkField()
    {
        return 'id';
    }

    // Массив наименований полей
    public function fieldsNames()
    {
        return [];
    }

    // Массив полей, выводимых в таблице общего списка
    public function listFields()
    {
        return [];
    }

    // Массив полей, добавляемых автоматически в начало таблицы общего списка
    // (не обязательно, по-умолчанию, только id)
    public function prependListFields()
    {
        return ['id'];
    }

    // Массив полей, добавляемых автоматически в конец таблицы общего списка
    // (не обязательно, по-умолчанию, не требуется)
    public function appendListFields()
    {
        return [];
    }

    // Массив полей, выводимых в интерфейсе создания\изменения записи
    public function itemFields()
    {
        return [];
    }

    // Массив полей, добавляемых автоматически в начало интерфейса создания\изменения записи
    // (не обязательно, по-умолчанию, только id)
    public function prependItemFields()
    {
        return ['id'];
    }

    // Массив полей, добавляемых автоматически в конец интерфейса создания\изменения записи
    // (не обязательно, по-умолчанию, только created_at и updated_at)
    public function appendItemFields()
    {
        return ['created_at', 'updated_at'];
    }

    // Массив полей, доступных для фильтрации
    public function filterFields()
    {
        return [];
    }

    // Массив полей, доступных для сортировки общего списка
    public function orderFields()
    {
        return [];
    }

    // Массив классов для полей в общем списке
    public function listFieldsClasses()
    {
        return [];
    }

    // Массив классов для полей в интерфейсе создания\изменения записи
    public function itemFieldsClasses()
    {
        return [];
    }

    // Массив классов для полей фильтра
    public function filterFieldsClasses()
    {
        return [];
    }
}

更详细的实现可以查看模型 ~/modules/SiteContentModule/Models/SiteContent.php

高级应用

高级应用提供扩展模块基本功能的自定义工具。以下是一些典型示例

层次实体

在编辑某条记录的界面中,可以实现从从属关系表输出子记录列表的功能。这可以通过在控制器中添加 childs 方法来实现

    public function childs()
    {
        $this->addChild('regions', 'country_id', 'id');
    }

主要的魔法发生在 addChild 方法中。第一个参数是要从属的另一个控制器的slug。第二个参数是关联控制器的模型中用于关联的字段名称。第三个参数是当前控制器模型的主键字段名称。在 childs 方法中可以列出多个从属关系。在这种情况下,列表将依次输出。

动作

控制器支持基本动作,如

-- index() - 当访问表时调用默认方法。默认调用 list() 方法 -- list() - 显示记录列表的方法 -- create() - 创建记录的方法 -- update() - 更新记录的方法 -- delete() - 删除记录的方法

它们都有可插入逻辑的方法。如果不需要自定义外观但需要自定义逻辑,则可以使用这些方法

    use Illuminate\Database\Eloquent\Model;

    protected function onList()
    {
        // ...
    }

    protected function onCreate()
    {
        // ...
    }

    protected function onUpdate(Model $item)
    {
        // ...
    }

    protected function onClone(Model $item)
    {
        // ...
    }

    protected function onDelete(Model $item)
    {
        // ...
    }

通过查看这些方法的源代码,可以自定义每个模块的行为。

操作栏

在控制器的 actionBar() 方法中,可以为每个动作自定义在操作栏中输出的按钮。源代码中提供了实现这些按钮的完整示例。

同样,也可以自定义每个动作的输出面板。为此,需要覆盖并更新相应的方法

    // Кастомизация actionBar для действия index
    public function actionBarIndex(Collection $actions)
    {
        // ...
    }

    // Кастомизация actionBar для действия list
    public function actionBarList(Collection $actions)
    {
        // ...
    }

    // Кастомизация actionBar для действия create
    public function actionBarCreate(Collection $actions)
    {
        // ...
    }

    // Кастомизация actionBar для действия update
    public function actionBarUpdate(Collection $actions)
    {
        // ...
    }

具体的实现示例需要查看源代码。

控制栏

在列表界面中,可以管理每个按钮的显示、设计以及扩展其列表。对于现有按钮,可以通过重定义以下方法来自定义

    // Набор alias для выводимых в списочном интерфейсе кнопок в controlBar. По-умолчанию: edit, delete
    // Кнопки выводятся в перечисленном порядке. Поддерживается кастомизация. (не обязательно)
    protected $controlButtons = ['edit', 'delete'];

    // Кастомизация controlBar для контрола edit
    public function controlBarEdit(Model $model)
    {
        // ...
    }

    // Кастомизация controlBar для контрола delete
    public function controlBarDelete(Model $model)
    {
        // ...
    }

具体的实现示例需要查看源代码。类似地,可以扩展字段列表

分组栏

在列表界面中,可以管理多个行分组选择元素的显示。要启用此功能,需要在控制器中声明哪些动作将适用于列表,并可以自定义输出

    protected $groupBar = ['clone', 'delete'];

    // Кастомизация groupBar для контрола clone
    public function groupBarClone()
    {
        // ...
    }

    // Кастомизация groupBar для контрола delete
    public function groupBarDelete()
    {
        // ...
    }

还可以自定义动作或重定义它们的逻辑部分

    protected function onGroupClone()
    {
        // ...
    }

    protected function onGroupDelete()
    {
        // ...
    }

    public function groupClone()
    {
        // ...
    }

    public function groupDelete()
    {
        // ...
    }

但是,如果需要禁用此功能,只需清除可用动作的数组即可

    protected $controlButtons = [];
字段输出自定义

在模型中,可以为任何接口中任何字段的输出设置自定义。了解模板层次结构后,可以了解哪些字段类型已经可以输出,哪些需要自己编程。要实现自定义,需要使用带字段名称的方法名称的突变器。这些方法的列表如下

-- get{FieldName}ListHeadField() - 自定义列表界面中字段 {FieldName} 的标题的输出方法。默认输出为文本 -- get{FieldName}ListField() - 自定义列表界面中字段 {FieldName} 输出的方法。默认输出为文本 -- get{FieldName}EditorField() - 自定义编辑界面中字段 {FieldName} 输出的方法。默认输出为文本输入 -- get{FieldName}FilterField() - 自定义过滤器面板中字段 {FieldName} 输出的方法。默认输出为文本输入

模型示例中有每种类型的完整实现。建议查看源代码。

过滤规则自定义

为了在模型中根据特定字段自定义过滤规则,提供了一个filterRules()方法,可以在其中列出用于按特定字段过滤结果的回调方法。默认情况下,过滤是按照严格匹配值进行的。但是,有时需要过滤结果,例如在两个日期之间。在这种情况下,过滤规则可能如下所示

    public function filterRules()
    {
        return [
            'date_start' => function ($query) {
                $field = $this->mappedFilterFieldValue('date_start');

                $query->when(!is_null($field) and !empty($field), function ($query) use ($field) {
                    $query->where('date_start', '>=', $field);
                });

                return $query;
            },
            'date_end' => function ($query) {
                $field = $this->mappedFilterFieldValue('date_end');

                $query->when(!is_null($field) and !empty($field), function ($query) use ($field) {
                    $query->where('date_end', '<=', $field);
                });

                return $query;
            },
        ];
    }

在一般情况下,过滤规则在Eloquent模型中类似于作用域方法