Reputation: 92581
I am looking at switching to laravel for my next project.
My next project is probably going to be a small site with a few static pages, a blog and a projects manager and will be using controllers not routes.
What I am curious about is how I can manage dynamic routes in Laravel.
Basically, I want to build in an admin section so I can easily create the static pages on the fly, and the static pages will have SEO focussed urls, e.g. http://domain.com/when-it-started I do not want to have to create a new controller or route manually for each page.
So I am wondering what the cleanest way is to handle this.
essentially all static pages are going to share the same view, just a few variables to change.
The dynamic routing should work with the controllers not instead of.
E.g. if we have a controller about
with a function staff
then this should be loaded via http://domain.com/about/staff
but we dont have the function players
, so a call to http://domain.com/about/players should check the database to see if a dynamic route exists and matches. If it does display that, otherwise show the 404 page. Likewise for a non-existant controller. (e.g. there would not be a when-it-started
controller!)
The chosen answer doesn't seem to work in Laravel 4. Any help with that?
Upvotes: 23
Views: 22669
Reputation: 1295
For Laravel 4 do this
Route::get('{slug}', function($slug) {
$page = Page::where('slug', '=', $slug)->first();
if ( is_null($page) )
// use either one of the two lines below. I prefer the second now
// return Event::first('404');
App::abort(404);
return View::make('pages.show', array('page' => $page));
});
// for controllers and views
Route::get('{page}', array('as' => 'pages.show', 'uses' => 'PageController@show'));
Upvotes: 18
Reputation: 712
Very similar to Charles' answer, but in the controller:
public function showBySlug($slug) {
$post = Post::where('slug','=',$slug)->first();
// would use app/posts/show.blade.php
return View::make('posts.show')->with(array(
'post' => $post,
));
}
Then you can route it like this:
Route::get('post/{slug}', 'PostsController@showBySlug')
->where('slug', '[\-_A-Za-z]+');`
...which has the added bonus of allowing you an easy way to link straight to the slug routes on an index page, for example:
@foreach ($posts as $post)
<h2>{{ HTML::link(
action('PostsController@showBySlug', array($post->slug)),
$post->title
)}}</h2>
@endforeach
Upvotes: 3
Reputation: 8449
You could use the route wildcards for the job, you can start with an (:any)
and if you need multiple url segments add an optional (:all?)
, then identify the page from the slug.
For example:
Route::get('(:any)', function($slug) {
$page = Page::where_slug($slug)->first();
if ( is_null($page) )
return Event::first('404');
return View::make('page')->with($page);
});
Upvotes: 8