craftcms /guest-entries
此插件允许您从网站前端保存访客条目。
Requires
- craftcms/cms: ^4.0.0-RC3|^5.0.0-beta.1
Requires (Dev)
- craftcms/ecs: dev-main
- craftcms/phpstan: dev-main
- craftcms/rector: dev-main
README
允许访客从网站前端创建条目。
要求
Guest Entries 需要 Craft CMS 4.0.0+ 或 5.0.0+。
安装
您可以从 插件商店 或使用 Composer 安装 Guest Entries。
从插件商店
转到项目控制面板中的 插件商店(在允许 管理员更改的环境中),搜索“Guest Entries”,然后点击 安装。
使用 Composer
打开您的终端并运行以下命令
# Navigate to your project directory: cd /path/to/my-project # Require the plugin package with Composer: composer require craftcms/guest-entries -w # Install the plugin with Craft: php craft plugin/install guest-entries
设置
从插件设置页面,您可以配置……
- ……哪些部分允许访客提交条目;
- ……默认条目作者和状态;
- ……以及是否在接收之前验证提交。
用法
基本的访客条目模板应类似于以下内容
{# Macro to help output errors: #} {% macro errorList(errors) %} {% if errors %} {{ ul(errors, { class: 'errors' }) }} {% endif %} {% endmacro %} {# Default value for the `entry` variable: #} {% set entry = entry ?? null %} <form method="post" action="" accept-charset="UTF-8"> {# Hidden inputs required for the form to work: #} {{ csrfInput() }} {{ actionInput('guest-entries/save') }} {# Custom redirect URI: #} {{ redirectInput('success') }} {# Section for new entries: #} {{ hiddenInput('sectionHandle', 'mySectionHandle') }} {# Entry properties and custom fields: #} <label for="title">Title</label> {{ input('text', 'title', entry ? entry.title, { id: 'title' }) }} {{ entry ? _self.errorList(entry.getErrors('title')) }} <label for="body">Body</label> {{ tag('textarea', { text: entry ? entry.body, id: 'body', name: 'fields[body]', }) }} {{ entry ? _self.errorList(entry.getErrors('body')) }} {# ... #} <button type="submit">Publish</button> </form>
注意
提交数据和处理成功和错误状态的过程在 控制器操作 文档中概述。
支持的参数
以下参数可以与提交一起发送
表单提示
指定部分 + 条目类型
插件通过查找 sectionHandle
、sectionUid
或 sectionId
参数(按此顺序)来确定新条目所在的分区。另一方面,条目类型只能由 typeId
参数定义——但由于 ID 在不同环境中可能不稳定,您必须通过已知标识符来查找它们。
假设您已经有了分区(或者至少有一个分区 handle),通过分区模型来做这件事是最简单的方法
{% set targetSection = craft.app.sections.getSectionByHandle('resources') %} {% set entryTypes = targetSection.getEntryTypes() %} {# Select a single type, identified by its handle: #} {% set targetEntryType = collect(entryTypes).firstWhere('handle', 'document') %} {{ hiddenInput('sectionId', targetSection.id) }} {{ hiddenInput('typeId', targetEntryType.id) }}
发送自定义字段
自定义字段数据应嵌套在 fields
键下,字段名用 [方括号]
包围
<input type="text" name="fields[myCustomFieldHandle]" value="{{ entry ? entry.myCustomFieldHandle }}">
如果指定分区的条目默认启用,则将在 所有 自定义字段上进行验证,这意味着标记为 必填 的条目类型的字段布局必须随提交一起发送。有关 Craft 接受的值类型的详细信息,请参阅 字段类型 文档。
警告
从您的表单中省略字段并不意味着它是安全的!聪明的用户可能会修改请求有效负载并提交额外的字段数据。如果这对您的网站造成问题,请考虑使用 事件 来清除值或拒绝提交。
验证错误
如果在输入时存在验证错误,页面将重新加载,并在一个名为 entry
的变量下提供一个填充的 craft\elements\Entry
对象。您可以像访问正常条目一样访问该对象中的已发布值,或者使用 getErrors()
、getFirstError()
或 getFirstErrors()
显示错误。
注意
可以使用控制面板中的“条目变量名称” 设置 重命名entry
变量。如果您想在已经注入同名变量的条目页上使用表单,这可能是有必要的。
重定向
发送一个 redirect
参数,在成功保存条目后将用户发送到特定位置。在上面的例子中,这是通过 redirectInput('...')
函数 来处理的。路径被评估为一个 对象模板,并且可以包含 {curlyBraces}
中的保存条目的属性。
通过 Ajax 提交
如果您通过带有 Accept: application/json
头的 Ajax 提交表单 通过 Ajax,将返回一个包含以下键的 JSON 响应
success
(布尔值) – 条目是否成功保存errors
(对象) – 所有验证错误按字段名称索引(如果未保存)id
(字符串) – 条目的 ID(如果已保存)title
(字符串) – 条目的标题(如果已保存)authorUsername
(字符串) – 条目的作者的用户名(如果已保存)dateCreated
(字符串) – 条目的创建日期,格式为 ISO 8601(如果已保存)dateUpdated
(字符串) – 条目的更新日期,格式为 ISO 8601(如果已保存)postDate
(字符串,null) – 条目的发布日期,格式为 ISO 8601(如果已保存且已启用)url
(字符串,null) – 条目的公共 URL(如果已保存、已启用且在具有 URL 的部分中)
查看条目
使用 redirect
参数允许您显示用户刚刚提交的一些或全部内容——即使条目默认情况下是禁用的。
警告
在您的网站上显示不受信任的内容时请格外小心,尤其是在绕过审核流程时!
默认启用
具有 URL 的部分的条目可以立即查看,使用此 redirect
参数
{{ redirectInput('{url}') }}
默认禁用
为了显示一个 已禁用 的条目,您需要设置一个自定义 路由…
<?php return [ // This route uses the special `{uid}` token, which will // match any UUIDv4 generated by Craft: 'submissions/confirmation/<entryUid:{uid}>' => ['template' => '_submissions/confirmation'], ];
…并通过在条目表单中包含 {{ redirectInput('submissions/confirmation/{uid}') }}
将用户引导到它。您的模板(_submissions/confirmation.twig
)将负责根据 Craft 提供的 entryUid
路由令牌查找禁用条目并显示它
{% set preview = craft.entries() .status('disabled') .section('documents') .uid(entryUid) .one() %} {# Bail if it doesn’t exist: #} {% if not preview %} {% exit 404 %} {% endif %} {# Supposing the user’s name was recorded in the `title` field: #} <h1>Thanks, {{ preview.title }}!</h1> <p>Your submission has been recorded, and is awaiting moderation.</p>
此查询仅选择 disabled
条目,以便条目上线后“预览”无效。此“确认”URI 不需要 与条目的实际 URI 匹配。
事件
访客条目 通过添加一些自己的事件来增强条目生命周期中发射的正常 事件,允许开发人员自定义提交过程。
以下片段应添加到您插件或模块的 init()
方法中,按照官方的 事件使用说明。
beforeSaveEntry
事件
插件可以通过使用 beforeSaveEntry
事件在访客条目保存之前得到通知。这也是标记提交为垃圾邮件并阻止其保存的机会
use craft\helpers\StringHelper; use craft\guestentries\controllers\SaveController; use craft\guestentries\events\SaveEvent; use yii\base\Event; // ... Event::on( SaveController::class, SaveController::EVENT_BEFORE_SAVE_ENTRY, function(SaveEvent $e) { // Get a reference to the entry object: $entry = $e->entry; // Perform spam detection logic of your own design: if (StringHelper::contains($entry->title, 'synergy', false)) { // Set the event property: $e->isSpam = true; } } );
afterSaveEntry
事件
插件可以通过使用 afterSaveEntry
事件在访客条目保存之后得到通知
use craft\guestentries\controllers\SaveController; use craft\guestentries\events\SaveEvent; use yii\base\Event; // ... Event::on( SaveController::class, SaveController::EVENT_AFTER_SAVE_ENTRY, function(SaveEvent $e) { // Grab the entry $entry = $e->entry; // Was it flagged as spam? $isSpam = $e->isSpam; } );
afterError
事件
插件可以在提交被判定为无效后立即使用 afterError
事件得到通知
use craft\guestentries\controllers\SaveController; use craft\guestentries\events\SaveEvent; use yii\base\Event; // ... Event::on( SaveController::class, SaveController::EVENT_AFTER_ERROR, function(SaveEvent $e) { // Grab the entry $entry = $e->entry; // Get any validation errors $errors = $entry->getErrors(); } );