Для нашего любимого фреймворка существует с десяток различных админок и ещё больше генераторов, выбор может показаться настолько запутанным, что некоторые пишут исключительно свои решения. Я не работал со всеми и не могу утверждать, что какие то лучше/хуже, но могу рассказать об 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('Управление')
);
}
}
Обновим страницу и посмотрим на результат.
Этот минимальный пример даёт понять написание кода с использованием пакета и если вам понравился материал, изложение, дайте обратную связь и мы рассмотрим эту тему более углубленно.
Комментарии (5)
Можно полный пример блога например )
Очень интересная система
материал полезный. рассмотрите тему ещё :)
в файле ProjectListScreen вместо
нужно использовать
а в функции layout вместо
вот это
в рутах вместо
нужно использовать
для чего использовался в модели трейт MultiLanguageTrait для меня осталось загадкой!