Динамическая маршрутизация в приложении Laravel 5

Я надеюсь, что кто-то может помочь мне с динамической маршрутизацией для URL, которые могут иметь несколько сегментов. Я занимался поиском по всей сети, но ничто из того, что я нашел, не помогло мне в моей конкретной ситуации.

Немного предыстории... Несколько лет назад я разработал пакет CMS для пользовательских клиентских веб-сайтов, который был построен на CodeIgniter. Этот пакет CMS имеет несколько модулей (Страницы, Блог, Календарь, Запросы и т.д.). Для модуля "Страницы" я кэшировал маршруты в файл конфигурации "пользовательских маршрутов", который связывал полный маршрут для страницы (включая родительский, дедушку и т.д.) С идентификатором страницы. Я сделал это так, чтобы мне не пришлось выполнять поиск в базе данных, чтобы найти страницу для отображения.

В настоящее время я работаю над перестройкой этого пакета CMS с помощью Laravel (5.1) [пока я изучаю Laravel]. Мне нужно выяснить ситуацию с маршрутизацией, прежде чем я смогу перейти к модулю Pages в новой версии пакета.

Я знаю, что могу сделать что-то вроде...

// routes.php
Route::get('{slug}', ['uses' => '[email protected]']);

// PageController.php
class PageController extends Controller
{
    public function view($slug)
    {
        // do a query to get the page by the slug
        // display the view
    }
}

И это сработало бы, если бы я не разрешал вложенные страницы, но я делаю. И я только навязываю уникальность слизняка на основе родителя. Так что может быть несколько страниц с куском фарго...

  • Места/Фарго
  • Персонал/Фарго

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

Сначала я хотел создать конфигурационный файл, который будет иметь динамические маршруты, как я делал со старой версией системы. Маршруты будут меняться только в определенное время (при создании страницы, при изменении slug, при изменении родительского элемента), поэтому их "кэширование" будет работать отлично. Но я все еще новичок в Laravel, поэтому я не уверен, каким будет лучший способ сделать это.

Мне удалось выяснить, что следующие маршруты работают. Но это лучший способ настроить это?

Route::get('about/foobar', function(){
    return App::make('\App\Http\Controllers\PageController')->callAction('view', [123]);
});

Route::get('foobar', function(){
    return App::make('\App\Http\Controllers\PageController')->callAction('view', [345]);
});

По сути, я хотел бы привязать определенный маршрут к определенному идентификатору страницы, когда страница создается (или когда изменяется слаг или родительский элемент).

Я просто слишком усложняю вещи?

Любая помощь или направление в этом отношении будет принята с благодарностью.

Спасибо!

Ответ 1

То, как я обрабатываю это, - это использовать два маршрута: один для главной страницы (который обычно содержит более сложную логику, например, новости, подбор статей, баннеров и т.д.), а также уловку для любой другой страницы.

Маршруты

// Home page
Route::get('/', [
    'as'      => 'home',
    'uses'    => '[email protected]'
]);

// Catch all page controller (place at the very bottom)
Route::get('{slug}', [
    'uses' => '[email protected]' 
])->where('slug', '([A-Za-z0-9\-\/]+)');

Важная часть, которую следует отметить в приведенном выше, - это метод ->where(), прикованный цепью в конце маршрута. Это позволяет объявлять соответствие шаблонов регулярных выражений для параметров маршрута. В этом случае я разрешаю буквенно-цифровые символы, дефисы и косые черты для параметра {slug}.

Это будет соответствовать пули, как, например, test-page
test-page/sub-page
another-page/sub-page

Методы PageController

public function index()
{
    $page = Page::where('route', '/')->where('active', 1)->first();

    return view($page->template)
        ->with('page', $page);
}

public function getPage($slug = null)
{
    $page = Page::where('route', $slug)->where('active', 1);

    $page = $page->firstOrFail();

    return view($page->template)->with('page', $page);
}

Я сохраняю информацию о файле шаблона в базе данных, так как я разрешаю пользователям создавать шаблоны в системе управления контентом.

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

Ответ 2

Я также искал тот же ответ, который касается создания динамической маршрутизации в laravel, я придумываю это: В routes.php

<?php


/*
|--------------------------------------------------------------------------
| Application Routes
|--------------------------------------------------------------------------
|
| Here is where you can register all of the routes for an application.
| It a breeze. Simply tell Laravel the URIs it should respond to
| and give it the controller to call when that URI is requested.
|
*/

$str=Request::url();
$del="/public/";
$pos=strpos($str, $del);
$important1=substr($str, $pos+strlen($del), strlen($str)-1);
$important=ucfirst($important1); 
$asif=explode("/", $important);
$asif1=explode("/", $important1);
//echo $important;
$post=$asif1[0];
$post1=$asif1[1];
if(isset($asif1[2]))
{
   $post2=$asif1[2];
}
if(!(isset($post2)))
{
   Route::match(array('GET','POST'),$important1, $asif[0].'[email protected]'.$asif[1]);
}
if(isset($post2))
{      Route::match(array('GET','POST'),$post.'/'.$post1.'/{id}',$asif[0].'[email protected]'.$asif[1]);
}
Route::get('/', function () {
    return view('welcome');
});

Пример

если у вас есть PostController с методом hello в laravel. Вы можете использовать этот url http://localhost/shortproject/public/post/hello. Где shortproject - имя вашего проекта.