Posts Learn Snippets Categories Tags About
/
Building Popular Posts Component with Laravel Livewire cover

Building Popular Posts Component with Laravel Livewire

Let's build a page component to display the popular content (post) with Laravel Livewire

2 weeks ago

8 mins read

949 views

In this post, you'll learn how to build a Livewire component to display the popular post or any other content of your website. The prerequisite for this tutorial is to have Laravel Views/Visitor Counter implemented on your Laravel project and with that out of the way, let's get started and create the component.

Popular Post Page Livewire Component


Create a new Livewire Component
Let's create a livewire component by making use of the "php artisan livewire:make" command. I'll let you name however you want it.
php artisan livewire:make Posts/Popular

By running the command above the "class" and "view" for the component will be created.
CLASS: app/Http/Livewire/Posts/Popular.php
VIEW:  resources/views/livewire/posts/popular.blade.php

Define the Route
Now that we have the component, let's define a new route that will be used to access the popular posts component. It's also recommended that you provide the route name to easily reference the route and generate the link.
Route::get('/posts/popular', \App\Http\Livewire\Posts\Popular::class)
    ->name('posts.popular');

Component Class
The component class will contain the "logic to retrieve the popular posts" with a filter to select the "periods". We'll also be making use of Livewire computed properties to dynamically retrieve the post based on the selected duration.

Since the page will contain a filter dropdown, you can define the value in the component property itself. This property will be looped through in the blade view and be placed with the select option.
public $selectedDuration = 7;

public $periods = [
    1 => 'Today',
    7 => 'Last 7 days',
    14 => 'Last 14 days',
    28 => 'Last 28 days',
];

Get Posts Computed Property
The computed property will retrieve all of the popular posts by the total number of views using "orderByViews" method. Do note that this method is provided by the eloquent viewable package. Now every time the "selectedDuration" property is updated, this computed property will get executed and perform the query to re-retrieve the post with the specified condition.
use CyrildeWit\EloquentViewable\Support\Period;

public function getPostsProperty()
{
    return Post::query()
        ->orderByViews('desc', Period::pastDays($this->selectedDuration))
        ->get()
        ->toArray();
}

Complete Example
The complete code example should be as follows.
<?php

namespace App\Http\Livewire\Posts;

use App\Models\Post;
use Livewire\Component;
use CyrildeWit\EloquentViewable\Support\Period;

class Popular extends Component
{
    public $selectedDuration = 7;

    public $periods = [
        1 => 'Today',
        7 => 'Last 7 days',
        14 => 'Last 14 days',
        28 => 'Last 28 days',
    ];

    public function getPostsProperty()
    {
        return Post::query()
            ->orderByViews('desc', Period::pastDays($this->selectedDuration))
            ->get()
            ->toArray();
    }

    public function render()
    {
        return view('livewire.posts.popular');
    }
}

The Views
For the blade views, it will be located inside the "livewire.posts.popular" directory. The page structure for this should be quite generic depending on how you style the page so the code example below will just show the logic of the implementation.

The select will contain the "periods" and it will be making use of "wire:model" to sync with the "selectedDuration" value. So anytime the option is chosen from the select, the value of the "selectedDuration" will be updated.
<select wire:model="selectedDuration">
    @foreach($periods as $duration => $period)
        <option value="{{ $duration }}">
            {{ $period }}
        </option>
    @endforeach
</select>

The post looping will be like usual and you can make use of your own custom structure and styling. One important takeaway to access the computed property is to use "$this->posts" variable and this is necessary for it to work.
@foreach($this->posts as $post)
    <div class="card">
        <h1>{{ $post->title }}</h1>
    </div>
@endforeach

Now that you have seen how the logic of the component code, you will be able to implement it for different types of components in your project. To see how this works in production you can visit PostSrc Popular Posts page. If you find this tutorial to be helpful do share it with others and cheers 🍻. happy coding!