Create a a Personal Blog with laravel 5.2

 

In this tutorial, we’ll code a simple personal blog with Laravel. The Tutorial is Updated to Laravel 5.2 So , We’ll also cover Laravel’s built-in authentication, paginate mechanism, and named routes. We’ll elaborate some rapid development methods, which come with Laravel, such as creating route URLs. The following topics will be covered in this chapter:

    Creating and migrating the posts database
    Creating a posts model
    Creating and migrating the authors database
    Creating a members-only area
    Saving a blog post
    Assigning blog posts to users
    Listing articles
    Paginating the content

Creating and migrating the posts database

We assume that you have already defined database credentials in the app/config/database.phpfile. For this application, we need a database. You can simply create and run the following SQL command or basically you can use your database administration interface, something like phpMyAdmin:

CREATE DATABASE laravel_blog

After successfully creating the database for the application, first we need to create a posts table and install it in the database. To do this, open up your terminal, navigate through your project folder, and run this command:

php artisan make:migration create_posts_table --table=posts --create

This command will generate a migration file under app/database/migrations for generating a new MySQL table named posts in our laravel_blog database.

To define our table columns and specifications, we need to edit this file. After editing the migration file, it should look like this:

<?php

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreatePostsTable extends Migration {

  /**
   * Run the migrations.
   *
   * @return void
   */
  public function up()
  {
    Schema::create('posts', function(Blueprint $table)
    {
      $table->increments('id');
      $table->string('title');
      $table->text('content');
      $table->integer('author_id');
      $table->timestamps();
    });
  }

  /**
   * Reverse the migrations.
   *
   * @return void
   */
  public function down()
  {
    Schema::drop('posts');
  }
}

After saving the file, we need to use a simple artisan command to execute migrations:

php artisian migrate

If no error occurs, check the laravel_blog database for the posts table and columns.

Creating a posts model

As you know, for anything related to database operations on Laravel, using models is the best practice. We will benefit from the Eloquent ORM.

Save this code in a file named as Posts.php under app

<?php
class Post extends Eloquent {

protected $table = 'posts';

protected $fillable = array('title','content','author_id');

public $timestamps = true;

public function Author(){

      return $this->belongsTo('User','author_id');
}

}

We have set the database table name with the protected $table variable. We have also set editable columns with the $fillable variable and timestamps with the $timestamps variable as we’ve already seen and used in previous chapters. The variables which are defined in the model are enough for using Laravel’s Eloquent ORM. We’ll cover the public Author() function in the Assigning blog posts to users section of this chapter.

Our posts model is ready. Now we need an authors model and database to assign blog posts to authors. Let’s investigate Laravel’s built-in authentication mechanism.

Creating and migrating the authors database

Contrary to most of the PHP frameworks, Laravel has a basic authentication class. The authentication class is very helpful in rapidly developing applications. First, we need a secret key for our application. The application secret key is very important for our application’s security because all data is hashed salting this key. The artisan command can generate this key for us with a single command line:

php artisian key:generate

If no error occurs, you will see a message that tells you that the key is generated successfully. After key generation, if you face problems with opening your Laravel application, simply clear your browsercache and try again. Next, we should edit the authentication class’s configuration file. For using Laravel’s built-in authentication class, we need to edit the configuration file, which is located atapp/config/auth.php. The file contains several options for the authentication facilities. If you need to change the table name, and so on, you can make the changes under this file. By default, Laravel comes with the User model. You can see the User.php file, which is located at app/models/. With Laravel 4, we need to define which fields are fillable in our Users model. Let’s edit User.php located at app/models/ and add the “fillable” array:

<?php

use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableInterface;

class User extends Eloquent implements UserInterface, RemindableInterface {

  /**
   * The database table used by the model.
   *
   * @var string
   */
  protected $table = 'users';

  /**
   * The attributes excluded from the model's JSON form.
   *
   * @var array
   */
  protected $hidden = array('password');

  //Add to the "fillable" array
   protected $fillable = array('email', 'password', 'name');

  /**
   * Get the unique identifier for the user.
   *
   * @return mixed
   */
  public function getAuthIdentifier()
  {
    return $this->getKey();
  }

  /**
   * Get the password for the user.
   *
   * @return string
   */
  public function getAuthPassword()
  {
    return $this->password;
  }

  /**
   * Get the e-mail address where password reminders are sent.
   *
   * @return string
   */
  public function getReminderEmail()
  {
    return $this->email;
  }

}

Basically, we need three columns for our authors. These are:

    email: This column stores author’s e-mails
    password: This column stores authors’ passwords
    name: This column stores the authors’ names and surnames

Now we need several migration files to create the users table and add an author to our database. To create a migration file, give a command such as the following:

php artisan make:migration create_users_table --table=users --create

Open the migration file, which was created recently and located at database/migrations/. We need to edit the up() function as the following:

  public function up()
  {
    Schema::create('users', function(Blueprint $table)
    {
      $table->increments('id');
      $table->string('email');
      $table->string('password');
      $table->string('name');
      $table->timestamps();
    });
  }

After editing the migration file, run the migrate command:

php artisian migrate

As you know, the command creates the users table and its columns. If no error occurs, check thelaravel_blog database for the users table and the columns.

Now we need to create a new migration file for adding some authors to the database. We can do so by running the following command:

php artisan make:migration add_some_users

Open up the migration file and edit the up() function as the following:

  public function up()
  {
    User::create(array(
            'email' => 'your@email.com',
            'password' => Hash::make('password'),
            'name' => 'John Doe'
        ));
  }

We used a new class in the up() function, which is named Hash. Laravel has a hash maker/checker class, which is based on secure Bcrypt. Bcrypt is an accepted, secure hashing method for important data such as passwords.

The class for which we have created an application key with the artisan tool at the beginning of this chapter is used for salting. So, to apply migration, we need to migrate with the following artisan command:

php artisian migrate

Now, check the users table for a record. If you check the password column, you will see a record stored as follows:

$2y$08$ayylAhkVNCnkfj2rITbQr.L5pd2AIfpeccdnW6.BGbA.1VtJ6Sdqy

It is very important to securely store your user’s passwords and their critical data. Do not forget that if you change the application key, all the existing hashed records will be unusable because the Hashclass uses the application key as the salting key when validating and storing given data.

Creating a members-only area

As you know, our blog system is member based. Because of that we need some areas to be accessible by members only, for adding new posts to the blog. We have two different methods to do this. The first one is the route filter method, which we will elaborate in the next chapters. The second is the template-based authorization check. This method is a more effective way of understanding the use of the Auth class with the Blade template system.

With the Auth class we can check the authorization status of a visitor by just a single line of code:

Auth::check();

The check() function, which is based on the Auth class, always returns true or false. So, that means we can easily use the function in an if/else statement in our code. As you know from previous chapters, with the blade template system we were able to use that kind of PHP statement in the template files.

Before creating the template files we need to write our routes. We need four routes for our application. These are:

    A login route to process login requests
    A new post route to process new post requests
    An admin route to show a new post form and a login form
    An index route to list posts

Named routing is another amazing feature of the Laravel framework for rapid development. Named routes allow referring to routes when generating redirects or URLs more comfortably. You may specify a name for a route as follows:

Route::get('all/posts', array('as' => 'posts', function()
{
    //
}));

You may also specify route names for controllers:

Route::get('all/posts', array('as' => 'allposts', , 'uses' => 'PostController@showPosts'));

Thanks to the named routes, we can easily create URLs for our application:

$url = URL::route('allposts');

We can also use the named routes to redirect:

$redirect = Redirect::route('allposts');

Open the route configuration file, which is located at app/http/routes.php and add the following code:

Route::get('/', array('as' => 'index', 'uses' => 'PostsController@getIndex'));
Route::get('/admin', array('as' => 'admin_area', 'uses' => 'PostsController@getAdmin'));
Route::post('/add', array('as' => 'add_new_post', 'uses' => 'PostsController@postAdd'));
Route::post('/login', array('as' => 'login', 'uses' => 'UsersController@postLogin'));
Route::get('/logout', array('as' => 'logout', 'uses' => 'UsersController@getLogout'));

Now we need to write the code for the controller side and templates of our application. First, we can start coding from our admin area. Let’s create a file under resources/views/ with the name addpost.blade.php. Our admin template should look like the following:

<html>
<head>
<title>Welcome to Your Blog</title>
<link rel="stylesheet" type="text/css" href="/assets/css/style.css">
<!--[if lt IE 9]><script src="//html5shim.googlecode.com/svn/trunk/html5.js"></script><![endif]-->
</head>
<body>
@if(Auth::check())
<section class="container">
<div class="content">
<h1>Welcome to Admin Area, {{Auth::user()->name}} ! - <b>{{link_to_route('logout','Logout')}}</b></h1>
<form name="add_post" method="POST" action="{{URL::route('add_new_post')}}">
<p><input type="text" name="title" placeholder="Post Title" value=""/></p>
<p><textarea name="content" placeholder="Post Content"></textarea></p>
<p><input type="submit" name="submit" /></p>
</div>
</section>
@else
<section class="container">
<div class="login">
<h1>Please Login</h1>
<form name="login" method="POST" action="{{URL::route('login')}}">
<p><input type="text" name="email" value="" placeholder="Email"></p>
<p><input type="password" name="password" value="" placeholder="Password"></p>
<p class="submit"><input type="submit" name="commit" value="Login"></p>
</form>
</div>
</section>
@endif
</body>
</html>

As you can see in the code, we use if/else statements in a template to check a user’s login credentials. We know already from the beginning of this section that we use the Auth::check()function to check the login status of a user. Also, we’ve used a new method to get the currently logged in user’s name:

Auth::user()->name;

We can get any information about the current user with the user method:

Auth::user()->id;
Auth::user()->email;

The template code first checks the login status of the visitor. If the visitor has logged in, the template shows a new post form; else it shows a login form.

Now we have to code the controller side of our blog application. Let’s start from our users controller. Create a file under app/controller/, which is named UsersContoller.php. The final code of the controller should be as follows:

<?php

class UsersController extends BaseController{

  public function postLogin()
  {
    Auth::attempt(array('email' => Input::get('email'),'password' => Input::get('password')));
  return Redirect::route('add_new_post');

  }
 
  public function getLogout()
  {
    Auth::logout();
    return Redirect::route('index');
  }
}

The controller has two functions: the first is the postLogin() function. This function basically checks the posted form data for user login and then redirects the visitor to the add_new_post route to show the new post form. The second function processes the logout request and redirects to the index route.

Saving a blog post

Now we need one more controller for our blog posts. So, create a file under app/http/controller/, that is named PostsContoller.php. The final code of the controller should be as follows:

<?php
class PostsController extends BaseController{

  public function getIndex()
  {
 
  $posts = Post::with('Author')-> orderBy('id', 'DESC')->get();
  return View::make('index')->with('posts',$posts);
 
  }
  public function getAdmin()
  {
  return View::make('addpost');
  }
  public function postAdd()
  {
  Post::create(array(
              'title' => Input::get('title'),
              'content' => Input::get('content'),
              'author_id' => Auth::user()->id
   ));
  return Redirect::route('index');
  }
}

Assigning blog posts to users

The postAdd() function processes the new blog post create request on the database. As you can see, we can get the author’s ID with a previously mentioned method:

Auth::user()->id

With this method, we can assign the current user with a blog post. As you will see, we have a new method in the query:

Post::with('Author')->

If you remember, we’ve defined a public Author () function in our Posts model:

public function Author(){

      return $this->belongsTo('User','author_id');
}

The belongsTo() method is an Eloquent function to create relations between tables. Basically the function needs one required variable and one optional variable. The first variable (required) defines the target Model. The second and optional variable is to define the source column of the current model’s table. If you don’t define the optional variable, the Eloquent class searches thetargetModelName_id column. In the posts table, we store the authors’ IDs in the author_idcolumn, not in the column named user_id. Because of this, we need to define a second optional variable in the function. With this method, we can pass our blog posts and all its authors’ information to the template file. You can think of the method as some kind of a SQL join method.


When we want to use these relation functions in queries, we can easily call them as follows:

Books::with('Categories')->with('Author')->get();

It is easy to manage the template files with fewer variables. Now we have just one variable to pass the template file, which is combined with all the necessary data. So, we need the second template file to list our blog posts. This template will work at our blog’s frontend.

Listing articles

In the previous sections of this chapter, we’ve learned to use PHP if/else statements within blade template files. Laravel passes data to the template file as an array. So we need to use the foreachloop to parse data into the template file. We can also use a foreach loop in template files. So create a file under resources/views/ named index.blade.php. The code should look as follows:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>My Awesome Blog</title>
<link rel="stylesheet" href="/assets/blog/css/styles.css" type="text/css" media="screen" />
<link rel="stylesheet" type="text/css" href="/assets/blog/css/print.css" media="print" />
<!--[if IE]><script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script><![endif]-->
</head>
<body>
<div id="wrapper">
<header>
<h1><a href="/">My Awesome Blog</a></h1>
<p>Welcome to my awesome blog</p>
</header>
<section id="main">
<section id="content">
@foreach($posts as $post)
<article>
<h2>{{$post->title}}</h2>
<p>{{$post->content}}</p>
<p><small>Posted by <b>{{$post->Author->name}}</b> at <b>{{$post->created_at}}</b></small></p>
</article>

@endforeach          
</section>
</aside>
</section>
<footer>
<section id="footer-area">
<section id="footer-outer-block">
<aside class="footer-segment">
<h4>My Awesome Blog</h4>
</aside>
</section>
</section>
</footer>
</div>
</body>
</html>
Let’s dig the code. We’ve used a foreach loop inside the template file to parse all blog post data. Also, we see the combined author data usage in the foreach loop. As you may remember, we get the author information with the belongsTo() method in the model side. The whole relational data parsing is done inside an array, which is named the relation function name. For example, if we had a second relation function, which is named Categories(), the query would be something as follows on the controller side:
$books = Books::with('Author')-> with('Categories')->orderBy('id', 'DESC')->get();
The foreach loop would look as follows:
@foreach($books as $book)

<article>
<h2>{{$book->title}}</h2>
<p>Author: <b>{{$book->Author->name}}</b></p>
<p>Category: <b>{{$book->Category->name}}</b></p>
</article>

@endforeach
 
Paginating the content

Eloquent’s get() method, which we’ve used in the controller side in the Eloquent query, fetches all the data from the database with a given condition. Often we need to paginate the content for a user-friendly frontend or less page loads and optimizations. The Eloquent class has a helpful method to do this quickly, which is called paginate(). This method fetches the data paginated and generates paginate links in the template with just a single line of code. Open theapp/controllers/PostsController.php file and change the query as follows:

$posts = Post::with('Author')->orderBy('id', 'DESC')->paginate(5);

The paginate() method paginates the data with the given numeric value. So, the blog posts will be paginating each page into 5 blog posts. We have to also change our template to show pagination links. Open app/views/index.blade.php and add the following code after the foreach loop:

{{$posts->links()}}

The section in the template, which has the İD as "main", should look as follows:

<section id="main">
<section id="content">
@foreach($posts as $post)

<article>
<h2>{{$post->title}}</h2>
<p>{{$post->content}}</p>
<p><small>Posted by <b>{{$post->Author->name}}</b> at <b>{{$post->created_at}}</b></small></p>
</article>
@endforeach

</section>
{{$posts->links()}}
</section>

The links() function will generate pagination links automatically, if there is enough data to paginate. Else, the function shows nothing.
Wrapping up

In this tutorial, we’ve created a simple blog with Laravel’s built-in functions and the Eloquent database driver. We’ve learned how to paginate the data and Eloquent’s basic data relation mechanism. Also we’ve covered Laravel’s built-in authentication mechanism. In the next chapters, we’ll learn how to work with more complex tables and relational data.