2017 © Pedro Peláez
 

library laravel-mentions

End-to-end mentions in Laravel 5.

image

jameslkingsley/laravel-mentions

End-to-end mentions in Laravel 5.

  • Tuesday, July 10, 2018
  • by jameslkingsley
  • Repository
  • 2 Watchers
  • 58 Stars
  • 197 Installations
  • PHP
  • 0 Dependents
  • 0 Suggesters
  • 5 Forks
  • 0 Open issues
  • 6 Versions
  • 27 % Grown

The README.md

End-to-end Mentions in Laravel 5 & 6

Build Status, (*1)

Abandoned

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., (*2)

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., (*3)


Hope this helps!, (*4)

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., (*5)

Here are a few short examples of what you can do:, (*6)

// 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:, (*7)

$mention = $comment->mention($user);
$mention->notify();

Requirements

Installation

You can install this package via composer using this command:, (*8)

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:, (*9)

Next, you must install the service provider in config/app.php:, (*10)

'providers' => [
    ...
    Kingsley\Mentions\MentionServiceProvider::class,
];

Now publish the migration, front-end assets and config:, (*11)

php artisan vendor:publish --provider="Kingsley\Mentions\MentionServiceProvider"

After the migration has been published you can create the mentions table by running the migrations:, (*12)

php artisan migrate

This is the contents of the published config file:, (*13)

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
        ]
    ]
];

Usage

First you will need to import Tribute., (*14)

npm install tributejs --save-dev

Then include Tribute in your bootstrap.js file and assign it globally., (*15)

import Tribute from "tributejs";
window.Tribute = Tribute;

Now in your bootstrap.js file you can import the Mentions class and also assign it globally., (*16)

import Mentions from "./laravel-mentions";
window.Mentions = Mentions;

Now to include the styling just import it into your SCSS file., (*17)

@import "laravel-mentions";

Now let's setup the form where we'll write a comment that has mentions:, (*18)



{{ csrf_field() }}

Next add the script to initialize the mentions:, (*19)

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., (*20)

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., (*21)

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., (*22)

Editing Content With Mentions

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:, (*23)

<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:, (*24)

$comment
    ->clearMentions()
    ->mention($request->mentions);

Notifications

If you want to use notifications, here's some stuff you may need to know., (*25)

  • 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.

Filters

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:, (*26)

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., (*27)

<?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');
    }
}

Resources

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., (*28)

Once you have your resource class, simply add it to your mention config in one or more of your pools, such as:, (*29)

return [
    'pools' => [
        'users' => [
            ...
            'resource' => 'App\Resources\UserCollection',
            ...
        ]
    ]
];

Middleware

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., (*30)

return [
    'middleware' => [
        'your-middleware-here',
    ],
    //
];

The Versions