Hailwood
Hailwood

Reputation: 92581

Dynamic urls in laravel?

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

Answers (3)

Dee S
Dee S

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

Adam Marshall
Adam Marshall

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

TLGreg
TLGreg

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

Related Questions