Simple Blog in Laravel
The purpose of this story is to get started with Laravel and create a very simple project. Uses Laravel 8.
Prerequisites
In order to install and run the Laravel project we need to have:
- Composer, a PHP dependency manager (for Windows download the exe installer)
- npm, a JavaScript packeage manager. Install Node.js in order to have npm, too.
- A command line terminal. If you are on windows I recommend GitBash which is installed along with Git.
Create a new Laravel project
There are many different ways to create a new project, here we use composer:
composer create-project laravel/laravel blog
This will download all necessary dependencies and will create the new project in a folder named blog.
Change directory into the newly created blog folder.
Examining files and folders
Opening the project folder with an IDE like Visual Studio Code or PhpStrom we see a long list of files and folders. In order to build this project we are going to use the following:
- .env: configuration file
- artisan: command line tool used to perform many tasks in Laravel
- app/Models: folder to hold models
- app/Http/Controllers: folder where controllers are located
- database/migrations: migration files, used to maintain tables in the database
- resources/views: here we add the user interface pages as blade templates
- routes/web.php: in this file the urls of the app are defined as routes and they are associated to a controller and a function in the controller
Run the application by:
php artisan serve
then open http://127.0.0.1:8000 and you will see the default Laravel home page.
Database
Create a database using any tool you prefer. Here we created a MySQL database using phpMyAdmin called blog
and a user bloguser
which is granted all privileges to this database.
Then provide this information in the .env file (change according to whatever was used as DB name, user, and password):
DB_DATABASE=blog
DB_USERNAME=bloguser
DB_PASSWORD=1111
Migrations is a powerful mechanism to maintain the database schema through the application. This is very convenient because everything related to the database structure is in migration files. These files are committed to Git and shared on GitHub, hence, everyone on the team will get the latest migration files and can run a migration in order to have the database schema in the same state as everyone else in the team.
In the migrations folder there are already three (3) migrations and they are applied by running:
php artisan migrate
Checking the database we see four tables: users, password_resets, failed_jobs, and migrations. The last one keeps track of the migrations applied.
Authentication
Laravel has scaffolded authentication kits. The easiest for beginners is Breeze. Install it by:
composer require laravel/breeze --dev
php artisan breeze:install
npm install
npm run dev
Now the home page has links for Login and Registration and we can create (register) some users.
Blog Posts
In order to add blog posts we need to create the respective table in the database. Laravel has an Object to Relational Mapping (ORM) mechanism called Eloquent . ORM associated model classes to the respective database tables using dome conventions. The class name of the model will be associated to the same name table in the database but in plural. For example the class Blogpost interacts with the blogposts table.
First create a migration:
php artisan make:migration create_blogpost_table --creat=blogposts
and a model:
php artisan make:model Blogpost
In the migration file that is created we add the columns necessary for the blog post: title, content, and the user_id which defines the user who wrote this post.
Also, the user has a one-to-many relationship with the blogpost and this relationship will be defined in the migration.
public function up()
{
Schema::create('blogposts', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->text('content');
$table->unsignedBigInteger('user_id');
$table->timestamps();
$table->foreign('user_id')->references('id')->on('users');
});
}
Finally, in order to be able to use the relationship we add the following function to the User model:
public function blogposts() {
return $this->hasMany(Blogpost::class);
}
Adding routes and controller
We will add the following pages:
- /users: Displays a list of the users. Each user is a link that leads to the blog of the respective user.
- /user/id: Displays the blog of a specific user. The id of the user is provided as part of the URL.
- /addblogpost: Adds a new post
Route::get('/users', [BlogController::class, 'users']);
Route::get('/user/{id}', [BlogController::class, 'user']);
Route::post('/addblogpost', [BlogController::class, 'addblogpost'])->middleware(['auth']);
Each route is associated with a function in the BlogController. Controllers organise the behaviour of each route as functions in a controller class.
The BlogController is created by:
php artisan make:controller BlogController
and contains the respective functions for each route:
Function users retrieves all users from the database and invokes the users view
public function users() {
$context['users'] = User::all();
return view('users', $context);
}
Function user retrieves the user defined in the URL by its id and invokes the user view
public function user($id) {
$context['user'] = User::find($id);
return view('user', $context);
}
Function addblogpost retrieves the data submitted by the user via a form
public function addblogpost(Request $request) {
$user = auth()->user();
$blogpost = new Blogpost();
$blogpost->title = $request->get('title');
$blogpost->content = $request->get('content');
$blogpost->user_id = $user->id;
$blogpost->save();
return redirect('dashboard');
}
The context associative array in these functions plays the role of a bag where we can put any data that should be submitted to the view in order to be displayed. Whatever subscript we use for this array will be found as a variable in the view.
Views
Views are using the blade templating system . This has the benefit of adding minimal code in the web page which makes maintenance and design much easier.
View users receives a list of User objects from the controller and displays them in a loop:
<h1>Users</h1>
@foreach($users as $user)
<p><a href="/user/{{ $user->id }}">{{ $user->name }}</a></p>
@endforeach
View user receives the data of the user specified by its id in the URL and displays the user name and the user's blog posts. Blog posts are accessed using the relationship function we added in the User model.
<h1>{{ $user->name }}</h1>
@foreach($user->blogposts as $blogpost)
<div>
<h2>{{ $blogpost->title }}</h2>
<p>{{ $blogpost->content }}</p>
</div>
@endforeach
In the existing dashboard View, a form is added. This form contains a @csrf
statement which adds a hidden field with a random value in order to protect from Cross-Site Request Forgery attacks.
<h2>Add blogpost</h2>
<form method="post" action="/addblogpost">
@csrf
Title: <input type="text" name="title" /><br>
Content: <textarea name="content"></textarea><br>
<input type="submit">
</form>
Endnote
This is a very simple (and not so interesting) Laravel application, aiming to introduce the key components of the framework.
It can be used as a basis for further development, for example to create a clone of a blog application like Wordpress.