为十月 CMS 开发自定义插件
已发表: 2022-03-10去年,我对 PHP 中的新 CMS 系统进行了一些研究,以找到 WordPress 的良好替代品。 理想情况下,它必须是具有干净和现代代码库的开源解决方案。
其中一个引起了我的兴趣:十月 CMS。 我试过了,几乎立刻就喜欢上了。 代码结构非常好,编写自定义插件很容易。
本文旨在为您提供对该平台的期望的概述,并在您决定使用它之前让您体验一下。
为什么选择十月作为您的 CMS 平台?
我个人决定在我的项目中使用它有几个主要原因。
由 Laravel 提供支持
October 建立在用于创建现代 Web 应用程序的最强大的 PHP 框架之上:Laravel。 我可以很有信心地说这是最好的。 它非常易于使用和理解,并且具有现代框架所需的所有功能,从路由、对象关系映射 (ORM)、授权、缓存以及许多其他提供良好且清晰的 MVC 结构的功能。 由于由 Laravel 提供支持,October 继承了它的老大哥的所有这些功能。
干净的代码和文档
与许多其他 CMS 解决方案不同,October 有一个非常干净且记录良好的代码库。 它是使用面向对象的范例编写的。 October 使用 Twig 作为其模板引擎,而不是普通的旧 PHP,这为开发人员简化了工作。 技术文档也写得很好,可以帮助您快速找到大多数问题的答案。
大社区
尽管十月的社区还没有那么大,但它非常有帮助且反应迅速。 您可以加入一个公共 Slack 频道,在那里您会找到乐于帮助您解决问题的开发人员。
大市场
与 WordPress 和其他 CMS 一样,October 有一个主题和插件市场。 即使没有那么多好的主题可供选择,但现在有 700 多个插件,因此您很可能只需搜索并安装其中一个即可添加功能。 插件的一个重要功能是,如果您只需在管理仪表板中添加项目 ID,它们就可以在所有项目之间轻松同步。
插件和组件
插件是向十月添加新功能的基础。 一个插件可以由多个文件和目录组成,这些文件和目录负责注册自定义组件、模型、更新数据库结构或添加翻译。
插件通常在项目的plugins/目录中创建。 由于许多插件被提交到市场供其他人使用,每个插件都应该有一个自定义命名空间,通常以创建插件的公司或开发人员的名称开头。 因此,例如,如果您的名字是Acme ,并且您创建了一个名为 Blog 的很棒的插件,那么您的插件将位于Acme\Blog的命名空间下。
让我向您展示插件目录结构的外观:
如您所见,还有一个名为plugin.php的文件负责在十月 CMS 中注册插件及其所有组件。
另一件重要的事情是,并非上面列出的所有目录都是插件运行所必需的。 您的插件可以具有以下结构并且仍然可以正常工作:
大多数情况下,构建一个插件来仅添加一项功能。 例如,“翻译”插件旨在帮助您将网站上的内容翻译成不同的语言,并为用户提供多语言支持。
十月 CMS 有一个很棒的市场,您可以在其中找到您的需求。
与 WordPress 和其他流行的 CMS 不同,October 插件也可以有组件。 根据 10 月份的文档,组件是“可以附加到任何页面、部分或布局的可配置建筑元素”。 示例可能包括:联系表格、导航、常见问题解答列表及其答案; 基本上任何可以作为一个构建块捆绑在一起的有意义的东西,可以在多个页面上重复使用。
组件是作为插件的一部分创建的,它们存在于components/子目录中:
每个组件都有一个定义组件的 PHP 文件(如componentName.php ),以及组件部分的可选子目录。 组件部分文件夹必须与组件本身具有相同的小写名称。
为了演示组件的功能,我们假设我们的组件负责显示博客文章。
namespace Acme\Blog\Components; class BlogPosts extends \Cms\Classes\ComponentBase { public function componentDetails() { return [ 'name' => 'Blog Posts', 'description' => 'Displays a collection of blog posts.' ]; } // This array becomes available on the page as {{ component.posts }} public function posts() { return ['First Post', 'Second Post', 'Third Post']; } }
如我们所见,该组件有两个主要功能。 第一个, componentDetails()
,向将在其网页上添加和使用组件的管理员提供有关组件的信息。
第二个函数posts()
返回可以在组件部分( blogposts/default.htm文件)中使用的虚拟帖子,如下所示:
url = "/blog" [blogPosts] == {% for post in blogPosts.posts %} {{ post }} {% endfor %}
为了让十月 CMS 知道我们的组件存在,我们必须使用我们的主插件文件在名为registerComponents()
的函数中注册它:
public function registerComponents() { return [ 'October\Demo\Components\Todo' => 'demoTodo' ]; }
创建自定义联系表单插件
我们将创建一个自定义联系表单插件。 以下是关于插件应该如何工作的假设:
- 该表单将包含以下字段:名字、姓氏、电子邮件、消息。
- 数据将使用 Ajax 提交到服务器。
- 提交数据后,管理员将收到一封电子邮件,其中包含用户发送的消息。
出于本教程的目的,我们将使用十月 CMS 的全新安装:
让我们通过在终端中运行将生成插件结构的命令开始创建我们的插件: php artisan create:plugin progmatiq.contactform
progmatiq.contactform
参数包含作者姓名 (progmatiq) 和插件名称 (contactform)。
现在我们需要打开我们的plugin.php文件并通过以下方法修改插件详细信息:
public function pluginDetails() { return [ 'name' => 'Contact Form', 'description' => 'A simple contact form plug-in', 'author' => 'progmatiq', 'icon' => 'icon-leaf' ]; }
以下是您应该查看的其他一些方法:
-
registerComponents()
在这里,您可以定义插件提供的一组组件。 -
registerPermissions()
您可以注册自定义权限,以后可以在应用程序的其他区域使用这些权限。 -
registerNavigation()
您可以将带有 URL 的自定义菜单项添加到管理仪表板菜单。
现在让我们创建我们的ContactForm
组件:
- 在插件的根目录中创建一个名为components/的新文件夹。
- 在components/文件夹中创建一个名为contactForm.php的文件。
- 粘贴以下代码,告诉十月我们的组件做了什么。 我们可以通过在组件内部创建一个名为
componentDetails()
的方法来做到这一点。
<?php namespace Progmatiq\Contactform\Components; use Cms\Classes\ComponentBase; class ContactForm extends ComponentBase { public function componentDetails() { return [ 'name' => 'Contact Form', 'description' => 'A simple contact form' ]; } }
现在我们需要在插件中注册我们的组件。 为此,我们修改registerComponents()
方法:
public function registerComponents() { return [ 'Progmatiq\Contactform\Components\ContactForm' => 'contactForm', ]; }
此函数返回我们插件提供的组件数组。 组件的完整类名是此方法中的键,值是别名,我们将使用它来引用 Twig 模板中的组件。
一旦我们注册了组件,我们就可以创建一个新的联系页面并添加我们的组件(步骤中的数字参考截图):
- 在您的管理仪表板中,转到CMS (1) >页面(2),然后单击 +添加(3)。
- 为您的页面命名和 URL (4)。
- 命名您的文件 (5) 并选择默认布局 (6)。
让我们将新组件添加到页面中:
- 单击左侧菜单 (1) 中的组件,然后选择我们的“联系表”组件。 一旦你点击它 (2),它就会被添加到页面中。
- 我们需要放置一段代码,为页面提供标题,并使用
{% component 'contactForm' %}
Twig 指令呈现组件:
<div class="container"> <h1> Contact </h1> {% component 'contactForm' %} </div>
如果您现在打开您的联系页面,您将看到标题为“联系”,而没有其他内容。
那是因为我们的联系表单没有任何要呈现的 HTML。
我们需要在components/文件夹中创建一个contactform/default.htm文件。
并将以下 HTML 代码添加到文件中:
<form method="POST" data-request="onSend" data-request-validate data-request-success="this.reset(); alert('Thank you for submitting your inquiry')" > <div> <label for="first_name">First Name</label> <input type="text" name="first_name" class="form-control"> <p data-validate-for="first_name" class="text-danger"></p> </div> <div> <label for="last_name">Last Name</label> <input type="text" name="last_name" class="form-control"> <p data-validate-for="last_name" class="text-danger"></p> </div> <div> <label for="email">Email</label> <input type="text" name="email" class="form-control"> <p data-validate-for="email" class="text-danger"></p> </div> <div> <label for="content">Content</label> <textarea rows="6" cols="20" name="content" class="form-control"></textarea> <p data-validate-for="content" class="text-danger"></p> </div> <div> <button type="submit" class="btn btn-primary" data-attach-loading>Send</button> </div> </form>
大部分代码都非常简单。 但是,它带有特殊的 data-* 属性,October 允许我们使用:
-
<form>
标签具有三个特殊属性:-
data-request="onSend"
。 这个属性告诉October,当使用Ajax 提交表单时,必须调用来自我们组件(我们接下来要创建的)的onSend
函数。 - 如果表单无效,
data-request-validate
将使用从服务器发送的错误来启用表单 Ajax 验证。 -
data-request-success="this.reset(); alert('Thank you for submitting your inquiry')"
清除表单,然后在请求成功且不存在验证或服务器端错误时触发警报消息。
-
- 每个输入都有一个以下块,负责显示服务器为给定输入返回的验证错误:
- 提交按钮具有
data-attach-loading
属性,该属性将在服务器处理请求时添加一个微调器并禁用该按钮。 这样做是为了防止用户在前一个请求完成之前再次提交表单。
<p data-validate-for="content" class="text-danger"></p>
这是我们的页面现在的样子:
让我们回到我们的contactForm.php组件并创建onSend()
以及validate()
辅助方法来负责处理表单提交:
public function onSend() { // Get request data $data = \Input::only([ 'first_name', 'last_name', 'email', 'content' ]); // Validate request $this->validate($data); // Send email $receiver = '[email protected]'; \Mail::send('progmatiq.contact::contact', $data, function ($message) use ($receiver) { $message->to($receiver); }); } protected function validate(array $data) { // Validate request $rules = [ 'first_name' => 'required|min:3|max:255', 'last_name' => 'required|min:3|max:255', 'email' => 'required|email', 'content' => 'required', ]; $validator = \Validator::make($data, $rules); if ($validator->fails()) { throw new ValidationException($validator); } }
我们要做的第一件事是从请求中获取数据并使用validate()
辅助方法对其进行验证。 (您可以使用的所有可用验证规则都可以在文档中找到。)如果验证失败,则validate()
方法将抛出ValidationException
异常并且代码执行将停止,服务器将响应状态码406
和验证消息。
如果验证成功,那么我们将向我们的管理员发送一封电子邮件。
注意:为简单起见,我假设我们要将提交发送到的电子邮件是 [email protected]。 确保使用您自己的电子邮件!
这是您的contactForm.php插件的完整代码:
<?php namespace Progmatiq\Contactform\Components; use Cms\Classes\ComponentBase; use October\Rain\Exception\ValidationException; class ContactForm extends ComponentBase { public function componentDetails() { return [ 'name' => 'Contact Form', 'description' => 'A simple contact form' ]; } public function onSend() { // Get request data $data = \Input::only([ 'first_name', 'last_name', 'email', 'content' ]); // Validate request $this->validate($data); // Send email $receiver = '[email protected]'; \Mail::send('progmatiq.contact::contact', $data, function ($message) use ($receiver) { $message->to($receiver); }); } protected function validate(array $data) { // Validate request $rules = [ 'first_name' => 'required|min:3|max:255', 'last_name' => 'required|min:3|max:255', 'email' => 'required|email', 'content' => 'required', ]; $validator = \Validator::make($data, $rules); if ($validator->fails()) { throw new ValidationException($validator); } } }
如您所见, Mail::send()
函数接受的第一个参数是将要为电子邮件正文呈现的电子邮件模板的名称。 我们需要在管理面板中创建它。 转到设置 > 邮件模板,然后单击新建模板按钮。 然后填写表格,如下面的屏幕所示:
这是我们将要使用的电子邮件的正文:
You have received a new contact inquiry **First Name**: {{ first_name }} *** **Last Name**: {{ last_name }} *** **Email**: {{ email }} *** **Message**: {{ content }} ***
现在保存电子邮件模板。 我们需要做的下一件事是配置将发送电子邮件的 SMTP 服务器。
转到设置 > 邮件配置并填写所有设置。
显然,我不会分享我的个人配置。 使用您自己的设置。
在这个阶段,我们已经准备好开始测试我们的联系表单组件。
首先,让我们检查当我们将“内容”字段留空并输入无效电子邮件时验证是否有效:
验证按预期工作。 现在让我们输入正确的数据,看看电子邮件是否会成功发送给我们的管理员。
这是[email protected]将收到的电子邮件:
表单提交成功后,用户会看到一条警告信息,通知他操作成功:
结论
在本教程中,我们介绍了插件和组件是什么以及如何将它们与十月 CMS 一起使用。
如果您找不到适合您需求的现有插件,请不要害怕为您的项目创建自定义插件。 这并不难,您可以完全控制它,并且您可以随时更新或扩展它。 如果您想将它与 Mailchimp 或 HubSpot 等其他服务集成,即使像我们今天所做的那样创建一个简单的联系表单插件也会很有用。
我希望本教程对您有所帮助。 如果您有任何问题,请随时在下面的评论部分中提问。