В этом руководстве покажем, как разработать админку для небольшого проекта, используя встроенные инструменты Laravel. Этот процесс позволяет лучше понять структуру фреймворка, улучшить навыки работы с Laravel и почувствовать контроль над каждой частью приложения.
Глубокое понимание фреймворка: Создавая админку с нуля, вы изучаете работу Laravel изнутри, что помогает лучше понимать, как устроены маршруты, middleware, контроллеры и модели.
Полный контроль над функциональностью: Сами решаете, какие функции необходимы в админке, и избегаете лишнего кода, который может быть в сторонних пакетах.
Гибкость: Можете реализовать любую бизнес-логику, адаптированную под конкретные требования вашего проекта, без необходимости подстраиваться под ограничения готовых решений.
Минимальная зависимость от сторонних библиотек: Снижается вероятность конфликтов версий и уязвимостей, которые могут быть в сторонних пакетах.
Больше времени на разработку: Самостоятельная реализация функциональности (например, CRUD для сущностей) требует больше времени, чем использование готовых решений.
Меньше готовых инструментов: Сторонние пакеты часто предоставляют полезные функции «из коробки» (фильтры, сортировка, интерфейсы), которые нужно реализовывать вручную.
Ограниченный функционал в упрощенном подходе: Избегая ООП и сложных решений, можно упустить важные аспекты, такие как масштабируемость и модульность.
В этом руководстве используется следующее окружение:
cloud
Создайте пользователя lara
и добавьте его в группы sudo
и www-data
:
adduser lara
usermod -aG sudo lara
usermod -aG www-data lara
su - lara
Добавьте PPA
для PHP:
sudo add-apt-repository ppa:ondrej/php -y
sudo apt update
Установите PHP и расширения:
sudo apt install php8.3 php8.3-cli php8.3-fpm php8.3-mysql php8.3-curl php8.3-gd php8.3-mbstring php8.3-bcmath php8.3-xml php8.3-zip php8.3-intl php8.3-soap php8.3-redis -y
Обновите список пакетов:
sudo apt update
Скачайте установочный скрипт:
cd /usr/local/bin
sudo curl -sS https://getcomposer.org/installer -o composer-setup.php
Проверьте целостность файла:
HASH=$(curl -sS https://composer.github.io/installer.sig)
php -r "if (hash_file('sha384', 'composer-setup.php') === '$HASH') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
Установите Composer:
sudo php composer-setup.php --install-dir=/usr/local/bin --filename=composer
sudo composer self-update 2.7.8
Проверьте установку:
composer --version
Удалите старые версии:
sudo apt purge nodejs -y
sudo apt autoremove -y
sudo apt update
Установите Node.js 18.x:
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt install -y nodejs
Проверьте версии:
node -v
npm -v
Создайте папку для проекта:
cd /var
sudo mkdir www
sudo chown lara:www-data www
sudo chmod 775 www
cd www
Установите Nginx:
sudo apt install -y nginx
sudo ufw allow 'Nginx Full'
Настройте виртуальный хост:
sudo nano /etc/nginx/sites-available/lara.com
Вставьте:
server {
listen 80;
server_name <Публичный_IP-Адрес_Сервера или домен>;
root /var/www/laravel-admin/public;
index index.php index.html index.htm;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php8.3-fpm.sock;
}
location ~ /\.ht {
deny all;
}
}
Активируйте конфигурацию:
sudo ln -s /etc/nginx/sites-available/lara.com /etc/nginx/sites-enabled/
sudo unlink /etc/nginx/sites-enabled/default
Перезапустите службы:
sudo systemctl restart nginx
sudo systemctl restart php8.3-fpm
Создайте проект:
composer create-project laravel/laravel:^9.0 laravel-admin
Настройте права на папки и файлы:
sudo find /var/www/laravel-admin -type f -exec chmod 644 {} \;
sudo find /var/www/laravel-admin -type d -exec chmod 755 {} \;
cd laravel-admin/
sudo chown -R lara:www-data .
sudo find . -type f -exec chmod 664 {} \;
sudo find . -type d -exec chmod 775 {} \;
sudo chgrp -R www-data storage bootstrap/cache
sudo chmod -R ug+rwx storage bootstrap/cache
Установите расширение SQLite:
sudo apt install php8.3-sqlite3
Настройте подключение. В файле .env
измените строки:
DB_CONNECTION=sqlite
DB_DATABASE=/var/www/laravel-admin/database/database.sqlite
Создайте базу данных:
touch database/database.sqlite
Измените владельца и группу для файла database.sqlite
:
sudo chown lara:www-data /var/www/laravel-admin/database/database.sqlite
Запустите миграции:
php artisan migrate
Команду php artisan
нужно выполнять из корня проекта: /var/www/laravel-admin
.
Провайдеры — это важная часть Laravel, представляющая собой специальные классы для настройки и инициализации компонентов приложения. Они позволяют определить, как должны быть организованы и связаны различные элементы системы. Laravel автоматически загружает провайдеры, указанные в файле config/app.php
, что обеспечивает гибкость и модульность в управлении приложением.
RouteServiceProvider — это системный провайдер, который отвечает за маршрутизацию в приложении. Его задачи включают:
Этот провайдер помогает организовать маршруты, разделяя их на группы (например, для административной панели и пользовательской части), а также задавать общие правила для маршрутов, такие как middleware, префиксы или ограничения.
Файл RouteServiceProvider.php
находится в папке app/Providers
. Поменяем значение константы HOME
и отредактируем метод boot
:
class RouteServiceProvider extends ServiceProvider
{
public const HOME = '/dashboard';
public function boot()
{
$this->configureRateLimiting();
$this->routes(function () {
Route::middleware('api')
->prefix('api')
->group(base_path('routes/api.php'));
Route::middleware('web')
->group(base_path('routes/web.php'));
Route::middleware(['web', 'auth'])
->namespace('App\Http\Controllers\Dashboard')
->prefix('dashboard')
->group(base_path('routes/dashboard.php'));
});
}
// Остальной код провайдера
}
Свойство HOME:
Определяет маршрут перенаправления для авторизованных пользователей после успешной аутентификации. В данном случае пользователи будут направлены на /dashboard
. Это удобно для централизованного управления перенаправлением: если маршрут изменится, достаточно будет обновить только значение константы.
public const HOME = '/dashboard';
Метод boot:
В методе boot
выполняется основная настройка маршрутов. Здесь используется метод routes
, который позволяет описать правила маршрутизации для различных частей приложения.
Маршруты для веб-приложения:
Route::middleware('web')
->group(base_path('routes/web.php'));
Маршруты клиентской части подключаются из файла routes/web.php
. Они используют только middleware web, что обеспечивает поддержку сессий, CSRF и других веб-функций.
Маршруты административной панели:
Route::middleware(['web', 'auth'])
->namespace('App\Http\Controllers\Dashboard')
->prefix('dashboard')
->group(base_path('routes/dashboard.php'));
Для маршрутов административной панели добавлено:
App\Http\Controllers\Dashboard
.dashboard
, что делает их доступными по URL /dashboard/...
.routes/dashboard.php
.Почему это важно?
Эта структура делает приложение модульным и удобным для масштабирования:
Создайте файл routes/dashboard.php
и добавьте следующий маршрут:
use Illuminate\Support\Facades\Route;
Route::get('/', function () {
return view('dashboard.app');
})->name('dashboard.home');
Route::get('/')
: Этот маршрут отвечает на GET-запросы по адресу /dashboard
(так как в RouteServiceProvider
для административной панели установлен префикс dashboard
).
Функция обратного вызова (callback
): В функции обратного вызова возвращается вид (view) dashboard.app
. Это базовый шаблон административной панели, который был создан ранее и наследует структуру из master.blade.php
.
Именование маршрута: ->name('dashboard.home')
. Именование маршрута позволяет обращаться к нему по имени dashboard.home
в шаблонах, контроллерах или при создании ссылок. Например, в Blade-шаблонах: <a href="{{ route('dashboard.home') }}">Главная</a>
.
Это главная страница административной панели.
Этот маршрут используется для рендеринга базового шаблона административной панели, который можно настроить и наполнить необходимым содержимым.
Для использования стандартных фронтенд-стилей и аутентификации в Laravel, необходимо установить пакет laravel/ui
. Этот пакет предоставляет базовые компоненты, такие как аутентификация, страницы входа и регистрации, а также позволяет использовать фронтенд-фреймворки, такие как Bootstrap
или Vue.js
.
Установите пакет laravel/ui
через Composer:
composer require laravel/ui
После установки пакета, выполните команду для генерации фронтенд-скелета с использованием Bootstrap:
php artisan ui bootstrap
Команду нужно выполнять из корня проекта: /var/www/laravel-admin
.
Это создаст необходимые файлы для интеграции Bootstrap в проект, включая шаблоны и стили.
После того, как вы установили и настроили laravel/ui
, вы можете сгенерировать стандартные страницы аутентификации (входа и регистрации). Для этого выполните команду:
php artisan ui bootstrap --auth
Согласитесь пересоздать файл Controller.php
.
Эта команда создаст необходимые контроллеры, маршруты и представления для аутентификации:
Установите необходимые JavaScript зависимости и скомпилируйте ресурсы с помощью npm:
npm install && npm run build
В случае зависания установки запустите команду еще раз.
После установки пакета laravel/ui
и настройки аутентификации, Laravel автоматически добавляет некоторые файлы и маршруты, которые не нужны в разработке админ-панели. Для очистки выполните следующие действия:
Контроллер HomeController
Контроллер HomeController.php
, созданный по умолчанию, часто не используется, так как его функциональность заменяется вашими собственными контроллерами.
Для удаления выполните команду:
rm app/Http/Controllers/HomeController.php
Маршрут home из routes/web.php
Маршрут для домашней страницы также создается автоматически:
Route::get('/home', [App\Http\Controllers\HomeController::class, 'index'])->name('home');
Его можно удалить из файла routes/web.php
, так как теперь маршрут перенаправления для аутентификации определяется константой HOME
в RouteServiceProvider
.
В файлах контроллеров, которые отвечают за аутентификацию и авторизацию, нужно заменить строку, указывающую путь для перенаправления после успешного входа/регистрации, на константу RouteServiceProvider::HOME
.
Эти файлы находятся в папке app/Http/Controllers/Auth/
и включают в себя следующие файлы:
ConfirmPasswordController.php
LoginController.php
RegisterController.php
ResetPasswordController.php
VerificationController.php
use
:use App\Providers\RouteServiceProvider;
$redirectTo
в каждом из этих контроллеров.По умолчанию в Laravel свойство $redirectTo
будет равно строке /home
:
protected $redirectTo = '/home';
Нужно заменить это на:
protected $redirectTo = RouteServiceProvider::HOME;
Пример для LoginController.php
:
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
class LoginController extends Controller
{
use AuthenticatesUsers;
protected $redirectTo = RouteServiceProvider::HOME;
// Остальной код контроллера
}
Для других контроллеров, где есть свойство $redirectTo
нужно аналогичным образом изменить строку.
После завершения всех предыдущих шагов, чтобы протестировать отображение страницы входа и регистрации, выполните следующие действия:
Очистите кэш приложения:
php artisan config:clear
Команду php artisan
нужно выполнять из корня проекта: /var/www/laravel-admin
.
Откройте браузер и перейдите по следующим маршрутам:
http://<Публичный_IP-Адрес_Сервера>/login
— для доступа к странице входа.
http://<Публичный_IP-Адрес_Сервера>/register
— для регистрации нового пользователя.
Теперь базовая аутентификация в вашем проекте Laravel готова. Вы можете использовать её как основу для дальнейшей настройки и расширения.
Создайте папку для шаблонов административной панели:
mkdir -p resources/views/dashboard/layouts
Создайте базовый шаблон resources/views/dashboard/layouts/master.blade.php
:
<!doctype html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,
initial-scale=1">
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>Dashboard</title>
<link
href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.
min.css" rel="stylesheet">
@stack('style')
</head>
<body class="container-fluid" style="height: 100%; margin: 0;">
<div class="wrapper row" style="height: 100%;">
<nav id="sidebar" class="p-3 bg-dark d-flex flex-column col-2" style="height: 100vh;">
@include('dashboard.layouts.sidebar')
</nav>
<div id="content" class="col" style="height: 100vh; overflow-y: auto;">
@include('dashboard.layouts.nav')
<div class="container-fluid mt-4 mb-4">
@if(Session::has('global'))
<div class="alert alert-success">
{{ Session::get('global') }}
</div>
@endif
@yield('content')
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
@stack('scripts')
</body>
</html>
Описание ключевых элементов шаблона:
{{ csrf_token() }}
: Генерирует уникальный токен для защиты от CSRF-атак.
@stack('style') и @stack('scripts')
: Позволяют добавлять стили и скрипты из дочерних шаблонов через @push
.
@include('dashboard.layouts.nav')
: Подключает Blade-шаблон с верхним меню.
<script src="https://cdn.jsdelivr.net/npm/..."></script>
: Для быстрого использования готовых стилей и компонентов на фронтенде, подключаем Bootstrap через CDN.
{{ Session::get('global') }}
: Выводит уведомления из переменной global
в сессии.
Файл бокового меню resources/views/dashboard/layouts/sidebar.blade.php
:
<ul class="nav flex-column">
<li class="nav-item">
<a class="nav-link text-white" href="{{ route('dashboard.home') }}">Главная</a>
</li>
</ul>
Файл верхнего меню resources/views/dashboard/layouts/nav.blade.php
:
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<div class="container-fluid">
<span class="navbar-brand">Dashboard</span>
</div>
</nav>
Теперь создайте файл resources/views/dashboard/app.blade.php
:
@extends('dashboard.layouts.master')
@section('content')
<p>Как создать админку на Laravel: Пошаговое руководство</p>
@endsection
Этот файл наследует базовый шаблон master.blade.php
и задает уникальный контент для каждой страницы.
После завершения всех предыдущих шагов, выполните следующие действия, чтобы протестировать работу аутентификации:
Для очистки кэшей и временных данных выполните команду в корне проекта:
php artisan optimize:clear
Теперь структура шаблонов для админ-панели завершена. Вы можете зарегистрировать первого пользователя, используя маршрут http://Публичный_IP-Адрес_Сервера/register
.
После этого вы сможете авторизоваться.
Создайте файл модели Post и файл миграцией (флаг -m
) с помощью команды:
php artisan make:model Post -m
Laravel автоматически создаст два файла:
Файл модели app/Models/Post.php
:
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Test extends Model
{
use HasFactory;
}
Файл миграции для таблицы database/migrations/YYYY_MM_DD_create_posts_table.php
:
database/migrations/YYYY_MM_DD_create_posts_table.php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('posts');
}
};
Добавьте колонки title
и content
в файле database/migrations/YYYY_MM_DD_create_posts_table.php
:
$table->string('title');
$table->text('content');
Вот так будет выглядеть файл миграции:
return new class extends Migration
{
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->text('content');
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('posts');
}
};
Выполните миграцию, чтобы создать таблицу в базе данных:
php artisan migrate
В файле app/Models/Post.php
добавьте следующее свойство:
protected $fillable = ['title', 'content'];
Вот как будет выглядеть модель Post
:
class Post extends Model
{
use HasFactory;
protected $fillable = ['title', 'content'];
}
$fillable
— перечисляет поля, которые могут быть массово заполнены (mass assignment), например, через Post::create()
.
HasFactory
— трейт, позволяющий использовать фабрики для тестирования.
Создайте файл контроллера для модели Post
с помощью команды:
php artisan make:controller Dashboard/PostController -r --model=Post
Laravel автоматически создаст файл контроллера app/Http/Controllers/Dashboard/PostController.php
:
app/Http/Controllers/Dashboard/PostController.php
namespace App\Http\Controllers\Dashboards;
use App\Http\Controllers\Controller;
use App\Models\Post;
use Illuminate\Http\Request;
class PostController extends Controller
{
public function index()
{
//
}
public function create()
{
//
}
public function store(Request $request)
{
//
}
public function show(Post $post)
{
//
}
public function edit(Post $post)
{
//
}
public function update(Request $request, Post $post)
{
//
}
public function destroy(Post $post)
{
//
}
}
Ресурсный контроллер (Resource Controller) в Laravel — это специальный тип контроллера, который автоматически создает пустые методы для стандартных операций CRUD (Create, Read, Update, Delete) над моделью данных. Это помогает упростить процесс создания маршрутов и контроллеров для управления ресурсами. Эти методы соответствуют RESTful-подходу и включают:
index
— отображение списка записей.create
— форма для создания новой записи.store
— сохранение новой записи в базе данных.edit
— форма для редактирования записи.update
— обновление записи в базе данных.destroy
— удаление записи.Удалите метод show
и обновите код методов index
, create
, store
, edit
, update
и destroy
в файле контроллера app/Http/Controllers/Dashboard/PostController.php
:
class PostController extends Controller
{
public function index()
{
$posts = Post::latest()->paginate(10);
return view('dashboard.posts.index', compact('posts'));
}
public function create()
{
return view('dashboard.posts.create');
}
public function store(Request $request)
{
$request->validate([
'title' => 'required|string|max:255',
'content' => 'required',
]);
Post::create($request->only('title', 'content'));
return redirect()->route('posts.index')->with('global', 'Запись успешно создана.');
}
public function edit(Post $post)
{
return view('dashboard.posts.edit', compact('post'));
}
public function update(Request $request, Post $post)
{
$request->validate([
'title' => 'required|string|max:255',
'content' => 'required',
]);
$post->update($request->only('title', 'content'));
return redirect()->route('posts.index')->with('global', 'Запись успешно обновлена.');
}
public function destroy(Post $post)
{
$post->delete();
return redirect()->route('posts.index')->with('global', 'Запись успешно удалена.');
}
}
В файле routes/dashboard.php
добавьте маршрут для ресурсного контроллера:
use App\Http\Controllers\Dashboard\PostController;
Route::resource('posts', PostController::class);
Этот маршрут автоматически создаст доступ к методам ресурсного контроллера, таким как index
, create
, store
, и т. д.
В файле resources/views/dashboard/layouts/sidebar.blade.php
добавьте ссылку на управление постами:
<li class="nav-item">
<a class="nav-link text-white" href="{{ route('posts.index') }}">Записи</a>
</li>
Вот как будет выглядеть файл sidebar.blade.php
:
<ul class="nav flex-column">
<li class="nav-item">
<a class="nav-link text-white" href="{{ route('dashboard.home') }}">Главная</a>
</li>
<li class="nav-item">
<a class="nav-link text-white" href="{{ route('posts.index') }}">Записи</a>
</li>
</ul>
Когда добавляете ресурсный маршрут:
Route::resource('posts', PostController::class);
Laravel автоматически создает несколько маршрутов для методов в контроллере PostController
. Эти маршруты будут иметь следующие имена:
posts.index
— для отображения списка постов (метод index
).posts.create
— для отображения формы создания поста (метод create
).posts.store
— для сохранения нового поста в базе данных (метод store
).posts.edit
— для отображения формы редактирования поста (метод edit
).posts.update
— для обновления поста в базе данных (метод update
).posts.destroy
— для удаления поста (метод destroy
).Теперь в меню админки появится пункт «Записи», который ведёт на страницу управления постами.
Класс Request в Laravel отвечает за управление входящими HTTP-запросами. Он обеспечивает:
Централизацию валидации: Правила проверки данных определяются в одном месте, что повышает читаемость и упрощает поддержку.
Безопасность: Гарантирует, что только валидированные данные попадут в контроллер.
Логическую изоляцию: Убирает из контроллеров лишнюю логику, делая код более чистым и понятным.
Валидация данных: В классе Request
вы описываете правила проверки данных. Например, требование, чтобы поле title
было обязательным и содержало строку определенной длины.
Авторизация: Класс позволяет определить, кто может выполнять запрос. Если авторизация в методе authorize
возвращает false
, запрос будет отклонен с кодом 403.
Чистота данных: Метод validated()
возвращает только те данные, которые прошли проверку. Это предотвращает попадание нежелательных данных в базу или логику приложения.
Изоляция логики: Все правила, связанные с запросом, изолируются в классе Request
, уменьшая сложность контроллера.
Чтобы создать кастомный класс Request
для модели Post
, выполните команду:
php artisan make:request PostRequest
Laravel автоматически создаст файл app/Http/Requests/PostRequest.php
:
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class PostRequest extends FormRequest
{
public function authorize()
{
return false;
}
public function rules()
{
return [
//
];
}
}
Обновите методы authorize
и rules
:
class PostRequest extends FormRequest
{
/**
* Определяет, может ли пользователь отправить запрос.
*/
public function authorize()
{
return true; // Замените на проверку, если требуется авторизация.
}
/**
* Определяет правила валидации входящих данных.
*/
public function rules()
{
return [
'title' => 'required|string|max:255',
'content' => 'required',
];
}
/**
* Сообщения об ошибках валидации.
*/
public function messages()
{
return [
'title.required' => 'Поле "Заголовок" обязательно для заполнения.',
'content.required' => 'Поле "Контент" обязательно для заполнения.',
];
}
}
В некоторых случаях полезно создавать два разных класса запроса для операций создания и обновления записи. Это может быть полезно, если правила валидации для этих операций различаются.
PostStoreRequest
— используется для валидации данных при создании нового поста.PostUpdateRequest
— используется для валидации данных при обновлении существующего поста.Это позволяет настраивать разные правила валидации для этих операций. Например, при обновлении записи поле title
может быть необязательным, если оно не изменяется, тогда как при создании оно обязательно.
В контроллере app/Http/Controllers/Dashboard/PostController.php
выполните следующие действия:
use
:use App\Http\Requests\PostRequest;
store
и update
, чтобы использовать новый класс app/Http/Requests/PostRequest.php
:namespace App\Http\Controllers\Dashboard;
use App\Http\Controllers\Controller;
use App\Models\Post;
use App\Http\Requests\PostRequest;
class PostController extends Controller
{
// Остальные методы
public function store(PostRequest $request)
{
Post::create($request->validated());
return redirect()->route('posts.index')->with('global', 'Запись успешно создана.');
}
public function update(PostRequest $request, Post $post)
{
$post->update($request->validated());
return redirect()->route('posts.index')->with('global', 'Запись успешно обновлена.');
}
// Остальные методы
}
Метод $request->validated()
используется для получения только тех данных из запроса, которые прошли валидацию. Когда вы используете кастомный класс запроса, Laravel автоматически выполняет все проверки, описанные в методе rules()
класса запроса. Например, может быть проверена обязательность полей или их соответствие заданному формату.
Метод validated()
возвращает массив данных, которые успешно прошли валидацию, исключая любые поля, которые не прошли проверки. Это защищает от небезопасных данных и помогает избежать ошибок при обработке.
Пример:
title
, которое не соответствует правилам валидации, Laravel прервет выполнение метода и вернет ошибку. Например, это произойдет, если поле пустое, хотя по правилам оно обязательно.$request->validated()
вернет только те поля, которые прошли все проверки, и их можно безопасно передать для создания или обновления записи в базе данных.Создайте папку для шаблонов модели Post
:
mkdir -p resources/views/dashboard/posts
Создайте шаблон для отображения всех элементов модели resources/views/dashboard/posts/index.blade.php
:
@extends('dashboard.layouts.master')
@section('content')
<div class="d-flex justify-content-between align-items-center">
<h1>Записи</h1>
<a href="{{ route('posts.create') }}" class="btn btn-primary">Создать запись</a>
</div>
<table class="table mt-4">
<thead>
<tr>
<th>#</th>
<th>Заголовок</th>
<th>Действия</th>
</tr>
</thead>
<tbody>
@foreach($posts as $post)
<tr>
<td>{{ $post->id }}</td>
<td>{{ $post->title }}</td>
<td>
<a href="{{ route('posts.edit', $post) }}" class="btn btn-warning btn-sm">Редактировать</a>
<form action="{{ route('posts.destroy', $post) }}" method="POST" class="d-inline-block">
@csrf
@method('DELETE')
<button class="btn btn-danger btn-sm" onclick="return confirm('Вы уверены?')">Удалить</button>
</form>
</td>
</tr>
@endforeach
</tbody>
</table>
{{ $posts->links() }}
@endsection
Шаблон с формой для создания элементов resources/views/dashboard/posts/create.blade.php
:
@extends('dashboard.layouts.master')
@section('content')
<h1>Создать запись</h1>
<form action="{{ route('posts.store') }}" method="POST">
@csrf
<div class="mb-3">
<label for="title" class="form-label">Заголовок</label>
<input type="text" class="form-control" id="title" name="title" value="{{old('title')}}">
@error('title')
<p class="text-danger">{{ $message }}</p>
@enderror
</div>
<div class="mb-3">
<label for="content" class="form-label">Контент</label>
<textarea class="form-control" id="content" name="content" rows="5">{{old('content')}}</textarea>
@error('content')
<p class="text-danger">{{ $message }}</p>
@enderror
</div>
<button type="submit" class="btn btn-success">Сохранить</button>
</form>
@endsection
Шаблон для редактирования элемента модели resources/views/dashboard/posts/edit.blade.php
:
@extends('dashboard.layouts.master')
@section('content')
<h1>Редактировать запись</h1>
<form action="{{ route('posts.update', $post) }}" method="POST">
@csrf
@method('PUT')
<div class="mb-3">
<label for="title" class="form-label">Заголовок</label>
<input type="text" class="form-control" id="title" name="title" value="{{old('title', $post->title)}}">
@error('title')
<p class="text-danger">{{ $message }}</p>
@enderror
</div>
<div class="mb-3">
<label for="content" class="form-label">Контент</label>
<textarea class="form-control" id="content" name="content" rows="5">{{old('content', $post->content)}}</textarea>
@error('content')
<p class="text-danger">{{ $message }}</p>
@enderror
</div>
<button type="submit" class="btn btn-success">Обновить</button>
</form>
@endsection
@extends
@extends
используется для наследования базового шаблона.
В данном случае шаблоны страниц index.blade.php
, create.blade.php
и edit.blade.php
наследуют базовый шаблон master.blade.php
, который определяет общий каркас страницы (шапка, меню, стили, скрипты и т.д.). Это позволяет переиспользовать общие части интерфейса и сократить дублирование кода.
@section
@section
используется для заполнения секций, определенных в базовом шаблоне через @yield
. Например, в базовом шаблоне master.blade.php
определена секция @yield('content')
, которая динамически заменяется содержимым дочерних шаблонов.
{{ old('title') }}
old()
используется для получения ранее введенного значения формы после перезагрузки страницы. Это особенно полезно, если при отправке формы произошли ошибки валидации, и важно сохранить введенные пользователем данные.
@error
@error
используется для вывода сообщений об ошибках валидации для определенного поля. Если поле title
не прошло проверку, то внутри блока @error('title')
будет отображено сообщение об ошибке.
После того как вы создадите шаблоны для отображения, создания и редактирования постов, не забудьте протестировать их в действии. Создайте несколько записей, используя форму на странице Создать запись, и попробуйте редактировать их через соответствующую форму.
Убедитесь, что все работает корректно: можно добавлять новые посты, а также редактировать уже существующие записи. Также проверьте, что сообщения об ошибках правильно отображаются при неверно заполненных полях.
Создайте контроллер для обработки запросов:
php artisan make:controller PostController
Импортируйте пространство имен App\Models\Post
и добавьте метод show
в контроллере app/Http/Controllers/PostController.php
для получения записей из базы данных:
namespace App\Http\Controllers;
use App\Models\Post;
use Illuminate\Http\Request;
class PostController extends Controller
{
public function show()
{
$posts = Post::latest()->paginate(10); // Пагинация для удобного отображения
return view('posts.index', compact('posts'));
}
}
Добавьте маршрут для отображения списка записей.
Откройте файл routes/web.php
.
В этом файле находятся маршруты для клиентской части вашего приложения.
Используйте контроллер app/Http/Controllers/Controller.php
для обработки запросов на главной странице:
use App\Http\Controllers\PostController;
Замените существующий маршрут главной страницы.
Было:
Route::get('/', function () {
return view('welcome');
});
Стало:
Route::get('/', [PostController::class, 'show'])->name('posts.index');
Этот шаг настраивает главную страницу приложения для отображения записей из базы данных.
Создайте Blade-шаблон для вывода записей.
Создайте папку posts
:
mkdir -p resources/views/posts
Создайте файл resources/views/posts/index.blade.php
:
@extends('layouts.app')
@section('content')
<div class="container mt-4">
<h1>Список записей</h1>
@foreach($posts as $post)
<div class="card mb-3">
<div class="card-body">
<h5 class="card-title">{{ $post->title }}</h5>
<p class="card-text">{{$post->content}}</p>
</div>
</div>
@endforeach
<div class="mt-4">
{{ $posts->links() }}
</div>
</div>
@endsection
Теперь на главной странице http://localhost:8000/
вы сможете увидеть список записей с их заголовками и содержанием.
Для загрузки изображений к постам в облачное хранилище S3 воспользуйтесь инструкцией Интеграция Laravel с S3-хранилищем Timeweb Cloud.
Запустите свое приложение на облачном сервере
Вы создали базовую админ-панель и клиентскую часть на Laravel! Ваш проект теперь включает: