| Install | |
|---|---|
composer require modularavel/favoritable |
|
| Latest Version: | v1.0.0 |
| PHP: | >=8.1 |
A Laravel Livewire package that adds favorites functionality to your Laravel 11+ application. Allow users to favorite any model in your application with a beautiful, customizable UI.
Install the package via Composer:
composer require modularavel/favoritable
Publish the migrations:
php artisan vendor:publish --tag="modularavel:favoritable-migrations"
Run the migrations:
php artisan migrate
Optionally, publish the config file:
php artisan vendor:publish --tag="modularavel:favoritable-config"
Optionally, publish the views for customization:
php artisan vendor:publish --tag="modularavel:favoritable-views"
Add the Favoritable trait to any model you want users to be able to favorite:
use Modularavel\Favoritable\Traits\HasModularavelFavoritable;
class Post extends Model
{
use HasModularavelFavoritable;
}
Add the package CSS to your main CSS file or import it in your layout:
@import '../../vendor/modularavel/favoritable/resources/css/favoritable.css';
Or include it directly in your Tailwind config:
module.exports = {
content: [
'./vendor/modularavel/favoritable/resources/**/*.blade.php',
],
}
The simplest way to add a favorite button:
<livewire:favoritable-btn :model="$post" />
Choose from multiple button styles:
{{-- Default variant --}}
<livewire:favoritable-btn :model="$post" variant="default" />
{{-- Outline variant --}}
<livewire:favoritable-btn :model="$post" variant="outline" />
{{-- Solid variant --}}
<livewire:favoritable-btn :model="$post" variant="solid" />
{{-- Icon only variant --}}
<livewire:favoritable-btn :model="$post" variant="icon" />
Choose from three sizes:
{{-- Small --}}
<livewire:favoritable-btn :model="$post" size="sm" />
{{-- Medium (default) --}}
<livewire:favoritable-btn :model="$post" size="md" />
{{-- Large --}}
<livewire:favoritable-btn :model="$post" size="lg" />
You can hide the favorites counter:
<livewire:favoritable-btn :model="$post" :show-count="false" />
Display a paginated list of user's favorites:
<livewire:favoritable-list />
Show only favorites of a specific type:
<livewire:favoritable-list type="Post::class" />
<livewire:favoritable-list :per-page="20" />
The Favoritable trait adds several helpful methods to your models:
// Check if favorited by a user
$post->isFavoritedBy($user);
// Toggle favorite
$post->toggleFavorite($user);
// Add favorite
$post->addFavorite($user);
// Remove favorite
$post->removeFavorite($user);
// Get favorites count
$post->favoritesCount();
// Query scope for favorited items
Post::favoritedBy($user)->get();
To customize how your favorited items appear in the favorites list, implement these methods in your model:
class Post extends Model
{
use Favoritable;
public function getFavoritableTitle(): string
{
return $this->title;
}
public function getFavoritableDescription(): ?string
{
return $this->excerpt;
}
public function getFavoritableImage(): ?string
{
return $this->featured_image;
}
public function getFavoritableUrl(): string
{
return route('posts.show', $this);
}
}
The package includes a configuration file with sensible defaults:
return [
// The fully qualified class name of the user model
'user_model' => env('FAVORITABLE_USER_MODEL', 'App\\Models\\User'),
// The name of the belongTo relationship on the favoritable model to the user model
'owner_relationship_name' => env('FAVORITABLE_OWNER_RELATIONSHIP_NAME', 'user'),
// Button configuration
'button' => [
'default_variant' => 'default',
'default_size' => 'md',
'show_count' => true,
],
// List configuration
'list' => [
'per_page' => 12,
],
];
The package dispatches Livewire events that you can listen to:
favoriteToggledDispatched when a favorite is toggled:
Livewire.on('favoriteToggled', (data) => {
console.log(data.modelType);
console.log(data.modelId);
console.log(data.isFavorited);
});
The package includes comprehensive Pest tests. To run tests:
composer test
The package uses Tailwind CSS for styling. All styles are scoped to avoid conflicts with your application. You can customize the appearance by:
If you need to extend the Favorite model:
use Modularavel\Favoritable\Models\Favorite as BaseFavorite;
class Favorite extends BaseFavorite
{
// Your custom code
}
Protect your favorites routes with middleware:
Route::middleware(['auth'])->group(function () {
Route::get('/favorites', function () {
return view('favorites');
});
});
MIT
For issues, questions, or contributions, please visit the GitHub repository.