Hello and welcome to this tutorial series, my name is Henry and I will be taking you through the various aspect of creating a simple blog system using Laravel web framework. In Part VII we learned how to upload and display an image. In this lesson, we are going to learn how to edit and update our posts.
In our admin dashboard, we had the following results:
The Process of Editing Our Post
- When you click on the edit button, you should get a form with data of a given post.
- In our button, we need to pass id of a specific post.
- In our HomeController we are going to create a method or function that will perform a query search using the blog post id.
- We pass the results to a view that has form and fill in the fields using the data we get from our results.
Getting Started
Open HomeController and make sure it has the following code:
<?php namespace App\Http\Controllers; use App\Blog; use App\User; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; class HomeController extends Controller { /** * Create a new controller instance. * * @return void */ public function __construct() { $this->middleware('auth'); } /** * Show the application dashboard. * * @return \Illuminate\Contracts\Support\Renderable */ public function index() { return view('home'); } public function getRegisteredUsers() { $users = User::orderBy('id', 'DESC')->get(); return view('users', ['users' => $users]); } /** * A function to show a list of all blog posts */ public function PostList() { $posts = Blog::with('writer')->get(); // dd($posts); return view('post_list', ['posts' => $posts]); } /** * A function to show a form to create post */ public function createPost() { return view('post_create'); } /** * A function to store our post */ public function storePost(Request $request) { $request->validate([ 'title' => 'required', 'body' => 'required', 'image' => 'required|image|mimes:jpeg,png,jpg,gif,svg|max:2048', ] ); $image = $request->file('image'); $input['imagename'] = time().'.'.$image->getClientOriginalExtension(); $destinationPath = public_path('/images'); $image->move($destinationPath, $input['imagename']); $article = new Blog(); $article->title = $request->get('title'); $article->body = $request->get('body'); $article->author = Auth::id(); $article->image = $input['imagename']; $article->save(); return redirect()->route('all_posts')->with('status', 'New article has been successfully created!'); } public function editPost($post_id) { $post = Blog::find($post_id); return view('edit_form', ['post' => $post]); } }
Let’s understand the code:
- From line 88 to 92, we have created a method called editPost. This method accepts a parameter called $post_id which will actually have our post id.
- Line 90 – we use eloquent to fetch a single post based on the id.
- Line 91 – we return a view called edit_form and we pass the results of our query in form of an array. Now we need to create edit_form view in our views folder. Here is the folder structure after creating our edit_form view.
Make sure that edit_form.blade.php file has the following code:
@extends('layouts.app') @section('content') <div class="container-fluid"> <div class="row"> @include('partials.sidenavbar') <main role="main" class="col-md-9 ml-sm-auto col-lg-10 px-4"> <div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom"> <h1 class="h2">Create A Post</h1> </div> <form action="" method="post" enctype="multipart/form-data"> {{ csrf_field() }} <div class="form-group"> <label for="title">Title</label> <input type="text" class="form-control" value="{{ $post->title }}" aria-describedby="emailHelp" placeholder="Enter blog title" name="title" required> </div> <div class="form-group"> <label for="body">Blog Content</label> <textarea class="form-control" rows="5" name="body" required>{{ $post->body }}</textarea> </div> <div class="form-group"> <label for="exampleFormControlFile1">Feature Image</label> <input type="file" class="form-control-file" id="exampleFormControlFile1" name="image"> </div> <button type="submit" class="btn btn-primary">Update Post</button> </form> </main> </div> </div> @endsection
Let’s understand the code:
- Basically, the code in this file is exactly the same as post_create form.
- Line 18 – we have added an attribute called value and we are showing the current title of a given post. This will give us ability to edit title
- Line 22 – we show the current content of given post so that the author can edit. In this form, I am choosing not to show the current image but it’s possible to do it.
The next step is to create a route that goes to our editPost method in our HomeController. Open the web.php file and make sure it has the following code:
<?php /* |-------------------------------------------------------------------------- | Web Routes |-------------------------------------------------------------------------- | | Here is where you can register web routes for your application. These | routes are loaded by the RouteServiceProvider within a group which | contains the "web" middleware group. Now create something great! | */ Route::get('/', function () { return view('welcome'); }); Auth::routes(); Route::get('/home', 'HomeController@index')->name('home'); Route::get('/registered/users', 'HomeController@getRegisteredUsers')->name('registered_users'); Route::get('/all/posts', 'HomeController@PostList')->name('all_posts'); Route::get('/create/post', 'HomeController@createPost')->name('create_post'); Route::post('/store/post', 'HomeController@storePost')->name('store_new_post'); Route::get('/edit/post/{post_id}', 'HomeController@editPost')->name('edit_post_form');
Line 25 – we have created a get route named edit_post_form. You will notice that this route has a place holder called post_id which will pass our post id to our editPost method in our HomeController.
The next step is to update our post_list file, make sure post_list.blade.php file has the following code:
@extends('layouts.app') @section('content') <div class="container-fluid"> <div class="row"> @include('partials.sidenavbar') <main role="main" class="col-md-9 ml-sm-auto col-lg-10 px-4"> <div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom"> <h1 class="h2">All Posts </h1> <a href="{{ route('create_post') }}" class="btn btn-primary float-right">Add Post</a> </div> @if (session('status')) <div class="alert alert-success"> {{ session('status') }} </div> @endif <div class="row"> @foreach($posts as $post) <div class="col-md-4"> <div class="card" style="width: 18rem;"> @if($post->image) <img class="card-img-top" src="{{ asset('images/'.$post->image) }}" alt="Blog Post Image"> @endif <div class="card-body"> <h5 class="card-title">{{ $post->title }} by <small><i>{{ $post->writer->name }}</i></small></h5> <p class="card-text"> {{ $post->body }} </p> <a href="{{ route('edit_post_form', ['post_id' => $post->id]) }}" class="card-link btn btn-primary">Edit</a> <a href="#" class="card-link btn btn-danger" >delete</a> </div> </div> </div> @endforeach </div> </main> </div> </div> @endsection
Line 34 – we have edit our href attribute to call our edit_post_form route, we also pass the id of a post as an array.
Make sure your development server is running, log in to the application and click the edit post button. Here is my output:
Great work!
The Process of Updating Our Post
- When author clicks on Update Post button, we pass the id of a post to our updating route.
- Our route will pass the post id to HomeController where we will create post updating method.
- After updating the post, we redirect the author with a success message.
Open HomeController and make sure it has the following code:
<?php namespace App\Http\Controllers; use App\Blog; use App\User; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; class HomeController extends Controller { /** * Create a new controller instance. * * @return void */ public function __construct() { $this->middleware('auth'); } /** * Show the application dashboard. * * @return \Illuminate\Contracts\Support\Renderable */ public function index() { return view('home'); } public function getRegisteredUsers() { $users = User::orderBy('id', 'DESC')->get(); return view('users', ['users' => $users]); } /** * A function to show a list of all blog posts */ public function PostList() { $posts = Blog::with('writer')->get(); // dd($posts); return view('post_list', ['posts' => $posts]); } /** * A function to show a form to create post */ public function createPost() { return view('post_create'); } /** * A function to store our post */ public function storePost(Request $request) { $request->validate([ 'title' => 'required', 'body' => 'required', 'image' => 'required|image|mimes:jpeg,png,jpg,gif,svg|max:2048', ] ); $image = $request->file('image'); $input['imagename'] = time().'.'.$image->getClientOriginalExtension(); $destinationPath = public_path('/images'); $image->move($destinationPath, $input['imagename']); $article = new Blog(); $article->title = $request->get('title'); $article->body = $request->get('body'); $article->author = Auth::id(); $article->image = $input['imagename']; $article->save(); return redirect()->route('all_posts')->with('status', 'New article has been successfully created!'); } public function editPost($post_id) { $post = Blog::find($post_id); return view('edit_form', ['post' => $post]); } public function updatePost(Request $request, $post_id) { $post = Blog::find($post_id); $post->title = $request->get('title'); $post->body = $request->get('body'); if ($request->hasFile('image')) { $image = $request->file('image'); $input['imagename'] = time().'.'.$image->getClientOriginalExtension(); $destinationPath = public_path('/images'); $image->move($destinationPath, $input['imagename']); $post->image = $input['imagename']; } $post->save(); return redirect()->route('all_posts')->with('status', 'Post has been successfully updated!'); } }
Let’s understand the code:
- Line 94 to 110 – we have created a method called updatePost which has two parameter, request and post_id.
- Line 96 – we find the post we want to update using the post_id passed to this method.
- Line 97 – we get the updated title from our request.
- Line 98 – we get the updated content from our request.
- Line 100 to 106 – we have created a control statement using if.
- Line 100 – we check our request whether the user wants to upload an image. If the request has the image we process the image from line 101 to 105.
- Line 107 – we save our post update.
- Line 108 – we redirect user to our post list with a success message. The next step is to create a route that comes to our updatePost method.
Open web.php file and make sure it has the following code:
<?php /* |-------------------------------------------------------------------------- | Web Routes |-------------------------------------------------------------------------- | | Here is where you can register web routes for your application. These | routes are loaded by the RouteServiceProvider within a group which | contains the "web" middleware group. Now create something great! | */ Route::get('/', function () { return view('welcome'); }); Auth::routes(); Route::get('/home', 'HomeController@index')->name('home'); Route::get('/registered/users', 'HomeController@getRegisteredUsers')->name('registered_users'); Route::get('/all/posts', 'HomeController@PostList')->name('all_posts'); Route::get('/create/post', 'HomeController@createPost')->name('create_post'); Route::post('/store/post', 'HomeController@storePost')->name('store_new_post'); Route::get('/edit/post/{post_id}', 'HomeController@editPost')->name('edit_post_form'); Route::post('/update/post/{post_id}', 'HomeController@updatePost')->name('update_post');
Line 26, we have created a post route called update_post. We have also created a place holder for our post_id which will be passed by our edit_form. The next step is to update the edit_form.blade.php file and make sure it has the following code:
@extends('layouts.app') @section('content') <div class="container-fluid"> <div class="row"> @include('partials.sidenavbar') <main role="main" class="col-md-9 ml-sm-auto col-lg-10 px-4"> <div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom"> <h1 class="h2">Create A Post</h1> </div> <form action="{{ route('update_post', ['post_id' => $post->id]) }}" method="post" enctype="multipart/form-data"> {{ csrf_field() }} <div class="form-group"> <label for="title">Title</label> <input type="text" class="form-control" value="{{ $post->title }}" aria-describedby="emailHelp" placeholder="Enter blog title" name="title" required> </div> <div class="form-group"> <label for="body">Blog Content</label> <textarea class="form-control" rows="5" name="body" required>{{ $post->body }}</textarea> </div> <div class="form-group"> <label for="exampleFormControlFile1">Feature Image</label> <input type="file" class="form-control-file" id="exampleFormControlFile1" name="image"> </div> <button type="submit" class="btn btn-primary">Update Post</button> </form> </main> </div> </div> @endsection
Line 14, we have added our update_post route in our action attribute. We have also passed our post id. Now edit your post and hit the Update post button. Here is the output of my action after editing my post:
I get success message notifying me that the post has been updated.
Goal Achieved in this lesson
- We have learnt how to pass an id to a route.
- We have learnt how filter post by id using eloquent
- We have learnt how update our post.
Task
Try to implement the ability to delete a post. Learn how to delete items in Laravel 5.7.
In the next lesson, we will continue building our blog admin portal, step by step together with you and this lesson has given us a great starting point. See you in Lesson IX
You can grab the code used in this tutorial at blog application in Laravel 5.7
Facebook Comments