Как сделать роутинг для страниц, добавляемых через админку?

Как в роутинге проверять, что данная страница добавлена через админку и передавать управление на соответствующий контроллер? Могут быть категории, подкатегории...
  • Вопрос задан
  • 98 просмотров
Пригласить эксперта
Ответы на вопрос 2
@aleksejjjjj
Очевидно все эти кастомные роуты сохраняются в БД.
Пишем в web.php
Route::get('category/{category:slug}', [CategoryController::class, 'searchFuckingSlug']);


Контроллер
public function searchFuckingSlug(Category $category)
{

}

Где проблема?
Ответ написан
delphinpro
@delphinpro Куратор тега Laravel
frontend developer
Считать из базы все слаги, динамически зарегистировать все возможные роуты.
Считанные слаги кэшировать. Кэш обновлять по сохранению страницы в базе.
Такой вариант дает возможность создавать в админке любые адреса, включая корневые.

В качестве примера:
class DynamicRoutes
{
  public function routes(): void
  {
    /** @var Collection $pageCollection */
    $pageCollection = getFromCacheIf(config('cache.pages'), CACHE_PAGES, function () {
      try {
        return $this->getPages();
      } catch (\Exception $exception) {
        return new Collection();
      }
    });

    $pageCollection->each(function (Page $page) use ($pageCollection) {

      $routeName = ROUTE_PREFIX_PAGE.$page->slug;
      $routeUri = $page->getAttribute('url');

      $parentRouteName = $page->parent_id
        ? ROUTE_PREFIX_PAGE.($pageCollection->get($page->parent_id)->slug)
        : 'home';

      Route::prefix($routeUri)->group(function () use ($page, $routeName, $parentRouteName) {

        Route::get('', static function () use ($page) {
          return App::call($page->controllerName(), ['page' => Page::findOrFail($page->id)]);
        })
          ->name($routeName)
          ->breadcrumbs(function (Trail $trail) use ($page, $routeName, $parentRouteName) {
            return $trail->parent($parentRouteName)
              ->push($page->localizedAttribute('title'), route($routeName));
          });

        switch ($page->controllerName()) {
          case GalleryController::class:
            $this->galleryRoutes($routeName);
            break;
          case TourController::class:
            $this->tourRoutes($routeName);
            break;
          case NewsController::class:
            $this->newsRoutes($routeName);
            break;
        }

      });

    });
  }

  private function galleryRoutes(string $parentRouteName): void
  {
    Route::get('{gallery:slug}', [GalleryController::class, 'show'])
      ->name(ROUTE_GALLERY)
      ->breadcrumbs(function (Trail $trail, Gallery $gallery) use ($parentRouteName) {
        return $trail->parent($parentRouteName)
          ->push($gallery->localizedAttribute('title'), route(ROUTE_GALLERY, $gallery));
      });
  }

  private function tourRoutes(string $parentRouteName): void
  {
    Route::get('{tour:slug}', [TourController::class, 'show'])
      ->name(ROUTE_TOUR)
      ->breadcrumbs(function (Trail $trail, Tour $tour) use ($parentRouteName) {
        return $trail->parent($parentRouteName)
          ->push($tour->localizedAttribute('title'), route(ROUTE_TOUR, $tour));
      });
  }

  private function newsRoutes(string $parentRouteName): void
  {
    Route::get('{news:slug}', [NewsController::class, 'show'])
      ->name(ROUTE_NEWS)
      ->breadcrumbs(function (Trail $trail, News $news) use ($parentRouteName) {
        return $trail->parent($parentRouteName)
          ->push($news->localizedAttribute('title'), route(ROUTE_NEWS, $news));
      });
  }

  private function getPages(): Collection
  {
    $pages = Page::whereNotNull('slug')->get()->keyBy('id');

    $pages->each(function (Page $page) use ($pages) {
      $page->setAttribute('url', $this->buildUrlForPage($page, $pages));
    });

    return $pages;
  }

  private function buildUrlForPage(Page $page, Collection $pages): string
  {
    if (!$page->parent_id) {
      return $page->slug;
    }

    $parentPage = $pages->get($page->parent_id);

    return $this->buildUrlForPage($parentPage, $pages).'/'.$page->slug;
  }
}


router/web.php
//...
app(DynamicRoutes::class)->routes();

Route::fallback(function () {
  return response()->view('errors.404', [], 404);
});
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы