Creating a Blog Using Laravel 4 Part 3: Routing

Creating a Blog Using Laravel 4 Part 3 Routing

Laravel 4 Blog Tutorial – Routing Screenshot

Previous parts of this tutorial:

Topics we have covered so far:

  • Laravel Setup
  • Laravel Migrations
  • Model creation using Eloquent ORM
  • Database Seeding
  • Controllers

Today we will cover the routing for our blog application. So, let’s get started.

Routing in Laravel

Routing plays an essential role in the core workings of any MVC framework. It specifies a mapping between requests and response generators i.e, controller actions. In other words, routing defines the entry points of a web application. A flexible routing provides a greater control over the flow of a web application.
Laravel has a very powerful routing component built right on the top of Symfony’s routing component, and provides you with a very easy to use interface and a rich set of functionalities.

Defining Routes

In Laravel we define our application’s routes in app/routes.php. A simple routes.php would look like this:

<?php

// will be used to handle GET requests.
Route::get('index',function()
{
    echo 'this is index page';
});

Route::get('login',function()
{
    echo 'GET login requests will be hndled here.';
});

// will be used to handle POST requests.
Route::post('login', function() 
{
    echo 'POST login requests will be handled here.';
});

We can also use controller actions instead of closures like:

<?php
Route::get('users', 'UsersController@getIndex');

In this case all requests to /users will be delegated to the getIndex() action of the UserController. We can also define routes for delete and put HTTP verbs using Route::put and Route::delete methods.

Route Parameters

<?php

// parameter {id} will be passed to the closure.
Route::any('post/{id}',function($id)
{
    echo "post with id: $id";
});

//binding models to route parameters.
Route::model('post','Post'); //binds a model to the route parameter {post}

// A model with given post id will be passed to closure for any HTTP request.
Route::any('post/{post}',function($post)
{
    echo "post with id: $post->id";
});

Named Routes and Route Filters

Route filters provide a convenient way of limiting access to a given route, which is useful for creating areas of your site which require authentication. There are several filters included in the Laravel framework, including an auth filter, an auth.basic filter, a guest filter, and a csrf filter. These are located in the app/filters.php file.
Laravel’s Official Documentation

We define and apply a filter to a given route as follows:

Route::filter('simpleBeforeFilter', function()
{
    echo 'this is simple before filter';
});

Route::get('admin',['before'=>'simpleBeforeFilter',function()
{
    echo 'simpleBeforefilter is already called';
}]);

We can name any route by defining a key as in the array we pass as second argument:

<?php

Route::get('admin',['as'=>'admin.home','before'=>'simpleBeforeFilter',function()
{
    echo 'simpleBeforefilter is already called';
}]);

//another example using controller action.
Route::get('/post/list',['as' => 'post.list','uses' => 'PostController@listPost']);

Naming a route makes it easier to generate URLs and redirects, for example:

<?php
URL::route('post.list'); //generates a url to /post/list route.

Laravel’s official documentation explains a lot of features of routing component. Covering each and every aspect of routing here is beyond the scope of the article. Please refer to the documentation page here for further details and clarifications.

Creating Routes for Blog Application

The following routes will define the flow of our blog application:

<?php
//file: app/routes.php

/* Model Bindings */
Route::model('post','Post');
Route::model('comment','Comment');

/* User routes */
Route::get('/post/{post}/show',['as' => 'post.show','uses' => 'PostController@showPost']);
Route::post('/post/{post}/comment',['as' => 'comment.new','uses' =>'CommentController@newComment']);

/* Admin routes */
Route::group(['prefix' => 'admin','before'=>'auth'],function()
{
    /*get routes*/
    Route::get('dash-board',function()
    {
        $layout = View::make('master');
        $layout->title = 'DashBoard';
        $layout->main = View::make('dash')->with('content','Hi admin, Welcome to Dashboard!');
        return $layout;

    });
    Route::get('/post/list',['as' => 'post.list','uses' => 'PostController@listPost']);
    Route::get('/post/new',['as' => 'post.new','uses' => 'PostController@newPost']);
    Route::get('/post/{post}/edit',['as' => 'post.edit','uses' => 'PostController@editPost']);
    Route::get('/post/{post}/delete',['as' => 'post.delete','uses' => 'PostController@deletePost']);
    Route::get('/comment/list',['as' => 'comment.list','uses' => 'CommentController@listComment']);
    Route::get('/comment/{comment}/show',['as' => 'comment.show','uses' => 'CommentController@showComment']);
    Route::get('/comment/{comment}/delete',['as' => 'comment.delete','uses' => 'CommentController@deleteComment']);

    /*post routes*/
    Route::post('/post/save',['as' => 'post.save','uses' => 'PostController@savePost']);
    Route::post('/post/{post}/update',['as' => 'post.update','uses' => 'PostController@updatePost']);
    Route::post('/comment/{comment}/update',['as' => 'comment.update','uses' => 'CommentController@updateComment']);

});

/* Home routes */
Route::controller('/','BlogController');

In the above code the initial two statements will bind the Post and Comment models to the route parameters. The next two routes post.show and comment.new will be used for displaying a single post and allowing the users of the blog to post the comments respectively.

Next we are defining a group of routes for the administration. A prefix admin is applied to differentiate them from user routes. Using named routes inside admin route group will make it easier to generate complex URLs ( e.g, URL::route('post.edit',12) will generate a URL: http://localhost/admin/post/12/edit ).

Protecting Admin Routes and Authentication

Laravel comes with some predefined filters including an auth and a guest filter. auth filter checks if a current user is logged in otherwise it redirects the user to the login page. The guest filter is the counter part of the auth filter.

Here is the code for the auth filter:

<?php

//file: app/filters.php
Route::filter('auth', function()
{
    if (Auth::guest()) return Redirect::guest('login');
});

As you can see in the code of the app/routes.php, I have already applied this filter to the admin group of the routes. So, whenever we will try to access one of the routes in the admin route group, this filter will ensure that a user is logged in to the application.

Note on Authentication:
A users table is required in the database for the Auth component to work properly. You can refer to my previous article on Laravel Authentication for database setup and other details.

In the next part of this tutorial we will create the layout and views for the application. Regards!


8 thoughts on “Creating a Blog Using Laravel 4 Part 3: Routing

  1. Ad Reply

    Hi, just thought I’d post to say I’m trying to follow your tutorial and as soon as I update routes.php as per your instructions I start getting errors.

    production.ERROR: exception ‘Symfony\Component\Debug\Exception\FatalErrorException’ with message ‘syntax error, unexpected ‘[” in /var/www/app/routes.php:9

    1. Usman Riaz author Reply

      It looks like you have syntax errors in your routes.php. By the way you can download source code from github. Regards!

  2. Sergio Reply

    When the next part?

    1. Usman Riaz author Reply

      I hope in a day or two, I was a little busy this month. But i am working on it now.

  3. Rizwan Reply

    Thanks Usman, this tutorial really helped me to learn laravel!

  4. Ivan Reply

    Hi, a very nice tutorial! Please, can you give us a clue how to handle exceptions when user types a non-existing URL (both cause it’s a tampered one or because post was deleted) in the browser, i.e. http://localhost/admin/post/123456xyz/edit? Thank you

    1. Usman Riaz author Reply

      Laravel throws a ModelNotFoundException when it does not find a record matching the id. You can add a custom error handler in app/start/global.php to catch this exception. Here is a sample error handler:

      App::error(function(Illuminate\Database\Eloquent\ModelNotFoundException $e,$code){
          return Response::make('custom 404 response here', 404);
          //or return Response::view('404page',null,404); 
      });
      

      Regards,

      1. Ivan Reply

        Thanks so much: in a much similar tutorial I’m having an NotFoundHttpException instead of ModelNotFoundException (don’t know why!) and your code works very fine with Symfony\Component\HttpKernel\Exception\NotFoundHttpException

        I also put this snippet in my routes.php file: though it’s not a route, this is the “general” file I edit most :-)

Leave a Reply

Your email address will not be published. Required fields are marked *


seven − 1 =

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>