Hello Laravel enthusiasts! In this tutorial, we'll walk through the process of building a basic CRUD (Create, Read, Update, Delete) blog application using Laravel 10 and integrating it with a Bootstrap user interface. By the end of this tutorial, you'll have a functional blog system ready to be customized and expanded according to your needs.
Step 1: Set up a new Laravel project and database configuration.
Step 2: Create a migration for the "posts" table. Run the following command in the terminal:
php artisan make:migration create_posts_table --create=posts
Step 3: In the created migration file (located in database/migrations
), define the columns for the "posts" table:
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreatePostsTable extends Migration
{
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->text('content');
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('posts');
}
}
Step 4: Run the migration to create the "posts" table:
php artisan migrate
Step 5: Generate a model and a controller for the "Post" resource:
php artisan make:model Post --resource --controller
Step 6: In the generated app/Http/Controllers/PostController.php
file, add the following methods:
use App\Models\Post;
use Illuminate\Http\Request;
class PostController extends Controller
{
public function index()
{
$posts = Post::latest()->get();
return view('posts.index', compact('posts'));
}
public function create()
{
return view('posts.create');
}
public function store(Request $request)
{
Post::create($request->all());
return redirect()->route('posts.index');
}
public function edit(Post $post)
{
return view('posts.edit', compact('post'));
}
public function update(Request $request, Post $post)
{
$post->update($request->all());
return redirect()->route('posts.index');
}
public function destroy(Post $post)
{
$post->delete();
return redirect()->route('posts.index');
}
}
Step 7: Create the following views in the resources/views/posts
directory:
index.blade.php
(for displaying all posts):
@extends('layouts.app')
@section('content')
<div class="container">
<h1>Blog Posts</h1>
<a href="{{ route('posts.create') }}" class="btn btn-primary mb-3">Create New Post</a>
<table class="table">
<thead>
<tr>
<th>Title</th>
<th>Content</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
@foreach ($posts as $post)
<tr>
<td>{{ $post->title }}</td>
<td>{{ $post->content }}</td>
<td>
<a href="{{ route('posts.edit', $post->id) }}" class="btn btn-sm btn-primary">Edit</a>
<form action="{{ route('posts.destroy', $post->id) }}" method="POST" style="display: inline;">
@csrf
@method('DELETE')
<button type="submit" class="btn btn-sm btn-danger" onclick="return confirm('Are you sure?')">Delete</button>
</form>
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
@endsection
create.blade.php
(for creating a new post):
@extends('layouts.app')
@section('content')
<div class="container">
<h1>Create New Post</h1>
<form action="{{ route('posts.store') }}" method="POST">
@csrf
<div class="form-group">
<label for="title">Title</label>
<input type="text" name="title" id="title" class="form-control">
</div>
<div class="form-group">
<label for="content">Content</label>
<textarea name="content" id="content" rows="5" class="form-control"></textarea>
</div>
<button type="submit" class="btn btn-primary">Create Post</button>
</form>
</div>
@endsection
edit.blade.php
(for editing an existing post):
@extends('layouts.app')
@section('content')
<div class="container">
<h1>Edit Post</h1>
<form action="{{ route('posts.update', $post->id) }}" method="POST">
@csrf
@method('PUT')
<div class="form-group">
<label for="title">Title</label>
<input type="text" name="title" id="title" class="form-control" value="{{ $post->title }}">
</div>
<div class="form-group">
<label for="content">Content</label>
<textarea name="content" id="content" rows="5" class="form-control">{{ $post->content }}</textarea>
</div>
<button type="submit" class="btn btn-primary">Update Post</button>
</form>
</div>
@endsection
Step 8: Create a basic layout in resources/views/layouts/app.blade.php
:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Blog Application</title>
<link rel="stylesheet" href="{{ asset('css/app.css') }}">
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<div class="container">
<a class="navbar-brand" href="{{ route('posts.index') }}">Blog</a>
</div>
</nav>
@yield('content')
<script src="{{ asset('js/app.js') }}"></script>
</body>
</html>
Step 9: Finally, update the routes in routes/web.php
:
use App\Http\Controllers\PostController;
Route::get('/', [PostController::class, 'index'])->name('posts.index');
Route::get('/posts/create', [PostController::class, 'create'])->name('posts.create');
Route::post('/posts', [PostController::class, 'store'])->name('posts.store');
Route::get('/posts/{post}/edit', [PostController::class, 'edit'])->name('posts.edit');
Route::put('/posts/{post}', [PostController::class, 'update'])->name('posts.update');
Route::delete('/posts/{post}', [PostController::class, 'destroy'])->name('posts.destroy');
Step 10: Run the application and navigate to the root URL (http://localhost:8000
by default).