Динамическая маршрутизация в приложении 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 - имя вашего проекта.