Магазин на Laravel 7, часть 2. Создание контроллера и шаблонов, добавление маршрутов

29.09.2020

Теги: CLILaravelMySQLPHPWeb-разработкаБазаДанныхИнтернетМагазинКаталогТоваровПрактикаФреймворкШаблонСайта

Теперь создаем контроллер CatalogController, шаблоны index.blade.php, category.blade.php, brand.blade.php, product.blade.php и добавляем необходимые маршруты. Маршртутов для начала у нас будет пять: главная страница сайта, страница каталога, страница категории, страница бренда и карточка товара.

Добавляем маршртуры

Добавляем необходимые маршруты:

<?php
use Illuminate\Support\Facades\Route;

Route::get('/', function () {
    return view('welcome');
});

Route::get('/catalog/index', 'CatalogController@index')->name('catalog.index');
Route::get('/catalog/category/{slug}', 'CatalogController@category')->name('catalog.category');
Route::get('/catalog/brand/{slug}', 'CatalogController@brand')->name('catalog.brand');
Route::get('/catalog/product/{slug}', 'CatalogController@product')->name('catalog.product');

Создаем контроллер

Создаем заготовку контроллера CatalogController

> php artisan make:controller CatalogController
Controller created successfully.
<?php
namespace App\Http\Controllers;

use App\Brand;
use App\Category;
use App\Product;
use Illuminate\Http\Request;

class CatalogController extends Controller {

    public function index() {
        $roots = Category::where('parent_id', 0)->get();
        return view('catalog.index', compact('roots'));
    }

    public function category($slug) {
        $category = Category::where('slug', $slug)->firstOrFail();
        $products = Product::where('category_id', $category->id)->get();
        return view('catalog.category', compact('category', 'products'));
    }

    public function brand($slug) {
        $brand = Brand::where('slug', $slug)->firstOrFail();
        $products = Product::where('brand_id', $brand->id)->get();
        return view('catalog.brand', compact('brand', 'products'));
    }

    public function product($slug) {
        $product = Product::select(
            'products.*',
            'categories.name as category_name',
            'categories.slug as category_slug',
            'brands.name as brand_name',
            'brands.slug as brand_slug'
        )
            ->join('categories', 'products.category_id', '=', 'categories.id')
            ->join('brands', 'products.brand_id', '=', 'brands.id')
            ->where('products.slug', $slug)
            ->firstOrFail();
        return view('catalog.product', compact('product'));
    }
}

Создаем шаблоны

Шаблон resources/views/catalog/index.blade.php:

<h1>Каталог товаров</h1>
<ul>
    @foreach ($roots as $root)
        <li>
            <a href="{{ route('catalog.category', ['slug' => $root->slug]) }}">
                {{ $root->name }}
            </a>
        </li>
    @endforeach
</ul>

Шаблон resources/views/catalog/category.blade.php:

<h1>Категория: {{ $category->name }}</h1>
<ul>
    @foreach ($products as $product)
        <li>
            <a href="{{ route('catalog.product', ['slug' => $product->slug]) }}">
                {{ $product->name }}
            </a>
        </li>
    @endforeach
</ul>

Шаблон resources/views/catalog/brand.blade.php:

<h1>Бренд: {{ $brand->name }}</h1>
<ul>
    @foreach ($products as $product)
        <li>
            <a href="{{ route('catalog.product', ['slug' => $product->slug]) }}">
                {{ $product->name }}
            </a>
        </li>
    @endforeach
</ul>

Шаблон resources/views/catalog/product.blade.php:

<h1>Товар: {{ $product->name }}</h1>
<p>Цена: {{ number_format($product->price, 2, '.', '') }}</p>
<p>
    Категория:
    <a href="{{ route('catalog.category', ['slug' => $product->category_slug]) }}">
        {{ $product->category_name }}
    </a>
</p>
<p>
    Бренд:
    <a href="{{ route('catalog.brand', ['slug' => $product->brand_slug]) }}">
        {{ $product->brand_name }}
    </a>
</p>
<p>{{ $product->content }}</p>

Layout шаблон

Теперь нам нужен layout-шаблон, в котором будет шапка и подвал. Для этого нам потребуется CSS-фреймворк Bootstrap4. В консоли последовательно запускаем три команды:

> composer require laravel/ui
> php artisan ui bootstrap
> npm install && npm run dev

Шаблон resources/views/layout/site.blade.php:

<!doctype html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Магазин</title>
    <link rel="stylesheet" href="{{ asset('css/app.css') }}">
    <script src="{{ asset('js/app.js') }}"></script>
</head>
<body>

</body>
</html>

Добавляем верхнее меню и две колонки

<!doctype html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Магазин</title>
    <link rel="stylesheet" href="{{ asset('css/app.css') }}">
    <script src="{{ asset('js/app.js') }}"></script>
</head>
<body>
<div class="container">
    <nav class="navbar navbar-expand-lg navbar-dark bg-dark">
        <!-- Бренд и кнопка «Гамбургер» -->
        <a class="navbar-brand" href="/">Магазин</a>
        <button class="navbar-toggler" type="button" data-toggle="collapse"
                data-target="#navbar-example" aria-controls="navbar-example"
                aria-expanded="false" aria-label="Toggle navigation">
            <span class="navbar-toggler-icon"></span>
        </button>
        <!-- Основная часть меню (может содержать ссылки, формы и прочее) -->
        <div class="collapse navbar-collapse" id="navbar-example">
            <!-- Этот блок расположен слева -->
            <ul class="navbar-nav mr-auto">
                <li class="nav-item">
                    <a class="nav-link" href="#">Каталог</a>
                </li>
                <li class="nav-item">
                    <a class="nav-link" href="#">Доставка</a>
                </li>
                <li class="nav-item">
                    <a class="nav-link" href="#">Контакты</a>
                </li>
            </ul>
            <!-- Этот блок расположен справа -->
            <form class="form-inline my-2 my-lg-0">
                <input class="form-control mr-sm-2" type="search"
                       placeholder="Поиск по каталогу" aria-label="Search">
                <button class="btn btn-outline-info my-2 my-sm-0"
                        type="submit">Искать</button>
            </form>
        </div>
    </nav>

    <div class="row">
        <div class="col-md-3">
            <h4>Разделы каталога</h4>
            <p>Здесь будут корневые разделы</p>
            <h4>Популярные бренды</h4>
            <p>Здесь будут популярные бренды</p>
        </div>
        <div class="col-md-9">
            @yield('content')
        </div>
    </div>
</div>
</body>
</html>

Теперь будем наследовать этот шаблон:

@extends('layout.site')

@section('content')
    <h1>Каталог товаров</h1>
    <ul>
        @foreach ($roots as $root)
            <li>
                <a href="{{ route('catalog.category', ['slug' => $root->slug]) }}">
                    {{ $root->name }}
                </a>
            </li>
        @endforeach
    </ul>
@endsection

@extends('layout.site')

@section('content')
    <h1>Категория: {{ $category->name }}</h1>
    <ul>
        @foreach ($products as $product)
            <li>
                <a href="{{ route('catalog.product', ['slug' => $product->slug]) }}">
                    {{ $product->name }}
                </a>
            </li>
        @endforeach
    </ul>
@endsection

@extends('layout.site')

@section('content')
    <h1>Бренд: {{ $brand->name }}</h1>
    <ul>
        @foreach ($products as $product)
            <li>
                <a href="{{ route('catalog.product', ['slug' => $product->slug]) }}">
                    {{ $product->name }}
                </a>
            </li>
        @endforeach
    </ul>
@endsection

@extends('layout.site')

@section('content')
    <h1>Товар: {{ $product->name }}</h1>
    <p>Цена: {{ number_format($product->price, 2, '.', '') }}</p>
    <p>
        Категория:
        <a href="{{ route('catalog.category', ['slug' => $product->category_slug]) }}">
            {{ $product->category_name }}
        </a>
    </p>
    <p>
        Бренд:
        <a href="{{ route('catalog.brand', ['slug' => $product->brand_slug]) }}">
            {{ $product->brand_name }}
        </a>
    </p>
    <p>{{ $product->content }}</p>
@endsection

Поиск: CLI • Laravel • MySQL • PHP • Web-разработка • База данных • Интернет магазин • Каталог товаров • Практика • Фреймворк • Шаблон сайта

Каталог оборудования
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Производители
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Функциональные группы
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.