沃通/laravel-mentions

Laravel 5, 6, 7 & 8 的端到端提及。

1.0.1 2020-11-21 10:16 UTC

This package is not auto-updated.

Last update: 2024-09-22 11:15:15 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 votong/laravel-mentions

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

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

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

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

php artisan vendor:publish --provider="VoTong\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 VoTong\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存储在数据字段中。
  • 通知类的构造方法接受进行提及的模型作为参数,例如$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',
    ],
    //
];