Как реализовать возможность выбора шаблона (view) для поста из админ панели?

Для реализации возможности выбора шаблона для поста из админ панели в Laravel можно использовать несколько подходов. Один из способов - использовать полиморфную связь между моделями Post и Template.

Шаг 1: Создание таблиц в базе данных

Сначала необходимо создать таблицы для постов и шаблонов. В миграциях Laravel можно создать такие таблицы:

Schema::create('posts', function (Blueprint $table) {
    $table->id();
    $table->string('title');
    $table->text('content');
    $table->unsignedBigInteger('template_id')->nullable();
    $table->timestamps();

    $table->foreign('template_id')
          ->references('id')
          ->on('templates')
          ->onDelete('set null');
});

Schema::create('templates', function (Blueprint $table) {
    $table->id();
    $table->string('name');
    $table->text('body');
    $table->timestamps();
});

Мы добавляем в таблицу постов столбец template_id, который является внешним ключом, связанным с таблицей шаблонов.

Шаг 2: Создание моделей

Для работы с данными из таблицы постов и шаблонов необходимо создать соответствующие модели.

class Post extends Model
{
    public function template()
    {
        return $this->belongsTo(Template::class);
    }
}

class Template extends Model
{
    public function posts()
    {
        return $this->hasMany(Post::class);
    }
}

С помощью методов belongsTo и hasMany мы указываем связь между моделями Post и Template.

Шаг 3: Создание контроллера и представлений

Создадим контроллер AdminPostController и методы index и update.

class PostController extends Controller
{
    public function index()
    {
        $posts = Post::with('template')->get();
        $templates = Template::all();

        return view('admin.posts.index', compact('posts', 'templates'));
    }

    public function update(Request $request, Post $post)
    {
        $post->template_id = $request->input('template_id');
        $post->save();

        return redirect()->route('admin.posts.index')
                         ->with('success', 'Шаблон для поста успешно обновлен');
    }
}

В методе index мы получаем все посты и связанные с ними шаблоны, а также передаем их в представление admin.posts.index.

Представление admin.posts.index может содержать форму для выбора шаблона для каждого поста.

@foreach ($posts as $post)
    <h3>{{ $post->title }}</h3>
    <p>{{ $post->content }}</p>

    <form action="{{ route('admin.posts.update', $post) }}" method="POST">
        @csrf
        @method('PUT')

        <label for="template_id">Выбрать шаблон:</label>
        <select name="template_id">
            <option value="">Без шаблона</option>
            @foreach ($templates as $template)
                <option value="{{ $template->id }}" {{ $post->template_id == $template->id ? 'selected' : '' }}>
                    {{ $template->name }}
                </option>
            @endforeach
        </select>

        <button type="submit">Сохранить</button>
    </form>
@endforeach

Здесь мы выводим каждый пост с его заголовком и содержимым, а также отображаем форму выбора шаблона для этого поста. Мы использовали route-нейминг для формы, чтобы отправить запрос PATCH/PUT на маршрут admin.posts.update.

Шаг 4: Роутинг

Не забудьте добавить соответствующие маршруты в файле web.php или api.php.

Route::group(['prefix' => 'admin', 'as' => 'admin.'], function () {
    Route::resource('posts', 'AdminPostController');
});

Этот код добавит маршруты для всех стандартных действий в контроллере AdminPostController.

Теперь вы можете открыть страницу админ панели, на которой будет список всех постов. У каждого поста будет выбор шаблона из выпадающего списка, и вы сможете выбрать нужный шаблон для каждого поста.