Unfortunately, I don't have the time to adequately maintain this package. I recommend Xetaravel-Mentions which appears to be better maintained with similar functionality.
In hindsight, this package has tried to do too much to implement this functionality. If you're looking to implement mentions, I think you'd be better off implementing the front-end manually, and abstracting the back-end to that package above or writing your own API.
Hope this helps!
This Laravel >=5.4 package provides an easy way to setup mentions for Eloquent models. It provides the front-end for inserting mentions into content-editable elements, the back-end for associating mentions with models and lastly an elegant way to notify the mentioned models that they have been mentioned.
Here are a few short examples of what you can do:
// Mention a single user
$comment->mention($user);
// Mention a collection of users
$comment->mention($users);
// Handle the form data
$comment->mention($request->mentions);
// Get all mentions, resolved to their models
$comment->mentions();
// Unmention a single user
$comment->unmention($user);
// Unmention a collection of users
$comment->unmention($users);
It handles notifications for you as well. If your mentions config has auto_notify
enabled, it will do it for you. If you need to handle the logic yourself, disable auto_notify
and explicitly notify the mention, for example:
$mention = $comment->mention($user);
$mention->notify();
You can install this package via composer using this command:
composer require jameslkingsley/laravel-mentions
If you're using Laravel 5.5 or greater this package will be auto-discovered, however if you're using anything lower than 5.5 you will need to register it the old way:
Next, you must install the service provider in config/app.php
:
'providers' => [
...
Kingsley\Mentions\MentionServiceProvider::class,
];
Now publish the migration, front-end assets and config:
php artisan vendor:publish --provider="Kingsley\Mentions\MentionServiceProvider"
After the migration has been published you can create the mentions table by running the migrations:
php artisan migrate
This is the contents of the published config file:
return [
// The middleware that should be applied to all
// routes that are registered in this package.
'middleware' => null,
// Pools are what you reference on the front-end
// They contain the model that will be mentioned
'pools' => [
'users' => [
// Model that will be mentioned
'model' => 'App\User',
// Filter class that alters the query
'filter' => null,
// The column that will be used to search the model
'column' => 'name',
// Notification class to use when this model is mentioned
'notification' => 'App\Notifications\UserMentioned',
// Automatically notify upon mentions
'auto_notify' => true
]
]
];
First you will need to import Tribute.
npm install tributejs --save-dev
Then include Tribute in your bootstrap.js
file and assign it globally.
import Tribute from "tributejs";
window.Tribute = Tribute;
Now in your bootstrap.js
file you can import the Mentions
class and also assign it globally.
import Mentions from "./laravel-mentions";
window.Mentions = Mentions;
Now to include the styling just import it into your SCSS file.
@import "laravel-mentions";
Now let's setup the form where we'll write a comment that has mentions:
<form method="post" action="{{ route('comments.store') }}">
<!-- This field is required, it stores the mention data -->
<input type="hidden" name="mentions" id="mentions" />
<!-- We write the comment in the div -->
<!-- The for attribute is a helper to auto-populate the textarea -->
<textarea class="hide" name="text" id="text"></textarea>
<div class="has-mentions" contenteditable="true" for="#text"></div>
<button type="submit">
Post Comment
</button>
<!-- CSRF field for Laravel -->
{{ csrf_field() }}
</form>
Next add the script to initialize the mentions:
new Mentions({
// Additional headers to send
// to possibly authenicate
// the current user
http: {
headers: [
// {
// name: "Authorization",
// value: "Bearer your-user-api-token"
// }
]
},
// Input element selector
// Defaults to .has-mentions
input: ".has-mentions",
// Output form field selector
// Defaults to #mentions
output: "#mentions",
// Pools
pools: [
{
// Trigger the popup on the @ symbol
// Defaults to @
trigger: "@",
// Pool name from the mentions config
pool: "users",
// Same value as the pool's 'column' value
display: "name",
// The model's primary key field name
reference: "id"
}
]
});
Now onto the back-end. Choose the model that you want to assign mentions to. In this example I'll choose Comments
. We'll import the trait and use it in the class.
namespace App;
use Illuminate\Database\Eloquent\Model;
use Kingsley\Mentions\Traits\HasMentions;
class Comment extends Model
{
use HasMentions;
}
Next switch to the controller for where you store the comment. In this case it's CommentController
. Create the comment however you like, and afterwards just call the mention
method.
public function store(Request $request)
{
// Handle the comment creation however you like
$comment = Comment::create($request->all());
// Call the mention method with the form mentions data
$comment->mention($request->mentions);
}
That's it! Now when displaying your comments you can style the .mention-node
class that is inserted via Tribute. That same node also has a data-object
attribute that contains the pool name and reference value, eg: users:1
.
You'll most likely need to edit the text content, so it's necessary to restore the mentions list in the form. It's as simple as this:
<input
type="hidden"
name="mentions"
id="mentions"
value="{{ $comment->mentions()->encoded() }}"
/>
Then on the back-end you can update the model's mentions by doing the following:
$comment
->clearMentions()
->mention($request->mentions);
If you want to use notifications, here's some stuff you may need to know.
- When a mention is notified, it will use Laravel's built-in Notification trait to make the notification. That means the model class defined in the pool's config must have the
Notifiable
trait. - It will use the notification class defined in the pool's config, so you can handle it differently for each one.
- The data stored in the notification will always be the model that did the mention, for example
$comment->mention($user)
will store$comment
in the data field. - __construct method of notification class gets the model that did the mention as an argument, for example
$comment->mention($user)
will get$comment
on the constructor.
You might want to apply some custom filters to the model when it retrieves the records. To do this just create a class somewhere in your app, then add it to the mention config:
return [
'pools' => [
'users' => [
...
'filter' => 'App\Filters\UserFilter',
...
]
]
];
This is what your filter class should look like. It just has one static method called handle
that takes the query as an argument, and must return the query.
<?php
namespace App\Filters;
class UserFilter
{
/**
* Handles the filtering and returns the updated query.
*
* @return Illuminate\Database\Eloquent\Builder
*/
public static function handle($query)
{
// Apply your filters here!
return $query->where('someColumn', 'someValue');
}
}
If you'd like to change the JSON response that the /api/mentions
route returns, you can create your own resource class. To begin with head over to the Laravel docs to create and setup a resource class.
Once you have your resource class, simply add it to your mention config in one or more of your pools, such as:
return [
'pools' => [
'users' => [
...
'resource' => 'App\Resources\UserCollection',
...
]
]
];
If you'd like you can optionally add middleware to the /api/mentions
route. This can be useful in case you want to protect the route behind an authentication guard. Head over to the Laravel docs find out more about middleware.
return [
'middleware' => [
'your-middleware-here',
],
//
];