Installation:
composer require vigstudio/vgcomments
php artisan vendor:publish --provider="Vigstudio\Vgcomments\VgcommentsServiceProvider" --tag="migrations"
php artisan migrate
Configure: Publish the config file:
php artisan vendor:publish --provider="Vigstudio\Vgcomments\VgcommentsServiceProvider" --tag="config"
Update config/vgcomments.php with your preferred settings (e.g., default_guard, upload_disk, recaptcha_site_key).
Model Integration:
Add the HasComments trait to your Eloquent model:
use Vigstudio\Vgcomments\Traits\HasComments;
class Post extends Model
{
use HasComments;
}
First Comment: Attach a comment to a model in a controller or blade:
$post = Post::find(1);
$post->comments()->create([
'body' => 'This is my first comment!',
'user_id' => auth()->id(),
]);
Or use the helper:
\Vigstudio\Vgcomments\Facades\Vgcomments::create($post, [
'body' => 'Hello!',
'user_id' => auth()->id(),
]);
Blade Display: Use the provided Blade directives:
@vgcomments($post)
@foreach($post->comments as $comment)
<div>{{ $comment->body }}</div>
@endforeach
@endvgcomments
Form Handling:
Use the Vgcomments facade or model relationship to create comments:
// Via Facade
$comment = \Vigstudio\Vgcomments\Facades\Vgcomments::create($model, $data);
// Via Model Relationship
$model->comments()->create($data);
Ensure $data includes:
body (required)user_id (or user() helper if using auth guard)parent_id (for nested comments), attachments (for files).Validation:
The package includes built-in validation (e.g., required|string for body). Extend via AppServiceProvider:
use Vigstudio\Vgcomments\Events\ValidatingComment;
ValidatingComment::listen(function ($event) {
$event->validator->addRules(['body' => 'max:1000']);
});
Blade Directives:
Use @vgcomments to loop through comments:
@vgcomments($model, ['limit' => 5])
@foreach($comments as $comment)
<div class="comment">
<p>{{ $comment->body }}</p>
<small>By {{ $comment->user->name }}</small>
</div>
@endforeach
@endvgcomments
Customize with options:
@vgcomments($model, [
'with' => ['user'], // Eager load relations
'order' => 'desc', // 'asc' or 'desc'
'limit' => 10,
])
Nested Comments:
Use @vgcomments.nested for threaded replies:
@vgcomments.nested($model, $comment)
@foreach($comment->replies as $reply)
<div class="reply">
{{ $reply->body }}
</div>
@vgcomments.nested($model, $reply)
@endforeach
@endvgcomments.nested
Configuration:
Set upload_disk in config/vgcomments.php (e.g., 'upload_disk' => 'public').
Configure allowed file types in allowed_file_types (default: ['jpg', 'png', 'pdf']).
Handling Uploads:
Use the attachments field in comment data:
$data = [
'body' => 'Check this out!',
'attachments' => $request->file('attachments'), // From Laravel request
];
$comment = $model->comments()->create($data);
Access attachments via $comment->attachments (returns a collection of Attachment models).
Switching Guards:
Set default_guard in config or override per-comment:
$comment = $model->comments()->create([
'body' => 'Hello!',
'user_id' => auth('admin')->id(),
'guard' => 'admin', // Optional: override default_guard
]);
Guest Comments: (Pending feature) Use middleware to allow guests:
// In routes/web.php
Route::post('/comment', function () {
$comment = \Vigstudio\Vgcomments\Facades\Vgcomments::create($model, [
'body' => $request->body,
'user_id' => null, // Guest comment
'ip_address' => $request->ip(),
]);
})->middleware('throttle:10,1'); // Rate limiting
Markdown Rendering:
Enable in config ('enable_markdown' => true). Render in Blade:
{!! \Vigstudio\Vgcomments\Facades\Vgcomments::renderMarkdown($comment->body) !!}
Customize via AppServiceProvider:
\Vigstudio\Vgcomments\Events\RenderingMarkdown::listen(function ($event) {
$event->markdown->extra('tables'); // Enable tables in markdown
});
Emoji Support:
Use :smile: syntax. Configure emoji set in config/vgcomments.php:
'emoji_set' => 'twitter', // Options: 'twitter', 'github', 'emojione'
->with() to eager load relations:
return $model->comments()->with('user')->get();
Or serialize with the facade:
return \Vigstudio\Vgcomments\Facades\Vgcomments::comments($model, [
'with' => ['user', 'attachments'],
]);
JavaScript Uploads: Use the package’s drag-and-drop support with Laravel Mix/Vite:
// Example for direct uploads (requires CSRF token)
const uploadFiles = async (files) => {
const formData = new FormData();
formData.append('_token', '{{ csrf_token() }}');
formData.append('attachments[]', files[0]);
const response = await axios.post('/upload-comment-attachments', formData);
return response.data.attachments;
};
reCaptcha v3: Add to Blade:
<form method="POST" @vgcomments.captcha>
@csrf
<textarea name="body"></textarea>
<button type="submit">Submit</button>
</form>
Validate in controller:
use Vigstudio\Vgcomments\Facades\Vgcomments;
if (!Vgcomments::verifyRecaptcha($request)) {
return back()->withErrors(['recaptcha' => 'Invalid captcha']);
}
Moderation:
Extend the Comment model to add moderation fields:
class Comment extends \Vigstudio\Vgcomments\Models\Comment
{
protected $casts = [
'is_approved' => 'boolean',
];
}
Filter approved comments in Blade:
@vgcomments($model, ['approved' => true])
Deletion: Soft-delete comments:
$comment->delete(); // Uses Laravel's soft deletes
Or force-delete:
$comment->forceDelete();
Factories: Use the provided factory:
$comment = \Vigstudio\Vgcomments\Models\Comment::factory()->create([
'commentable_id' => $model->id,
'commentable_type' => get_class($model),
]);
Feature Tests: Test comment creation:
public function test_comment_creation()
{
$response = $this->post('/comments', [
'body' => 'Test comment',
'commentable_id' => $post->id,
'commentable_type' => Post::class,
]);
$this->assertDatabaseHas('comments', [
'body
How can I help you explore Laravel packages today?