Posts Learn Components new Snippets new Categories Tags About
/

Building Popular Posts Component with Laravel Livewire

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

3 months ago

8 mins read

1219 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!

Alternative Tags

new

If you like our tutorial, do make sure to support us with some coffee. We need the juice to write the content during the night 🤙🏻