2015-10-07 23 views
10

Mam nadzieję, że ktoś może mi pomóc dzięki dynamicznemu routingowi dla adresów URL, które mogą mieć wiele segmentów. Szukałem w sieci, ale nic, co znalazłem, nie pomogło mi w mojej konkretnej sytuacji.Routing dynamiczny w aplikacji Laravel 5 Aplikacja

Małe tło ... kilka lat temu opracowałem pakiet CMS dla niestandardowych stron internetowych klientów, który został zbudowany na CodeIgniter. Ten pakiet CMS ma kilka modułów (strony, blog, kalendarz, zapytania itp.). W przypadku modułu Strony buforowałem trasy do pliku konfiguracyjnego "trasy niestandardowe", które powiązało całą trasę dla strony (w tym rodzica, dziadka, itp.) Z identyfikatorem strony. Zrobiłem to tak, że nie musiałem wykonywać odnośników do bazy danych, aby znaleźć stronę do wyświetlenia.

Obecnie pracuję nad przebudowaniem tego pakietu CMS przy użyciu Laravel (5.1) [podczas gdy uczę się Laravel]. Zanim przejdę do pracy z modułem Strony w nowej wersji pakietu, muszę poznać sytuację routingu.

wiem, że mogę zrobić coś takiego ...

// 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 
    } 
} 

A to będzie działać, jeśli nie pozwalają zagnieżdżonych stron, ale robię. I tylko wymuszam unikalność ślimaka w oparciu o rodzica. Więc nie może być więcej niż jedna strona z łyk Fargo ...

  • lokalizacje/Fargo
  • kierowniczym/Fargo

Jak z pakietem że zbudowany przy użyciu CodeIgniter, ja chciałby móc uniknąć dodatkowych wyszukiwań bazy danych, aby znaleźć właściwą stronę do wyświetlenia.

Moja początkowa myśl polegała na utworzeniu pliku konfiguracyjnego, który miałby dynamiczne trasy, tak jak zrobiłem ze starą wersją systemu. Trasy będą się zmieniać tylko w określonych momentach (kiedy strona jest tworzona, kiedy slug jest modyfikowany, kiedy rodzic jest zmieniany), więc "buforowanie" ich będzie działało świetnie. Ale wciąż jestem nowa w Laravel, więc nie jestem pewien, jaki byłby najlepszy sposób, aby to osiągnąć.

Udało mi się ustalić, że działają następujące trasy. Ale czy to najlepszy sposób, aby to ustawić?

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]); 
}); 

Zasadniczo chciałbym związać konkretną trasą do konkretnej strony ID, gdy strona jest tworzona (lub gdy ślimak lub rodzic są zmieniane).

Czy po prostu nadmiernie kompiluję rzeczy?

Każda pomoc lub skierowanie w tym kierunku byłoby bardzo cenne.

Dzięki!

+0

"Czy po prostu nadmiernie kompiluję rzeczy?", IMO 'Tak'. Ponadto te trasy wyglądają jak statyczne, nie ma dynamizmu, jeśli nie zezwalasz na zastępowanie "ID". Każda trasa jest po prostu związana z jednym konkretnym "identyfikatorem". –

+0

W jaki sposób mam zamiar skonfigurować, nie sądzę, że istnieje sposób, aby użyć dynamicznej trasy, która nie wymagałaby ode mnie dodatkowych zapytań do bazy danych, aby znaleźć właściwą stronę. Użyję dynamicznych tras dla innych modułów, takich jak Blog, ale dla zwykłych stron, nie sądzę, że to zadziała. – Becky

Odpowiedz

18

Sposób, w jaki sobie z tym poradzę, polega na użyciu dwóch tras, jednej dla strony głównej (która zazwyczaj zawiera bardziej złożoną logikę, jak wiadomości, przedmioty do pobrania, banery itp.), A także catch dla każdej innej strony.

Trasy

// 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\-\/]+)'); 

Ważną częścią zwrócić uwagę na powyższe jest metoda ->where() przykuty na końcu trasy. Pozwala to zadeklarować dopasowanie wzorca regex dla parametrów trasy.W tym przypadku zezwalam na wprowadzanie znaków alfanumerycznych, łączników i ukośników w przód dla parametru {slug}.

To będzie pasował ślimaki jak
test-page
test-page/sub-page
another-page/sub-page

PageController Metod

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); 
} 

I zachować informacje o pliku szablonu w bazie danych, jak umożliwić użytkownikom tworzenie szablonów w system zarządzania treścią.

Odpowiedź z kwerendy w bazie danych jest następnie przekazywana do widoku, w którym może być wyjście do metadanych, strona, bułka tarta, itp

+0

Jak wspomniałem w moim pytaniu, 2 różne strony mogą mieć ten sam ślimak, jeśli mają różnych rodziców. Więc nie mogę zrobić tego, co sugerujesz. I nie chcę robić wielu wyszukiwań, aby znaleźć właściwego rodzica. – Becky

+0

@Becky Kolumna slug w bazie danych zawierałaby FULL slug. TO ZNACZY. 'locations/fargo'. W ten sposób nigdy nie będziesz musiał się martwić o duplikaty. Czy jest jakiś powód, dla którego używasz tylko ostatniego segmentu dla twojego ślimaka? – Jeemusu

+0

Ślimak to tylko strona, na podstawie tytułu. To, co sugerowałbyś, to pełny permalink i to nie jest to, czego szukam. – Becky

-7

Ja również poszukuje tej samej odpowiedzi, która jest o stworzenie dynamiczny routing w laravel wymyślić to: w routes.php

<?php 


/* 
|-------------------------------------------------------------------------- 
| Application Routes 
|-------------------------------------------------------------------------- 
| 
| Here is where you can register all of the routes for an application. 
| It's 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'); 
}); 

Ex

jeśli masz PostController metodą powitania w laravel. Możesz użyć tego adresu URL: http://localhost/shortproject/public/post/hello. Gdzie krótki projekt to nazwa twojego folderu projektu.