
В прошлом на хабре публиковалась статья «Orchid CMS — ещё одна CMS на Laravel», а теперь спустя два года и больше 100 релизов попробуем разобрать ошибки и проблемы которые стояли на пути разработки.
1. Позиционирование
В самом заголовке предыдущей статьи и во многих других указывалась, аббревиатура CMS, что во влажных мечтах должно было привлечь больше интереса к разработке. Одновременно с этим, пакет не предлагал ни каких готовых решений в тиражировании веб-сайтов, а только управление в администрировании.
В итоге было только хуже… Само это сочетание отталкивало опытных пользователей устанавливать, а новички ожидали увидеть привычные для себя возможности, вместо, некоторой свободы.
2. Формы
Когда речь заходит об панелях администрирования, впервую очередь имеет значение формы и как с ними работать. Для примера будем рассматривать форму построенную на blade-шаблонах, которая отображает и позволяет редактировать данные некоторого объекта:
<form action="..."> <input type="text" name="title"> <input type="text" name="price"> <input type="submit" value="Изменить"> </form>
Менеджеры, редакторы и пользователи в целом хотят видеть как можно больше об объекте редактирования и в этом нет ни каких проблем если всю информацию можно взять из одной таблицы, но когда информация очень растянута?
Самым популярным решением, что я видел, было просто разделение формы на несколько классов и файлов с представлением. Они отображались в виде вкладок на форме, информация в которых была бы сгруппирована по связям:
<form action="..." id="main"> <input type="text" name="title"> <input type="text" name="price"> <input type="submit" value="Изменить"> </form> <form action="..." id="editors"> <!-- Связи с редакторами --> <input type="submit" value="Применить"> </form> <form action="..." id="history"> <!-- История изменений --> <input type="submit" value="Восстановить"> </form>
Именно это и было воспроизведено… Конечно с небольшими изменениями и особенностями, но смысл оставался прежним. В создании отдельного класса группирующего все обработки в виде других форм:

Накладывая на предыдущие примеры, в коде каждая форма выглядела приблизительно следующим образом:
class Example extends Form { public $name = 'General'; public function rules(): array { return [ 'title' => 'required|max:160' ]; } public function display(): View { return view('main'); } public function persist(Model $model) { //.. return $model->save(); } }
И формирование в контроллере всей группы:
class ExampleController extends Controller { public function index(Model $model) { $form = new FormGroup([ Example::class // editors.. // history.. ]); return $form->render($model); } }
Кроме разделения самой формы и небольшой организации кода это не принесло ни каких других результатов. В итоге:
- Такой способ ни как не помогал решать дублирование нескольких элементов, например, поле «Заголовок» у объекта мог встречаться множество раз, но полной копии формы ни разу.
- При отличных от «стандартных» действий нужно было создавать отдельный метод контроллера, что напрочь портило весь смысл деления формы.
- Ни каких плюсов в автоматизации построения представления, все так же необходимо указывать вручную.
3. CRUD
Самый спорный вариант, который очень часто фигурирует в новостных лентах и блогах разработчиков. Такой подход используется почти всеми альтернативными пакетами, сделали и его. По примеру одной известной системы где все храниться в одной таблице была создана модель с динамическим JSON полем:

В отдельном классе описывались необходимые для создания и редактирования поля, а так же базовые действия:
class Example extends Behavior { public $name = 'Main'; public function rules(): array { return [ 'title' => 'required|max:160' ]; } public function fields(): array { return [ Input::make('title') ->type('text') ->max(160) ->required(), ]; } }
Благодаря такому подходу, написание простейшего кода было быстрым из-за полного отсутствия работы с представлением, но принесло не мало проблем:
- Нестандартные операции не доступны в рамках объекта.
- Динамическое представление, вроде модальных окон с загрузкой информации недоступно.
- При малейшем отклонении, например, построения графиков мы снова возвращаемся к написанию
bladeшаблонов со стилями и сценариями. - Невозможность использовать данные из отличных от базы данных источников.
- Работа только в рамках одной таблицы, это можно было исправить, но в первой и последней реализации так было.
Исправление
Вариант с CRUD был основан на полном автоматизации представления, что в итоге привело к новой реализации. Как некоторый эталон на этот раз был взят продукт Visual Studio LightSwitch, который позволял пользоваться человеку без глубоких знаний разработки.
Естественно такого эффекта нам не нужно и это даже не является целью, при этом почти все технические возможности присутствовали в Laravel или пользовательских реализаций.
Решено было сосредоточится только на одно единственном аспекте — Экраны.

Экран — это все, что пользователь видит на странице и какие действия может совершать.
Все это описывается в одном классе, он не знает откуда берутся данные, это может быть: база данных, API или любые другие внешние источники. Построение внешнего вида основано на слоях и всё, что необходимо было сделать это лишь определить какие данные будут показаны в том или ином шаблоне.
Слой же может представлять из себя некоторый макет, который может быть таблицей, строкой, графиком и т.п. При этом каждый макет может включать в себя другой макет, то есть вложенность. Например экран делится двумя колонками, в левой поля для заполнения, справа справочная таблица и график и т.д.
Для управления над данными отображаемые на экране предусмотрены команды, которые берут на себя обработку.
class ExampleScreen extends Screen { public $name = 'Example Screen'; public function query(Model $model): array { return [ 'model' => $model ]; } public function commandBar(): array { return [ Link::make('Веб-сайт') ->link('http://orchid.software/ru') ->icon('icon-globe-alt'), ]; } public function layout(): array { return [ Layout::rows([ Input::make('model.title') ->type('text') ->max(160) ->required(), ]) ]; } }
Остановка произошла на таком варианте, так как он держит здоровый баланс между полным написанием и автоматической генерации, при этом оставаясь понятным.
ссылка на оригинал статьи https://habr.com/ru/post/460471/
Добавить комментарий