itbm/laravel-mentions

Laravel 5 & 6 的端到端提及功能。

1.5.0 2023-03-04 17:15 UTC

This package is auto-updated.

Last update: 2024-09-04 20:47:42 UTC


README

Build Status

弃用

遗憾的是,我没有足够的时间来充分维护这个包。我推荐 Xetaravel-Mentions,它似乎维护得更好,功能也相似。

事后看来,这个包试图做太多来实现这个功能。如果您想实现提及功能,我认为您最好手动实现前端,并将后端抽象为上述包或编写自己的API。

希望这能帮到您!

这个 Laravel >=5.4 包提供了一个简单的方法来为 Eloquent 模型设置提及功能。它提供了将提及插入到 content-editable 元素中的前端,将提及与模型关联的后端,以及优雅地通知被提及模型它们已被提及的方法。

以下是一些简短的示例,说明您可以做什么

// 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);

它还为您处理通知。如果您的提及配置启用了 auto_notify,它将为您处理。如果您需要自己处理逻辑,请禁用 auto_notify 并显式通知提及,例如

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

要求

安装

您可以使用以下命令通过 composer 安装此包

composer require jameslkingsley/laravel-mentions

如果您使用的是 Laravel 5.5 或更高版本,此包将自动发现,但是如果您使用的是低于 5.5 的版本,您需要以旧的方式注册它

接下来,您必须在 config/app.php 中安装服务提供者

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

现在发布迁移、前端资源和配置

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

迁移发布后,您可以通过运行迁移来创建提及表

php artisan migrate

以下是发布配置文件的内容

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

用法

首先,您需要导入 Tribute

npm install tributejs --save-dev

然后,在您的 bootstrap.js 文件中包含 Tribute,并将其全局分配。

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

现在,在您的 bootstrap.js 文件中,您可以导入 Mentions 类,并将其全局分配。

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

现在,要包含样式,只需将其导入到您的 SCSS 文件中。

@import "laravel-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>

接下来,添加初始化提及的脚本

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"
        }
    ]
});

现在转到后端。选择您想将提及分配到的模型。在这个例子中,我将选择 Comments。我们将导入特质并在类中使用它。

namespace App;

use Illuminate\Database\Eloquent\Model;
use Kingsley\Mentions\Traits\HasMentions;

class Comment extends Model
{
    use HasMentions;
}

接下来,切换到存储评论的控制器。在这种情况下,它是 CommentController。以任何您喜欢的方式创建评论,然后只需调用 mention 方法。

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

就这样!现在,当显示您的评论时,您可以通过样式化通过 Tribute 插入的 .mention-node 类来显示。相同的节点还有一个 data-object 属性,其中包含池名称和引用值,例如:users:1

使用提及编辑内容

您很可能会需要编辑文本内容,因此需要在表单中恢复提及列表。这很简单

<input
    type="hidden"
    name="mentions"
    id="mentions"
    value="{{ $comment->mentions()->encoded() }}"
/>

然后,在后端,您可以通过以下方式更新模型的提及

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

通知

如果您想使用通知,这里有一些您可能需要知道的事情。

  • 当提及被通知时,它将使用 Laravel 内置的通知特质来创建通知。这意味着在池配置中定义的模型类必须具有 Notifiable 特质。
  • 它将使用在池的配置中定义的通知类,因此您可以针对每个实例进行不同的处理。
  • 通知中存储的数据始终是执行提及的模型,例如 $comment->mention($user) 将在数据字段中存储 $comment
  • 通知类的 __construct 方法将执行提及的模型作为参数,例如 $comment->mention($user) 将在构造函数中获取 $comment

过滤器

您可能希望在模型检索记录时对模型应用一些自定义过滤器。为此,只需在您的应用程序中某个位置创建一个类,然后将它添加到提及配置中即可。

return [
    'pools' => [
        'users' => [
            ...
            'filter' => 'App\Filters\UserFilter',
            ...
        ]
    ]
];

您的过滤器类应该看起来像这样。它只有一个名为 handle 的静态方法,该方法接收查询作为参数,并且必须返回查询。

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

资源

如果您想更改 /api/mentions 路由返回的 JSON 响应,您可以创建自己的资源类。首先,前往 Laravel 文档 以创建和设置资源类。

拥有您的资源类后,只需将其添加到您的池的提及配置中,例如

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

中间件

如果您愿意,可以可选地将中间件添加到 /api/mentions 路由。如果想要在认证守卫后面保护路由,这将非常有用。前往 Laravel 文档 了解有关中间件的更多信息。

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