Home/Blog Crud using Laravel Livewire

Blog Crud using Laravel Livewire

Published On: 8 August 2022.By .
  • Product & platform Engineering

Laravel

Laravel is a free and open-source PHP Framework for Web Artisans based on Symfony that helps craft Web Applications following the MVC (Model View Controller) design pattern. Many developers would prefer the MVC framework as the architecture of the app is fully maintained and the management is much more easier than the core web applications structure.

Besides that many frameworks would inbuilt packages that provide us more fundamental security required for every web app, features like authentication, user registration and supported by many 3rd party packages.

What is livewire ?

Livewire is a Laravel library that makes it simple to create contemporary, dynamic interfaces from the comfort of Laravel. If you want to create a dynamic application but are hesitant to use a complete Js framework like Vue or react, this is a fantastic tool to use.

How it works ?

Write a PHP class, that will act as the backend portion of a frontend component. The public fields will be visible to Livewire. Write a frontend component in Laravel’s templating language (Blade). This component references the fields in the backend component that you wrote before. Write methods in your backend-component’s class, that change the state of the public fields. Instantiate the component in another view, or another component.

Why Livewire ?

Nowadays there are many frameworks like Vue js or React js which provide full stack developers many options to work. But they add complexity to them of learning various new skills and then interacting between different languages. While in Livewire we only need to use laravel and PHP and the operations will be performed as if they were performed using js.

Advantages of Livewire

  1. Beginner-friendly, since AJAX requests can be made with little or no JavaScript knowledge
  2. SEO-friendly, as the HTML is sent to the browser on first rendering
  3. Integration into existing Laravel pages possible
  4. Automated testing possible due to included test suite

Disadvantages of Livewire

  1. Increased server load, since all status changes are done via AJAX request
  2. More difficult troubleshooting possible due to mixing of backend frontend logic

Create a Blog Crud using Laravel Livewire

    1. Create a project with name my-blog. Type the following command:
composer create-project --prefer-dist laravel/laravel my-blog
    1. Creating Database
      • Go to http://localhost/phpmyadmin/ 
      • Create new database “myblogs”.
    2. Open the .env file in your code editor
      • APP_NAME key to name of your blog i.e. “My Blog”
      • DB_DATABASE key to database name i.e. myblogs
    3. Run the application, by typing the following command:
      • php artisan serve
      • It will start the application and give you a URL,http://127.0.0.1:8000, open the URL in your browser
    4. Lets reate a new posts table. Run
      • php artisan make:migration create_posts_table
      • If we open up that file, we can add the following schema data to our migration:
<?php

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

class CreatePostsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->id();
            $table->integer('user_id');
            $table->string('title');
            $table->text('body');
            $table->string('slug')->unique();
            $table->boolean('active')->default(1);
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('posts');
    }
}
    1. After creating the migration please run the following command: php artisan serve Before running the migration, be sure to connect your database by adding the correct DB info to your .env file:
...
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=myblogs
DB_USERNAME=root
DB_PASSWORD=
...
    1. Now we will Install Livewire. Run the following command:
      • composer require livewire/livewire
    2. Create our App layout
        • Inside our app, we’ll create a new layout file located at resources/views/layouts/app.blade.php, with the following contents:
      <!DOCTYPE html>
      <html lang="en">
      <head>
          <meta charset="UTF-8">
          <meta name="viewport" content="width=device-width, initial-scale=1.0">
          <title>@yield('title', 'Laravel Blog')</title>
          <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tailwindcss/1.9.6/tailwind.min.css">
      </head>
      <body>
      
          @yield('content')
      
      </body>
      </html>
      • Lets included a CDN link to the Tailwind CSS.
      • Now that we have our main layout file, we can add our Livewire scripts and styles.
    3. Adding the Livewire scripts and style to our layout file is very simple. We include @livewireStyles to our head and @livewireScripts to our body, like so:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>@yield('title', 'Laravel Blog')</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tailwindcss/1.9.6/tailwind.min.css">
    @livewireStyles
</head>
<body>

    @yield('content')

	@livewireScripts
</body>
</html>
  1. Add Our Homepage
      • Inside of routes/web.php, you’ll see a home route pointing to our welcome.blade.php:
    Route::get('/', function () {
        return view('welcome');
    });
      • Lets change this route to the following:
    Route::view('/', 'home');
      • This will point our homepage to a new file at resources/views/home.blade.php. You will want to create that file with the following contents:
    @extends('layouts.app')
    
    @section('content')
    
        <div class="container mx-auto p-5">
            <h1 class="text-4xl mt-32 text-center tracking-tight leading-10 font-extrabold text-gray-900 sm:text-5xl sm:leading-none md:text-6xl">
                Welcome to My Blogs
            </h1>
        </div>
    
    @endsection
      • Using Blade Components, we can create a header component for our blog with the following command:
    php artisan make:component header
      • This will generate our new component view template located at resources/views/components/header.blade.php, which we’ll want to add the following contents:
    <header class="text-gray-700 body-font border-b">
        <div class="container mx-auto flex flex-wrap p-5 flex-col md:flex-row items-center">
            <nav class="flex lg:w-2/5 flex-wrap items-center text-base md:ml-auto">
                <a href="/" class="mr-5 hover:text-gray-900">Home</a>
                <a href="{{ route('blogs') }}" class="mr-5 hover:text-gray-900">Blog</a>
            </nav>
            <a class="flex order-first lg:order-none lg:w-1/5 title-font font-bold items-center text-gray-900 lg:items-center lg:justify-center mb-4 md:mb-0">
                BLOG
            </a>
            <div class="lg:w-2/5 inline-flex lg:justify-end ml-5 lg:ml-0">
                <a href="#_" class="inline-flex items-center bg-gray-200 border-0 py-1 px-3 focus:outline-none hover:bg-gray-300 rounded text-base mt-4 md:mt-0">Login</a>
            </div>
        </div>
    </header>
  2. Create Posts Component
      • Run the following command to create a new Livewire component that will be used for creating posts on our blog:
    php artisan make:livewire PostCreate
      • This will create a component CLASS and a component VIEW in our application located at:
    CLASS: app/Http/Livewire/PostCreate.php
    VIEW:  resources/views/livewire/post-create.blade.php
      • We can add a new route to our routes/web.php, which will load our new component:
    Route::get('post/create', \App\Http\Livewire\PostCreate::class);
      • Open up the app/Http/Livewire/PostCreate.php file, and we can specify the section we want our component to be injected inside our layout file. We can do that by modifying the render() function:
    public function render()
    {
        return view('livewire.post-create')
                ->extends('layouts.app')
                ->section('content');
    }
      • The reason that we added the ->section(‘content’) to our view is that inside of our layout file, we output that section with the @yield(‘content’) line. Next, we’ll add an <h1> to our component view resources/views/livewire/post-create.blade.php, like so:
    <div>
        <div class="container mx-auto px-4">
            <h1 class="text-4xl mt-6 tracking-tight leading-10 font-extrabold text-gray-900 sm:text-5xl sm:leading-none md:text-6xl">Create Post</h1>
            <p class="text-lg mt-2 text-gray-600">Start crafting your new post below.</p>
        </div>
    </div>
  3. Create Post Functionality
      • To create a new post, we’re going to need a Post model, which we can create by running:
    php artisan make:model Post
      • We’ll need a form to create a new post inside of our Livewire view file resources/views/livewire/post-create.blade.php:
    <div>
        <div class="container mx-auto px-4">
            <h1 class="text-4xl mt-6 tracking-tight leading-10 font-extrabold text-gray-900 sm:text-5xl sm:leading-none md:text-6xl">Create Post</h1>
            <p class="text-lg mt-2 text-gray-600">Start crafting your new post below.</p>
            <div class="space-y-8 divide-y divide-gray-200 w-1/2 mt-10">
    
                @if($saveSuccess)
                    <div class="rounded-md bg-green-100 rounded-lg p-4">
                        <div class="flex">
                            <div class="flex-shrink-0">
                                <svg class="h-5 w-5 text-green-400" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
                                    <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd" />
                                </svg>
                            </div>
                            <div class="ml-3">
                                <h3 class="text-sm font-medium text-green-800">Successfully Saved Post</h3>
                                <div class="mt-2 text-sm text-green-700">
                                    <p>Your new post has been saved.</p>
                                </div>
                            </div>
                        </div>
                    </div>
                @endif
    
                <div class="sm:col-span-6">
                    <label for="title" class="block text-sm font-medium text-gray-700">
                        Post Title
                    </label>
                    <div class="mt-1">
                        <input id="title" wire:model="post.title" name="title" class="block w-full transition duration-150 ease-in-out appearance-none bg-white border border-gray-400 rounded-md py-2 px-3 text-base leading-normal transition duration-150 ease-in-out sm:text-sm sm:leading-5">
                    </div>
                </div>
                <div class="sm:col-span-6 pt-5">
                    <label for="body" class="block text-sm font-medium text-gray-700">Body</label>
                    <div class="mt-1">
                        <textarea id="body" rows="3" wire:model="post.body" class="shadow-sm focus:ring-indigo-500 appearance-none bg-white border border-gray-400 rounded-md py-2 px-3 text-base leading-normal transition duration-150 ease-in-out focus:border-indigo-500 block w-full sm:text-sm border-gray-300 rounded-md"></textarea>
                    </div>
                    <p class="mt-2 text-sm text-gray-500">Add the body for your post.</p>
                </div>
                <div wire:click="savePost" class="inline-flex justify-center px-4 py-2 text-sm font-medium leading-5 text-white transition duration-150 ease-in-out bg-indigo-500 border border-transparent rounded-md hover:bg-indigo-600 focus:outline-none focus:border-indigo-700 focus:shadow-outline-indigo active:bg-indigo-700 cursor-pointer">Submit Post</div>
            </div>
        </div>
    </div>
      • In the HTML above, we have a title and body input where we are binding the values to Livewire with wire:model.
      • Now we need to add the logic to our Livewire class app/Http/Livewire/PostCreate.php, so we can easily create a new post.
    <?php
    
    namespace App\Http\Livewire;
    
    use App\Models\Post;
    use Illuminate\Support\Str;
    use Livewire\Component;
    
    class PostCreate extends Component
    {
        public $saveSuccess = false;
        public $post;
    
        protected $rules = [
            'post.title' => 'required|min:6',
            'post.body' => 'required|min:6',
        ];
    
        public function mount(){
            $this->post = new Post;
        }
    
        public function savePost(){
            $this->post->user_id = 1;
            $this->post->slug = Str::slug($this->post->title);
            $this->post->save();
            $this->saveSuccess = true;
        }
    
        public function render()
        {
            return view('livewire.post-create')
                    ->extends('layouts.app')
                    ->section('content');
        }
    }
  4. Displaying Posts
      • Displaying a post is pretty easy. We know that we want a user to visit /post/{slug}, and our application will lookup the post with the corresponding slugslug and display it on the page. Let’s create a new Livewire component with the following command:
    php artisan make:livewire Post
      • And, we’ll have 2 new files created at:
    CLASS: app/Http/Livewire/Post.php
    VIEW:  resources/views/livewire/post.blade.php
      • If we jump into our app/Http/Livewire/Post.php, we can add the following code:
    <?php
    
    namespace App\Http\Livewire;
    
    use App\Models\Post as BlogPost;
    use Livewire\Component;
    
    class Post extends Component
    {
        public $post;
    
        public function mount($slug){
            $this->post = BlogPost::where('slug', $slug)->first();
        }
    
        public function render()
        {
            return view('livewire.post')
                    ->extends('layouts.app')
                    ->section('content');
        }
    }
      • We will also need to add a route that maps to our Livewire controller inside of our routes/web.php:
    Route::get('post/{slug}', \App\Http\Livewire\Post::class);
      • Finally, we can output our post content inside of our Livewire view file located at resources/views/livewire/post.blade.php:
    <div>
        <div class="max-w-4xl mx-auto py-20">
            <h1>{{ $post->title }}</h1>
            <p>{!! $post->body !!}</p>
        </div>
    </div>
  5. Displaying our Post List
      • Lastly, we are going to display our posts in our resources/views/home.blade.php file file. We can easily loop through all of our posts by adding the following code:
    @extends('layouts.app')
    
    @section('content')
    
        <div class="container mx-auto p-5">
            <h1 class="text-4xl mt-32 text-center tracking-tight leading-10 font-extrabold text-gray-900 sm:text-5xl sm:leading-none md:text-6xl">
                Welcome to The Blog
            </h1>
    
            <div class="mt-10 max-w-xl mx-auto">
                @foreach(\App\Models\Post::all() as $post)
                    <div class="border-b mb-5 pb-5 border-gray-200">
                        <a href="/post/{{ $post->slug }}" class="text-2xl font-bold mb-2">{{ $post->title }}</a>
                        <p>{{ Str::limit($post->body, 100) }}</p>
                    </div>
                @endforeach
            </div>
        </div>
    
    @endsection

Conclusions

Laravel Livewire is a great tool and it can be used to make robust and flexible web applications. There are so many features of laravel livewire that i have not used in this blog like state management. Apart from that laravel is the most loved framework and a framework that has a large community.
Let us know your valuable thought about why Laravel is thriving now? Share in the comments below.

Related content

We Love Conversations

Say Hello
Go to Top