Create Blog Post using Livewire in Laravel 10

Livewire in Laravel

Sharing is caring!

422 Views -

Laravel, a popular PHP framework, has continually evolved to simplify web development. One of its most versatile features is Livewire, a real-time framework that enables seamless interaction between the server and client without writing JavaScript code. In this tutorial, we’ll explore how to implement CRUD (Create, Read, Update, Delete) operations using Livewire in Laravel 10 to create a dynamic and engaging blog post management system.

What is Livewire?

Livewire is a powerful technology that facilitates real-time interaction between a web server and client-side interfaces without the need for writing extensive JavaScript code. Developed specifically for the Laravel PHP framework, Livewire simplifies the creation of dynamic, interactive web applications by allowing developers to build rich user experiences using server-rendered HTML.

Setting Up Your Development Environment

Before diving into Livewire and CRUD operations, ensure you have Laravel 10 installed. If not, use Composer to create a new Laravel project

composer create-project laravel/laravel laravel-liwewire-blog

Navigate to the newly created project directory

cd laravel-liwewire-blog

Installing and Configuring Livewire

composer require livewire/livewire

Publishing the configuration file

php artisan livewire:publish --config

Need to call the JavaScript on every page of our application that will be using Livewire.

Create a layouts directory and then create a file named as app.blade.php and add the following code.

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
 
        <title>{{ $title ?? 'Page Title' }}</title>
    </head>
    @livewireStyles
</head>
<body>
    {{ $slot }}
 
    @livewireScripts
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-HwwvtgBNo3bZJJLYd8oVXjrBZt8cqVSpeBNS5n7C8IVInixGAoxmnlMuBnhbgrkm" crossorigin="anonymous"></script>
</body>
</html>

Creating the Blog Post Model and Migration

Generate a new model and migration for your blog posts

php artisan make:migration create_posts_table

php artisan make:model POST

update post migration

<?php

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

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->id();
            $table->string('title')->nullable();
            $table->text('description')->nullable();
            $table->timestamps();
        });
    }

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

Run the migration to create the table

php artisan migrate

Creating Livewire Components

Now, let’s create the Livewire components needed for the CRUD operations

php artisan make:livewire post

This command will output like this

COMPONENT CREATED 🤙
CLASS: app/Http/Livewire//Post.php
VIEW: C:\xampp\htdocs\laravel-liwewire-blog\resources\views/livewire/post.blade.php

Open the Livewire Post container that we created using the above command and update with this code.

<?php

namespace App\Http\Livewire;

use Livewire\Component;
use App\Models\Post as Posts;

class Post extends Component
{
    public $posts, $title, $content, $postId, $updatePost = false, $addPost = false;
 
    /**
     * delete action listener
     */
    protected $listeners = [
        'deletePostListner'=>'deletePost'
    ];
 
    /**
     * List of add/edit form rules
     */
    protected $rules = [
        'title' => 'required',
        'content' => 'required'
    ];
 
    /**
     * Resetting all inputted fields
     * @return void
     */
    public function resetFields(){
        $this->title = '';
        $this->content = '';
    }
 
    /**
     * Render the post data
     * @return \Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View
     */
    public function render()
    {
        $this->posts = Posts::select('id', 'title', 'content')->get();
        return view('livewire.post');
    }
 
    /**
     * Open Create Post form
     * @return void
     */
    public function addPost()
    {
        $this->resetFields();
        $this->addPost = true;
        $this->updatePost = false;
    }
     /**
      * store the post data in the posts table
      * @return void
      */
    public function storePost()
    {
        $this->validate();
        try {
            Posts::create([
                'title' => $this->title,
                'content' => $this->content
            ]);
            session()->flash('success','Post Created Successfully!!');
            $this->resetFields();
            $this->addPost = false;
        } catch (\Exception $ex) {
            session()->flash('error','Something goes wrong!!');
        }
    }
 
    /**
     * show selected post data in edit post form
     * @param mixed $id
     * @return void
     */
    public function editPost($id){
        try {
            $post = Posts::findOrFail($id);
            if( !$post) {
                session()->flash('error','Post not found');
            } else {
                $this->title = $post->title;
                $this->content = $post->content;
                $this->postId = $post->id;
                $this->updatePost = true;
                $this->addPost = false;
            }
        } catch (\Exception $ex) {
            session()->flash('error','Something goes wrong!!');
        }
 
    }
 
    /**
     * update post data
     * @return void
     */
    public function updatePost()
    {
        $this->validate();
        try {
            Posts::whereId($this->postId)->update([
                'title' => $this->title,
                'content' => $this->content
            ]);
            session()->flash('success','Post Updated Successfully!!');
            $this->resetFields();
            $this->updatePost = false;
        } catch (\Exception $ex) {
            session()->flash('success','Something goes wrong!!');
        }
    }
 
    /**
     * Cancel Add/Edit form and redirect to post listing page
     * @return void
     */
    public function cancelPost()
    {
        $this->addPost = false;
        $this->updatePost = false;
        $this->resetFields();
    }
 
    /**
     * delete selected post data from the posts table
     * @param mixed $id
     * @return void
     */
    public function deletePost($id)
    {
        try{
            Posts::find($id)->delete();
            session()->flash('success',"Post Deleted Successfully!");
        }catch(\Exception $e){
            session()->flash('error',"Something went wrong!!");
        }
    }
}

Now create 3 new files.

post.blade.php inside resources/views/livewire

create.blade.php inside resources/views/livewire

update.blade.php inside resources/views/livewire

Open welcome.blade.php and update this code.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Laravel Livewire Blog</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-4bw+/aepP/YC94hEpVNVgiZdgIC5+VKNBQNGCHeKRQN+PtmoHDEXuppvnDJzQIu9" crossorigin="anonymous">
    @livewireStyles
</head>
<body>
    <nav class="navbar navbar-expand-lg navbar-dark bg-dark">
        <div class="container-fluid">
            <a class="navbar-brand" href="/">Laravel Livewire Blog</a>
        </div>
    </nav>
    <div class="container">
        <div class="row justify-content-center mt-3">
            @livewire('post')
        </div>
    </div>
 
    @livewireScripts
  </body>
</html>

 

Open create.blade.php add this code.

<form>
    <div class="form-group">
        <label for="title">Title</label>
       <input type="text" class="form-control @error('title') is-invalid @enderror" id="title" placeholder="Enter Title" wire:model="title">
        @error('title') <span class="text-danger">{{ $message }}</span> @enderror
    </div>
  
    <div class="form-group">
        <label for="content">Content</label>
       <textarea class="form-control @error('content') is-invalid @enderror" id="content" wire:model="content" placeholder="Enter content"></textarea>
        @error('content') <span class="text-danger">{{ $message }}</span> @enderror
    </div>
    <div>
        <button wire:click.prevent="storePost()" class="btn btn-success btn-block">Save</button>
        <button wire:click.prevent="cancelPost()" class="btn btn-secondary btn-block">Cancel</button>
    </div>
</form>

 

Open update.blade.php and add this code.

<form>
    <div class="form-group">
        <label for="title">Title</label>
       <input type="text" class="form-control @error('title') is-invalid @enderror" id="title" placeholder="Enter Title" wire:model="title">
        @error('title') <span class="text-danger">{{ $message }}</span> @enderror
    </div>
  
    <div class="form-group">
        <label for="content">Content</label>
       <textarea class="form-control @error('content') is-invalid @enderror" id="content" wire:model="content" placeholder="Enter content"></textarea>
        @error('content') <span class="text-danger">{{ $message }}</span> @enderror
    </div>
    <div>
        <button wire:click.prevent="updatePost()" class="btn btn-success btn-block">Update</button>
        <button wire:click.prevent="cancelPost()" class="btn btn-secondary btn-block">Cancel</button>
    </div>
</form>

Testing Your Implementation

php artisan serve

Visit the provided URL in your browser and navigate to the page where you’ve included the Livewire components. You should now have a functional blog post management system with CRUD operations using Livewire in Laravel 10.

 

 

0 0 votes
Article Rating
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments