狼群ps-天空大师扩展插件

tech2022-08-30  116

狼群ps-天空大师扩展插件

Developers usually stick with a new CMS for its simplicity and extensibility. OctoberCMS presents itself as a back to basics CMS, and provides an enjoyable experience for both developers and users. In this article, I’m going to demonstrate some aspects of the CMS that make it extensible, and we’ll also try a simple plugin to extend another plugin functionality.

开发人员通常会坚持使用新的CMS,因为它具有简单性和可扩展性。 OctoberCMS表示自己是对CMS的回归,并为开发人员和用户提供了愉快的体验。 在本文中,我将演示使CMS具有可扩展性的某些方面,我们还将尝试使用一个简单的插件来扩展另一个插件功能。

介绍 (Introduction)

Every CMS has a plugin system for extending the platform’s functionality, and we measure the extensibility by how deep into the CMS’ inner workings we can go. However, we’re not only talking about the CMS here, we’re talking about plugins!

每个CMS都有一个用于扩展平台功能的插件系统,我们通过对CMS内部工作的深入程度来衡量可扩展性。 但是,我们不仅在这里谈论CMS,还在谈论插件!

If you build a plugin, you need to make sure that other developers can change bits of your functionality. For example, we have a blog plugin and the user can publish a post by selecting it on a list. It would be a good idea to fire an event saying that a new post has been published, and another developer may hook into this event and notify subscribed users via email about this!

如果您构建插件,则需要确保其他开发人员可以更改您的功能。 例如,我们有一个博客插件,用户可以通过在列表中选择帖子来发布帖子。 引发一个事件,说已经发布了一个新帖子,这是一个好主意,另一个开发人员可能会加入该事件并通过电子邮件通知订阅的用户!

class Posts extends Controller { public function index_onPublish() { if (($checkedIds = post('checked')) && is_array($checkedIds) && count($checkedIds)) { foreach ($checkedIds as $postId) { if ((!$post = Post::find($postId)) || !$post->canEdit($this->user)) continue; $post->publish(); Event::fire('rainlab.blog.posts.published', [$post]); } Flash::success('Successfully published those posts.'); } return $this->listRefresh(); } }

The other developer can listen for this event to do something with the published post.

其他开发人员可以侦听此事件以对已发布的帖子执行某些操作。

Event::listen('rainlab.blog.posts.published', function($post) { User::subscribedTo($post).each(function($user) use($post) { Mail::send('emails.notifications.post-published', ['user' => $user, 'post' => $post], function($message) use($user, $post) { $message->from('us@example.com', 'New post by ' . $user->name); $message->to($user->email); }); }); });

We will mainly use events to hook into different parts of the request cycle. Let’s start with a concrete example to clear things up.

我们将主要使用事件来挂钩请求周期的不同部分。 让我们从一个具体的例子开始,以解决问题。

Rainlab博客插件 (The Rainlab Blog Plugin)

If you’ve used OctoberCMS for a while, you must know the Rainlab Blog plugin. It lets you add posts and attach them to categories in the backend, and you can display them in the front-end using components.

如果您使用OctoberCMS已有一段时间,则必须了解Rainlab Blog插件。 它使您可以添加帖子并将其附加到后端的类别中,并且可以使用组件在前端显示它们。

On the posts listing page, we have the possibility to delete posts. But, what if we wanted to soft delete them? Let’s see if we can do that and learn more about OctoberCMS extensibility.

在帖子列表页面上,我们可以删除帖子。 但是,如果我们要软删除它们怎么办? 让我们看看是否可以这样做,并进一步了解OctoberCMS的可扩展性。

创建一个新插件 (Creating a New Plugin)

Go ahead and create a new plugin for our demo using the scaffolding helper command, and update the plugin details inside the Plugin.php file.

继续,使用scaffolding helper命令为我们的演示创建一个新插件,并更新Plugin.php文件中的插件详细信息。

php artisan create:plugin rafie.blogplus

扩展数据库架构 (Extending the Database Schema)

The first thing that comes to mind when talking about soft deletion is the deleted_at field column that need to be present in the DB.

在谈论软删除时,想到的第一件事是deleted_at中需要存在的deleted_at字段列。

Create a new file called create_posts_deleted_at_field.php under the blogplus/updates folder and update the version.yaml file.

在blogplus/updates文件夹下创建一个名为create_posts_deleted_at_field.php的新文件,并更新version.yaml文件。

// updates/version.yaml 1.0.1: - First version of blogplus. - create_posts_deleted_at_field.php // updates/create_posts_deleted_at_field.php class CreatePostsDeletedAtField extends Migration { public function up() { Schema::table('rainlab_blog_posts', function ($table) { $table->timestamp('deleted_at') ->default(null) ->nullable(); }); } public function down() { Schema::table('rainlab_blog_posts', function ($table) { $table->dropColumn('deleted_at'); }); } }

The migration class will alter the rainlab_blog_posts table and add our deleted_at column with a default null value. Don’t forget to run the php artisan plugin:refresh rafie.blogplus command for the changes to take effect.

迁移类将更改rainlab_blog_posts表,并添加具有默认null值的deleted_at列。 不要忘记运行php artisan plugin:refresh rafie.blogplus命令以使更改生效。

扩展帖子列表 (Extending Posts List)

Next, we have to add our field as a column to be displayed in the list. OctoberCMS provides an event for us to hook into, and alter the currently displayed widget (the backend list is considered a widget).

接下来,我们必须将字段添加为要在列表中显示的列。 OctoberCMS为我们提供了一个事件,供我们挂接和更改当前显示的窗口小部件(后端列表被视为窗口小部件)。

Event::listen('backend.list.extendColumns', function ($widget) { // Only for the Posts controller if (( ! $widget->getController() instanceof \Rainlab\Blog\Controllers\Posts)) { return; } $widget->addColumns([ 'deleted_at' => [ 'label' => 'Deleted', 'type' => 'date' ] ]); });

Note: The above code should be placed inside the Plugin@boot method.

注意 :上面的代码应放在Plugin@boot方法中。

We have an if statement to prevent our code from being executed on every page, then we add a new column to the list widget, and we can also remove any existing ones using the removeColumn method. Check the documentation for a list of available column options.

我们有一个if语句,以防止我们的代码在每个页面上执行,然后在列表小部件中添加新列,并且还可以使用removeColumn方法删除任何现有列。 查看文档以获取可用列选项的列表 。

扩展过滤器 (Extending the Filter)

The bar on top of the posts list lets the user filter the list using a date, category, etc. In our case, we need a filter to show/hide the trashed posts.

帖子列表顶部的栏使用户可以使用日期,类别等过滤列表。在我们的情况下,我们需要一个过滤器来显示/隐藏已删除的帖子。

// plugin.php Event::listen('backend.filter.extendScopes', function ($widget) { // Only for the Posts controller if (( ! $widget->getController() instanceof \Rainlab\Blog\Controllers\Posts)) { return; } $widget->addScopes([ 'Trashed' => [ 'label' => 'Hide trashed', 'type' => 'checkbox', 'scope' => 'trashed' ], ]); });

You can read more about the list filters in the documentation. The above code is fairly simple, and only contains a few options. However, the scope attribute should be the name of a query scope method defined inside the related (Models\Post) model instance.

您可以在文档中阅读有关列表过滤器的更多信息。 上面的代码非常简单,仅包含一些选项。 但是, scope属性应该是在相关( Models\Post )模型实例内部定义的查询范围方法的名称。

扩展类 (Extendable Classes)

The October\Rain\Extension\ExtendableTrait trait provides a magical way to dynamically extend an existing class by adding new methods, properties, behavior, etc. In our example we need to add a new method to the posts model to handle our scope filter.

October\Rain\Extension\ExtendableTrait特性提供了一种神奇的方法,可以通过添加新的方法,属性,行为等来动态扩展现有的类。在我们的示例中,我们需要向posts模型添加一个新方法来处理我们的范围过滤器。

// plugin.php \Rainlab\Blog\Models\Post::extend(function ($model) { $model->addDynamicMethod('scopeTrashed', function ($query) { return $query->where('deleted_at', '=', null); }); });

We can do the same with addDynamicProperty, asExtension, etc. Let’s refresh our posts list to see if our changes are working.

我们可以使用addDynamicProperty , asExtension等来做同样的addDynamicProperty 。让我们刷新帖子列表以查看更改是否有效。

Of course, we don’t have any trashed posts yet because we need to finish the last part: intercepting the deletion of the post and only updating the deleted_at column.

当然,我们还没有任何已删除的帖子,因为我们需要完成最后一部分:拦截帖子的删除,仅更新deleted_at列。

Tip: Instead of using the scope attribute, you can use conditions to specify a simple where condition. The code below gives the same result as using model scopes.

提示:您可以使用conditions来指定简单的where条件,而不是使用scope属性。 下面的代码提供与使用模型范围相同的结果。

$widget->addScopes([ 'Trashed' => [ 'label' => 'Hide trashed', 'type' => 'checkbox', 'conditions' => 'deleted_at IS NULL', ], ]);

口才事件 (Eloquent Events)

Eloquent fires a list of events on every action (create, update, delete, etc). In this case, we need to hook into the delete event and prevent the record’s deletion.

Eloquent会在每个动作(创建,更新,删除等)上触发事件列表 。 在这种情况下,我们需要加入delete事件并阻止记录的删除。

When deleting a record, the deleting event is fired before performing the actual delete action, and the deleted one is fired afterwards. If you return false on the deleting event, the action will abort.

当删除记录时, deleting事件执行实际删除操作之前发射,并deleted一个后来被解雇。 如果在deleting事件上返回false ,则操作将中止。

// plugin.php Event::listen('eloquent.deleting: RainLab\Blog\Models\Post', function ($record) { $record->deleted_at = Carbon::now(); $record->save(); return false; });

Now we are ready to test the final result! Go ahead and delete some records, and then go to the post listing page to see if you can toggle the trashed items in the list.

现在我们准备测试最终结果! 继续并删除一些记录,然后转到发布列表页面以查看是否可以切换列表中已删除的项目。

结论 (Conclusion)

This article was a quick overview of how you can extend different parts of the OctoberCMS platform. You can read more about this in the extending plugins section of the documentation. If you have any questions or comments, be sure to post them below!

本文简要概述了如何扩展OctoberCMS平台的不同部分。 您可以在文档的扩展插件部分中阅读有关此内容的更多信息。 如果您有任何疑问或意见,请务必在下面发布!

翻译自: https://www.sitepoint.com/extending-octobercms-building-a-soft-delete-plugin/

狼群ps-天空大师扩展插件

相关资源:天空CAD插件平台(软件安装后,会自动更新)
最新回复(0)