Для нашего любимого фреймворка существует с десяток различных админок и ещё больше генераторов, выбор может показаться настолько запутанным, что некоторые пишут исключительно свои решения. Я не работал со всеми и не могу утверждать, что какие то лучше/хуже, но могу рассказать об ORCHID и как с ней работать ~ за 10 минут.
Всегда начинайте с данных
Буду надеяться, что вы уже установили фреймворк и платформу, создали базу данных и даже запустили веб-сервер. Очевидным продолжением будет написание моделей и миграций для вашей базы данных.
Создадим новую модель "Проекты":
php artisan make:model Project -m
Используя флаг
-m, будет создан файл нашей миграции
Добавим ей поле имя (уникальный идентификатор и время создания/обновления уже должны стоять по умолчанию)
namespace App;
use Illuminate\Database\Eloquent\Model;
class Project extends Model
{
/**
* @var array
*/
protected $fillable = [
'name'
];
}
Не забудем изменить и файл миграции:
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateProjectsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('projects', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('projects');
}
}
Отлично, осталось только применить наши изменения к базе данных используя команду:
php artisan migrate
Добавим экран
На текущем этапе нам нужно лишь добавить простое действия, вроде создания, и отображения таблицы наших "Проектов" . Большинство решений предлагает создать единственный класс, в котором был бы описан весь CRUD, но ORCHID предлагает иной механиз - Экраны, где разработчик описывает то, что должно отображаться на странице в браузере.
Создадим свой собственный экран для отображения списка, для этого выполним команду:
php artisan orchid:screen ProjectListScreen
В директории app/Orchid/Screens будет создан новый класс ProjectListScreen, давай те разберём его:
namespace App\Orchid\Screens;
use Orchid\Screen\Screen;
class ProjectListScreen extends Screen
{
/**
* Свойства имя и описание отвечают за то,
* какое название будет отображаться
* на экране пользователя и заголовках.
*/
public $name = 'ProjectListScreen';
public $description = 'ProjectListScreen';
/**
* Метод определяющие все входные данные экрана,
* именно в нём должны вызываться запросы к базе данных,
* api или любые другие (не обязательно явно),
* результатом которого должен быть массив,
* обращение к которым будут использоваться его ключи.
*/
public function query(): array
{
return [];
}
/**
* Определяет управляющие кнопки и события
* которые должны будут произойти по нажатию
*/
public function commandBar(): array
{
return [];
}
/**
* Набор отображений,
* строк, таблицы, графиков,
* модальных окон и их комбинация
*/
public function layout(): array
{
return [];
}
}
Главным отличием экрана от контроллера, является определённая заранее структура, которая обслуживает только одну страницу определяя данные и события.
Как и контроллер, экран нужно регистрировать в файле маршрутов, определим его в файле для панели администрирования routes/platform.php:
use App\Orchid\Screens\ProjectListScreen;
$this->screen('projects', ProjectListScreen::class)->name('platform.projects');
Этим мы определим url адрес /dashboard/projects будет обрабатываться классом ProjectListScreen и иметь системное имя platform.projects
Посмотрим на результат в браузере:

Видим только указанные свойства нашего класса, добавим возможность с создания "Проектов", для этого определим поле ввода и метод сохранения, основная визуальная составляющая описывается в виде классов Layouts, это могут быть таблицы, строки, метрики и т.п.
Добавим вариант с отображением в виде строки, которая будет содержать простое поле для ввода:
namespace App\Orchid\Screens;
use Orchid\Screen\Fields\InputField;
use Orchid\Screen\Layouts;
use Orchid\Screen\Screen;
class ProjectListScreen extends Screen
{
/**
* Свойста имя и описание отвечают за то,
* какое название будет отображаться
* на экране пользователя и заголовках.
*/
public $name = 'ProjectListScreen';
/**
* @var string
*/
public $description = 'ProjectListScreen';
/**
* Метод определяющие все входные данные экрана,
* именно в нём должны вызываться запросы к базе данных,
* api или любые другие (не обязательно явно),
* результатом которого должен быть массив,
* обращение к которым будут использоваться его ключи.
*/
public function query(): array
{
return [];
}
/**
* Определяет управляющие кнопки и события
* которые должны будут произойти по нажатию
*/
public function commandBar(): array
{
return [];
}
/**
* Набор отображений,
* строк, таблицы, графиков,
* модальных окон и их комбинация
*/
public function layout(): array
{
return [
Layouts::rows([
InputField::make('project.name')
->type('text')
->title('Название проекта')
]),
];
}
}
Обновим страницу и удостоверимся, что поле действительно отображается на экране.

Хоть поле и отображается оно ещё не несёт ни какого смысла без дополнительной обработки, так сделаем же её! Для этого добавим кнопку на командную строку и определим её событие:
namespace App\Orchid\Screens;
use App\Project;
use Illuminate\Http\Request;
use Orchid\Screen\Fields\InputField;
use Orchid\Screen\Layouts;
use Orchid\Screen\Link;
use Orchid\Screen\Screen;
use Orchid\Support\Facades\Alert;
class ProjectListScreen extends Screen
{
/**
* Свойства имя и описание отвечают за то,
* какое название будет отображаться
* на экране пользователя и заголовках.
*/
public $name = 'ProjectListScreen';
/**
* @var string
*/
public $description = 'ProjectListScreen';
/**
* Метод определяющие все входные данные экрана,
* именно в нём должны вызываться запросы к базе данных,
* api или любые другие (не обязательно явно),
* результатом которого должен быть массив,
* обращение к которым будут использоваться его ключи.
*/
public function query(): array
{
return [];
}
/**
* Определяет управляющие кнопки и события
* которые должны будут произойти по нажатию
*/
public function commandBar(): array
{
return [
Link::name('Добавить проект')
->method('createProject'),
];
}
/**
* Набор отображений,
* строк, таблицы, графиков,
* модальных окон и их комбинация
*/
public function layout(): array
{
return [
Layouts::rows([
InputField::make('project.name')
->type('text')
->title('Название проекта')
]),
];
}
/**
* @param Request $request
* @return \Illuminate\Http\RedirectResponse
*/
public function createProject(Request $request)
{
Project::create($request->get('project'));
Alert::success('Проект был успешно создан');
return back();
}
}
На экране будет отображена новая кнопка "Добавить проект", по нажатию на которой будет выполнен метод createProject.

Отлично, но этого явно не достаточно для полноценной работы, так как мы невидим уже созданные проекты, добавим их список к экрану, для этого создадим новый Layout типа таблицы используя команду:
php artisan orchid:table ProjectListTable
В директории app/Orchid/Layouts будет создан класс ProjectListTable со следующим содержанием:
namespace App\Orchid\Layouts;
use Orchid\Screen\Layouts\Table;
class ProjectListTable extends Table
{
/**
* Источник данных
*
* @var string
*/
public $data = '';
/**
* Поля которые будут отображаться ввиде колонок
*
* @return array
*/
public function fields(): array
{
return [];
}
}
Нам необходимо определить его в экране и передать ему данные, что бы максимально использовать возможности вернёмся к модели Project и дополним её трейтом MultiLanguageTrait:
namespace App;
use Illuminate\Database\Eloquent\Model;
use Orchid\Platform\Traits\MultiLanguageTrait;
class Project extends Model
{
use MultiLanguageTrait;
/**
* @var array
*/
protected $fillable = [
'name'
];
}
После этого вернемся к экрану и определим данные :
namespace App\Orchid\Screens;
use App\Orchid\Layouts\ProjectListTable;
use App\Project;
use Illuminate\Http\Request;
use Orchid\Screen\Fields\InputField;
use Orchid\Screen\Layouts;
use Orchid\Screen\Link;
use Orchid\Screen\Screen;
use Orchid\Support\Facades\Alert;
class ProjectListScreen extends Screen
{
/**
* Свойства имя и описание отвечают за то,
* какое название будет отображаться
* на экране пользователя и заголовках.
*/
public $name = 'ProjectListScreen';
/**
* @var string
*/
public $description = 'ProjectListScreen';
/**
* Метод определяющие все входные данные экрана,
* именно в нём должны вызываться запросы к базе данных,
* api или любые другие (не обязательно явно),
* результатом которого должен быть массив,
* обращение к которым будут использоваться его ключи.
*/
public function query(): array
{
$projects = Project::paginate();
return [
'projects' => $projects
];
}
/**
* Определяет управляющие кнопки и события
* которые должны будут произойти по нажатию
*/
public function commandBar(): array
{
return [
Link::name('Добавить проект')
->method('createProject'),
];
}
/**
* Набор отображений,
* строк, таблицы, графиков,
* модальных окон и их комбинация
*/
public function layout(): array
{
return [
Layouts::rows([
InputField::make('project.name')
->required()
->type('text')
->title('Название проекта')
]),
ProjectListTable::class,
];
}
/**
* @param Request $request
* @return \Illuminate\Http\RedirectResponse
*/
public function createProject(Request $request)
{
Project::create($request->get('project'));
Alert::success('Проект был успешно создан');
return back();
}
}
В методе query определил ключ projects содержащий список проектов, который будет доступен во всех шаблонах и автоматически подставляться в поля/колонки и т.п.
Осталось только определить ключ и колонки в нашей таблице:
namespace App\Orchid\Layouts;
use Orchid\Screen\Layouts\Table;
use Orchid\Screen\TD;
class ProjectListTable extends Table
{
/**
* @var string
*/
public $data = 'projects';
/**
* @return array
*/
public function fields(): array
{
return [
TD::set('name','Имя проекта'),
TD::set('created_at','Дата создания'),
TD::set('updated_at','Дата обновления')
];
}
}
Обновим страницу и посмотрим на результат.

Одинокое поле рядом с таблице смотрится не лучшим образом, уберём её в модальное окно, для этого обернём наше поля для ввода и изменением кнопку следующим образом:
namespace App\Orchid\Screens;
use App\Orchid\Layouts\ProjectListTable;
use App\Project;
use Illuminate\Http\Request;
use Orchid\Screen\Fields\InputField;
use Orchid\Screen\Layouts;
use Orchid\Screen\Link;
use Orchid\Screen\Screen;
use Orchid\Support\Facades\Alert;
class ProjectListScreen extends Screen
{
/**
* Свойста имя и описание отвечают за то,
* какое название будет отображаться
* на экране пользователя и заголовках.
*/
public $name = 'ProjectListScreen';
/**
* @var string
*/
public $description = 'ProjectListScreen';
/**
* Метод определяющие все входные данные экрана,
* именно в нём должны вызываться запросы к базе данных,
* api или любые другие (не обязательно явно),
* результатом которого должен быть массив,
* обращение к которым будут использоваться его ключи.
*/
public function query(): array
{
$projects = Project::paginate();
return [
'projects' => $projects
];
}
/**
* Определяет управляющие кнопки и события
* которые должны будут произойти по нажатию
*/
public function commandBar(): array
{
return [
Link::name('Добавить проект')
->title('Добавить проект')
->modal('createProjectModal')
->method('createProject'),
];
}
/**
* Набор отображений,
* строк, таблицы, графиков,
* модальных окон и их комбинация
*/
public function layout(): array
{
return [
Layouts::modals([
'createProjectModal' => Layouts::rows([
InputField::make('project.name')
->required()
->type('text')
->title('Название проекта')
]),
]),
ProjectListTable::class,
];
}
/**
* @param Request $request
* @return \Illuminate\Http\RedirectResponse
*/
public function createProject(Request $request)
{
Project::create($request->get('project'));
Alert::success('Проект был успешно создан');
return back();
}
}

На этом наш экран почти готов, осталось позаботиться о выводе его в меню и хлебных крошках:
Для указания хлебных крошек отредактируем файл routes/breadcrumbs.php, добавив в самый конец:
// Platform -> Projects
Breadcrumbs::for('platform.projects', function ($trail) {
$trail->parent('platform.index');
$trail->push('Проекты');
});

А для указания в меню необходимо добавить добавить в класс композер /app/Orchid/Composers/MainMenuComposer.php
namespace App\Orchid\Composers;
use Orchid\Platform\ItemMenu;
use Orchid\Platform\Dashboard;
class MainMenuComposer
{
/**
* @var Dashboard
*/
private $dashboard;
/**
* MenuComposer constructor.
*
* @param Dashboard $dashboard
*/
public function __construct(Dashboard $dashboard)
{
$this->dashboard = $dashboard;
}
/**
* Registering the main menu items.
*/
public function compose()
{
// Main
$this->dashboard->menu
->add('Main',
ItemMenu::setLabel('Проекты')
->setIcon('icon-folder')
->setRoute(route('platform.projects'))
->setGroupName('Управление')
);
}
}
Обновим страницу и посмотрим на результат.

Этот минимальный пример даёт понять написание кода с использованием пакета и если вам понравился материал, изложение, дайте обратную связь и мы рассмотрим эту тему более углубленно.
Laravel по-русски
Комментарии (5)
Можно полный пример блога например )
Очень интересная система
материал полезный. рассмотрите тему ещё :)
в файле ProjectListScreen вместо
нужно использовать
а в функции layout вместо
вот это
в рутах вместо
нужно использовать
для чего использовался в модели трейт MultiLanguageTrait для меня осталось загадкой!