mcpField
C
craftcms

craftcms

github.com/michtio开发8687 次安装1 天前更新
代码仓库

关于 craftcms

craftcms 是面向开发者的参考技能,指导如何通过插件、模块、自定义元素和字段类型及后端集成扩展 Craft CMS 5。内容按任务组织,涵盖 Craft API 和常见实现陷阱。

主要功能

  1. 01插件与模块开发指导
  2. 02自定义元素和字段类型
  3. 03控制器、迁移与事件
  4. 04控制面板及后端集成
  5. 05按任务选择参考资料
  6. 06Craft 实现中的常见问题

适用场景

  1. 01构建自定义元素类型或字段类型
  2. 02添加 Webhook 端点或队列任务
  3. 03创建插件设置页或仪表板组件
  4. 04排查 Craft 配置与迁移行为

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/michtio/craftcms-claude-skills --skill craftcms

安装后在 Claude Code 中输入/craftcms确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
architecture.md
caching.md
conditions.md
config-app.md
config-bootstrap.md
config-general-extended.md
config-general.md
console-commands.md
controllers.md
cp-components.md
cp-ui-patterns.md
cp.md
debugging.md
deployment.md
drafts-revisions.md
element-authorization.md
element-index.md
elements.md
email.md
events.md
field-types-custom.md
fields.md
graphql.md
identity-protocols.md
migrations.md
permissions.md
plugin-vite.md
quality.md
queue-jobs.md
sessions-and-auth.md

详细介绍

Craft CMS 5 — 扩展(插件与模块)

通过插件和模块扩展 Craft CMS 5 的参考指南。涵盖从元素和服务到控制器、迁移、字段和事件的所有内容。

此技能适用于 Craft 的扩展,包括构建插件、模块、自定义元素类型、字段类型和后台集成。有关网站/平台开发(内容建模、区块、条目类型、Twig 模板、插件选择),请参阅 craft-site 技能。

配套技能 — 始终一并加载

触发此技能时,还需加载:

  • craft-php-guidelines — PHPDoc 标准、章节标题、命名约定、类组织、ECS/PHPStan 和验证清单。编写任何 PHP 代码时都必须加载。
  • ddev — 所有命令均通过 DDEV 运行。运行 ECS、PHPStan、脚手架和测试时都必须加载。
  • craft-garnish — 处理 CP JavaScript、资源包或交互式 CP 组件时加载。涵盖 Garnish 的类系统、UI 小部件(Modal、HUD、DisclosureMenu、Select)、拖动系统以及 Craft.* JS 类模式。
  • craft-pest — 编写、运行、修复或审查测试时加载。涵盖 markhuot/craft-pest-core 测试框架、数据库隔离(其回滚为选择启用,环境变量覆盖受当前工作目录限制——二者都会导致对开发数据库的写入悄无声息地发生)、工厂、HTTP/队列/数据库断言以及 CI 测试任务。
  • craft-cloud — 项目托管在 Craft Cloud 上时加载(通过仓库根目录的 craft-cloud.yaml 或 composer.json 中的 craftcms/cloud 检测)。处理插件的 Cloud 兼容性约束时必须加载,包括 App::isEphemeral() 守卫、资源包 CDN 发布、队列任务 15 分钟时限、使用 csrfInput() 函数而非直接输出令牌,以及 cloud/up 部署生命周期事件。

文档

参考文件未包含足够细节时,请对具体文档页面使用 WebFetch。

常见陷阱(跨领域)

  • 始终在 beforePrepare() 中使用 addSelect()——这是 Craft 的惯例;多个扩展共同添加列时,它也能安全地累加。
  • 队列工作进程在主站点上下文中运行——跨站点查询请使用 ->site('*')。
  • 在 getConfig() 中包含 id——项目配置使用 UID,从不使用数据库 ID。
  • 不要在模型或控制器中编写业务逻辑——逻辑应放在服务中。
  • 模块需要手动注册模板根目录、翻译和 controllerNamespace——没有任何内容会自动注册。
  • 在元素/查询中使用 DateTimeHelper,在服务中使用 Carbon——不要在同一个类中混用。
  • 不要在 CP URL 中硬编码 /admin——cpTrigger 可配置。PHP 中使用 UrlHelper::cpUrl(),Twig 中使用 cpUrl()。
  • 在拆分设置页面上,直接将 $request->getBodyParams() 传给 savePluginSettings()——只有已提交的键会被保存,其他设置会悄无声息地丢失。请先加载完整的设置模型,更新属性,然后保存。
  • 将路由或查询参数命名为 token——这会与 Craft 保留的 tokenParam 冲突,请求会在控制器运行前被拒绝并返回 400。请参阅 controllers.md(保留的请求参数)。
  • 插件 templates/ 目录中任何未以下划线开头的模板都可直接通过 CP 路由访问,绕过控制器的 beforeAction() 限制。除非模板有意作为直接路由,否则都应以下划线开头。请参阅 cp.md(CP 模板路由会绕过控制器)。

参考文件

根据任务阅读相关参考文件。通常需要同时参考多个文件。 任务示例:

  • “构建自定义元素类型” → 阅读 elements.md(先看 Architecture 部分)+ element-index.md + fields.md + migrations.md + cp.md
  • “构建分层/树状元素类型” → 阅读 elements.md(Architecture:One Element Class with Native Structure)
  • “添加 webhook 端点” → 阅读 controllers.md + events.md
  • “创建一个用于同步元素的队列任务” → 阅读 queue-jobs.md + elements.md + debugging.md
  • “添加带表单字段的设置页面” → 阅读 controllers.md + cp.md + architecture.md
  • “注册自定义字段类型” → 阅读 fields.md + events.md
  • “修复 PHPStan 错误” → 阅读 quality.md
  • “添加仪表板小组件” → 阅读 cp-components.md(Dashboard Widgets)+ events.md(Widget Types 部分)
  • “为插件用户公开模板变量” → 阅读 events.md(Twig Extensions 部分)
  • “为条目附加自定义方法” → 阅读 events.md(Behaviors 部分)
  • “注册自定义元素或字段类型” → 阅读 events.md(Registration Pattern → Registration scope — never gate by request context)
  • “已删除的自定义元素永远不会被删除/垃圾回收未清理/elements 表中的行不断堆积” → 阅读 events.md(Registration Pattern → Registration scope)
  • “构建 CP 工具页面” → 阅读 cp-components.md(Utility Pages)+ events.md(Utilities 部分)
  • “为插件的 CP 资源配置 Vite” → 阅读 plugin-vite.md + 加载 craft-garnish skill
  • “为 CP 页面添加拖动排序或交互式 JS” → 加载 craft-garnish skill
  • “为自定义字段类型编写 CP JavaScript” → 阅读 fields.md + 加载 craft-garnish skill
  • “构建无头 Craft API” → 阅读 graphql.md + 加载 craft-site skill 以查阅 headless.md
  • “为 Next.js 前端配置预览” → 加载 craft-site skill 以查阅 headless.md
  • “为插件设置 Pest 测试” → 加载 craft-pest skill → isolation.md
  • “为控制器操作编写测试” → 加载 craft-pest skill → patterns.md
  • “测试正在写入我的开发数据库/创建了数千个多余元素” → 加载 craft-pest skill → isolation.md
  • “通过代码创建或删除站点(导入器、配置命令、fixture)” → 阅读 architecture.md(Creating or deleting sites at runtime)
  • “创建站点后,元素查询不再按 siteId 筛选” → 阅读 architecture.md(Creating or deleting sites at runtime — refreshSites() 不会使读取变体查询失效)
  • “删除站点后,分区/类别组仍引用该站点” → 阅读 architecture.md(Creating or deleting sites at runtime — deleteSite() 的清理与记忆化服务缓存)
  • “将记录的 dateUpdated 与截止时间比较/‘自某时起更改’筛选相差数小时” → 阅读 architecture.md(Those strings are naive UTC)
  • “将 ActiveRecord 中的 datetime 列读入模型” → 阅读 architecture.md(Record-to-Model Hydration Boundary)
  • “我的元素查询使用 ['like', ...] 后没有返回任何结果” → 阅读 architecture.md(Element-query param setters don't take Yii operator tuples)
  • “按标题/slug 前缀匹配元素” → 阅读 architecture.md(Element-query param setters don't take Yii operator tuples)
  • “配置 Redis 用于缓存和会话” → 阅读 config-app.md
  • “将 PHP 会话存储在数据库中(负载均衡器、没有 Redis)” → 阅读 config-app.md(Session Component — craft\web\DbSession、setup/php-session-table)
  • “为生产环境设置环境变量” → 阅读 config-bootstrap.md
  • “查找 GeneralConfig 设置” → 阅读 config-general.md
  • “在插件代码中读取配置值(App::env、parseEnv、GeneralConfig)” → 阅读 config-bootstrap.md + config-general.md
  • “在插件代码中检查 allowAdminChanges 是否已启用” → 阅读 config-general.md + cp.md(Read-Only Mode)
  • “在插件设置中解析环境变量($MY_API_KEY)” → 阅读 config-bootstrap.md(App::parseEnv)
  • “了解 CRAFT_* 环境变量约定” → 阅读 config-bootstrap.md
  • “配置邮件传输/SMTP” → 阅读 config-app.md
  • “设置自定义 URL 路由” → 阅读 config-bootstrap.md
  • “配置搜索以查找较短的单词” → 阅读 config-app.md
  • “设置 GraphQL 令牌和架构” → 阅读 graphql.md + config-general.md
  • “升级到 Craft 5.11 后,GraphQL 的 author/uploader 字段消失了” → 阅读 graphql.md(Craft 5.11 Additions — “Query for users” 范围)
  • “为高流量网站设置缓存” → 阅读 caching.md
  • “为我的插件注册自定义权限” → 阅读 permissions.md
  • “在模板中检查用户权限” → 阅读 permissions.md
  • “设置插件版本/功能门控” → 阅读 architecture.md(Plugin Editions 部分)
  • “构建流式渲染构建器/craft.plugin.widget().render()” → 阅读 architecture.md(Render builders:属性合并、选项允许列表)
  • “网站无法覆盖插件的前端 CSS/插件样式优先生效” → 阅读 architecture.md(插件注册的 CSS 在网站样式表之后加载)
  • “插件 JS 在随附模板中有效,在用户编写的模板中却无效” → 阅读 architecture.md(JS 与标记的契约是公共 API)
  • “从注册表/生成器输出生成文档/架构/类型,但不同安装或版本的输出不一致” → 阅读 quality.md(Generated Artifacts Must Not Read Runtime Registries)
  • “发布版本/打标签/Packagist 未提供新版本” → 加载 craft-plugin-release skill
  • “删除站点后,插件中按站点存储的行仍然存在” → 阅读 architecture.md(Site deletion is a soft delete)
  • “缓存了 false/缓存返回 false,我无法判断是否未命中” → 阅读 caching.md(Data Caching → boolean sentinel idiom)
  • “插件/运维设置(阈值、通知路由、工作流映射)应放在哪里——项目配置还是数据库?” → 阅读 architecture.md(Settings belong in project config)
  • “阈值是否应该只存在数据库中,以避免跨环境变更?” → 阅读 architecture.md(Settings belong in project config)——这是一个需要纠正的误解
  • “将插件从 Craft 4 升级到 5” → 阅读 quality.md(Rector 部分)
  • “为 Craft 插件设置 CI” → 阅读 quality.md(CI/CD Integration 部分)
  • “在迁移中创建分区或字段” → 阅读 migrations.md(Content Migrations 部分)
  • “安装失败并提示 ‘Too many keys specified; max 64 keys allowed’/重复索引不断堆积” → 阅读 migrations.md(可重复运行的索引创建与 MySQL 的 64 个键上限)
  • “运行模块的迁移/--track=module: 被拒绝/库中提供的模块架构从未应用” → 阅读 migrations.md(模块和库中提供的模块没有 CLI 跟踪标记)
  • “修复插件升级后错误存储的项目配置值” → 阅读 migrations.md(不要在迁移中调用 ProjectConfig::flush())
  • “以编程方式解除用户停用/恢复用户/解除停用后用户仍无法登录” → 阅读 elements.md(getStatus() 会隐藏并存的状态)
  • “我需要重写 settingsAttributes() 吗?” → 阅读 field-types-custom.md(settingsAttributes() 实际包含的内容)
  • “设置数据库只读副本” → 阅读 config-app.md(Database Replicas 部分)
  • “在 app.php 中注册模块” → 阅读 config-app.md(Module Registration 部分)
  • “创建自定义验证器” → 阅读 architecture.md(Custom Validators 部分)
  • “创建自定义文件系统类型” → 阅读 events.md(Filesystem Types 部分)
  • “为元素索引构建自定义条件规则” → 阅读 cp-ui-patterns.md(Condition Builders)
  • “构建三态/继承/关闭控件” → 阅读 cp-ui-patterns.md(Tri-State Inheritance Controls)
  • “为插件添加带标签页的设置页面” → 阅读 cp.md(Tabbed Settings Pages)
  • “插件支持 config/.php 覆盖——设置页面应如何显示?” → 阅读 cp.md(Settings Pages → Config-file overrides: warn on the field, don't disable it)
  • “设置已保存,但没有任何变化/配置文件悄悄覆盖了设置” → 阅读 cp.md(Settings Pages → Config-file overrides)
  • “为什么我的 URL 标签页无法导航/标签页与独立页面的侧边栏导航该如何选择?” → 阅读 cp.md(Tabs switch panes — they never navigate)
  • “构建 CP 索引/列表屏幕:列、复制小标签、行操作” → 阅读 cp-ui-patterns.md(Index-screen column scheme)+ cp-components.md(VueAdminTable)
  • “VueAdminTable 裁切标题/介绍文字和 New 按钮该放在哪里?” → 阅读 cp-components.md(VueAdminTable → sole pane content)
  • “工具图标不显示/icon() 路径” → 阅读 cp-components.md(Utility Pages)
  • “在布局元素上隐藏可见性/可编辑性条件构建器” → 阅读 fields.md(Suppressing the condition builders)
  • “在字段上显示‘覆盖全局设置’警告” → 阅读 cp-ui-patterns.md(Field Warning Parameter)
  • “Craft CP 使用哪些 CSS 变量/设计令牌?” → 阅读 cp-ui-patterns.md(Craft CSS Custom Properties — 颜色/状态/间距/圆角/控件/焦点/字体令牌)
  • “布尔设置应使用 Lightswitch 还是复选框?” → 阅读 cp.md(Form Macros Reference → Lightswitch vs checkbox)
  • “渲染复制文本/API 密钥/webhook URL 字段” → 阅读 cp.md(Form Macros Reference → copytextField)
  • “Save/Delete/Add 按钮应使用哪个按钮类?” → 阅读 cp.md(Form Macros Reference → Button modifier classes)
  • “向 CP 面板添加内部侧边栏子导航” → 阅读 cp.md(Form Macros Reference → Inner sidebar navigation)
  • “向设置页面添加可内联编辑的表格” → 阅读 cp-components.md(Editable Table Field)
  • “在 CP 中显示模态框或确认对话框(Craft.confirm() 并不存在)” → 阅读 cp-components.md(Modals)+ 加载 craft-garnish skill 以实现行为
  • “关系字段有哪些视图模式/previewMode/maxRelations?” → 阅读 element-index.md(Relation Field Display/Props)
  • “向字段布局添加 Tip/Heading/内置 UI 元素” → 阅读 fields.md(Field-Layout UI Elements Reference)
  • “向元素编辑屏幕的侧边栏添加面板” → 阅读 cp-ui-patterns.md(Element Edit Screen)+ elements.md(EVENT_DEFINE_SIDEBAR_HTML)
  • “向元素顶部工具栏添加拆分按钮” → 阅读 cp-ui-patterns.md(Element Edit Screen → toolbar split button)+ elements.md(EVENT_DEFINE_ADDITIONAL_BUTTONS)
  • “为什么我的侧边栏面板渲染后没有样式/显示异常?” → 阅读 cp-ui-patterns.md(Element Edit Screen → .meta 与 .meta read-only)
  • “在自定义元素上重写 metaFieldsHtml()” → 阅读 cp-ui-patterns.md(Element Edit Screen → metaFieldsHtml override)
  • “设置代码质量的提交前钩子” → 阅读 quality.md(Pre-Commit Hooks 部分)
  • “按用户组限制元素访问” → 阅读 element-authorization.md + permissions.md
  • “按权限限定 CP 元素索引” → 阅读 element-authorization.md(Layer 3: Query Scoping)
  • “为自定义元素添加授权事件” → 阅读 element-authorization.md + elements.md
  • “为安全插件构建纵深防御” → 阅读 element-authorization.md(Defense Patterns)
  • “在所有设备上强制用户登出” → 阅读 sessions-and-auth.md(Plugin Patterns)
  • “了解 Craft 会话的工作方式” → 阅读 sessions-and-auth.md
  • “实现必须重置密码的功能” → 阅读 sessions-and-auth.md(passwordResetRequired Gap)
  • “向 Users 元素索引添加一列” → 阅读 element-index.md(Extending Element Indexes via Events)
  • “向元素索引添加批量操作” → 阅读 element-index.md(Adding a custom bulk action)
  • “向每个元素编辑屏幕的菜单添加操作” → 阅读 element-index.md(Per-Element Edit-Screen Action Menu)
  • “在表格列中渲染状态标签” → 阅读 element-index.md(Status Pills in Table Attributes)
  • “向元素索引添加自定义侧边栏来源” → 阅读 element-index.md(Adding a sidebar source)
  • “构建自定义字段类型” → 阅读 field-types-custom.md + fields.md
  • “构建关系字段类型” → 阅读 field-types-custom.md(Relation Fields)
  • “向条目索引添加条件规则” → 阅读 conditions.md + element-index.md
  • “构建自定义条件规则” → 阅读 conditions.md
  • “从插件发送电子邮件” → 阅读 email.md
  • “注册自定义系统消息” → 阅读 email.md(Registering Custom System Messages)
  • “配置 SMTP 传输” → 阅读 config-app.md + email.md
  • “将 Craft CMS 部署到生产环境” → 阅读 deployment.md
  • “为 Craft 项目设置 CI/CD” → 阅读 deployment.md(CI/CD Patterns)
  • “零停机部署” → 阅读 deployment.md(Zero-Downtime)
  • “回滚失败的部署” → 阅读 deployment.md(Rollback Strategies)
  • “使用草稿和修订版本” → 阅读 drafts-revisions.md
  • “以编程方式创建草稿” → 阅读 drafts-revisions.md(Creating Drafts)
  • “在 afterSave 中跳过草稿的副作用” → 阅读 drafts-revisions.md(Plugin Considerations)
  • “向自定义元素添加生成字段” → 阅读 elements.md(Generated Fields)
  • “自定义元素显示为小标签或卡片时的外观” → 阅读 element-index.md(Element Display Modes)
  • “向用户编辑页面添加屏幕” → 阅读 elements.md(Extending User Edit Screens)
  • “当 allowAdminChanges 关闭时,将插件设置设为只读” → 阅读 cp.md(Read-Only Mode)
  • “向插件的设置页面添加标签页” → 阅读 cp.md(Settings Pages → With tabs or custom actions)。settingsHtml() 仅支持单面板——标签页需要自定义控制器和直接扩展 _layouts/cp 的模板。
  • “在插件自己的 CP 分区中渲染插件设置(而非全局设置/插件页面)” → 阅读 cp.md(Settings Pages → Keep settings inside the plugin's own CP section)
  • “让插件兼容 Cloud” → 加载 craft-cloud skill → plugin-development.md(临时文件系统、资源包限制、队列上限、CSRF 函数、无 Cookie 设计)
  • “将 Craft 项目部署到 Cloud” → 加载 craft-cloud skill → config-file.md + deploy-pipeline.md + extension.md
  • “将可自托管的 Craft 站点迁移到 Cloud” → 加载 craft-cloud skill → migration.md
  • “为什么插件在 Cloud 上写入文件时会无提示地失败?” → 加载 craft-cloud skill → plugin-development.md(临时文件系统)+ extension.md(App::isEphemeral)
  • “构建 SSO/OIDC 登录或 SCIM 配置功能” → 阅读 identity-protocols.md + sessions-and-auth.md
  • “处理单点登出/logout_token/由提供方发起的取消配置” → 阅读 identity-protocols.md 仅加载任务所需的参考文件——每个文件都会在每轮消耗输入令牌。 | 任务 | 阅读 | ~词元 | |------|------|--------:| | 元素核心:生命周期、查询、状态、授权、草稿、修订、传播、字段布局、用户编辑界面、事件 | references/elements.md | 8.4K | | 元素索引:来源、表格/卡片属性、状态标签、排序、条件、操作(批量操作和单元素操作菜单)、导出器、侧边栏、元数据、关系字段显示/属性(viewMode、previewMode、maxRelations)、通过事件扩展 | references/element-index.md | 6.1K | | 服务、模型、记录、项目配置(包括运行时站点创建/删除缓存)、MemoizableArray、事件、API 客户端、自定义验证器 | references/architecture.md | 7.4K | | 控制器:控制面板 CRUD、Webhook、API 端点、操作路由、授权 | references/controllers.md | 3.9K | | 控制面板模板、表单宏(包括 lightswitch 与 checkbox、copytext、money、按钮类)、设置页面、导航(包括内侧边栏导航)、权限、只读模式 | references/cp.md | 7.2K | | 控制面板组件:仪表板小组件、工具页面、滑出式编辑器、Ajax、可编辑表格、加载指示器、模态框(标记和遮罩)、警报 | references/cp-components.md | 1.8K | | 控制面板 UI 模式:三态控件、状态指示器、语义化 CSS 令牌(颜色/状态/间距/圆角/控件/焦点/字体)、条件构建器、资源包、元素编辑界面侧边栏面板和工具栏拆分按钮 | references/cp-ui-patterns.md | 3.4K | | 数据库迁移、Install.php、外键、索引、幂等性、部署 | references/migrations.md | 3.9K | | 队列作业、BaseJob、TTR、重试、进度、批量作业、站点上下文 | references/queue-jobs.md | 4.2K | | 控制台命令、参数、选项、进度条、输出辅助工具、重新保存操作 | references/console-commands.md | 6.0K | | 调试、性能、查询策略、性能分析、Xdebug、缓存、日志记录 | references/debugging.md | 4.6K | | PHPStan、ECS、代码审查清单 | references/quality.md | 3.5K | | 测试:指向 craft-pest 技能(Pest/craft-pest-core 在其中)+ Codeception 基础知识 | references/testing.md | 0.6K | | 字段类型、原生字段、BaseNativeField、字段布局元素(内置 Tip/Heading/LineBreak/HorizontalRule 参考)、FieldLayoutBehavior | references/fields.md | 3.6K | | 事件:注册、生命周期、命名约定、自定义事件、行为、Twig 扩展、实用工具、小组件、文件系统 | references/events.md | 4.4K | | GraphQL 类型、查询、变更、指令、架构组件、解析器 | references/graphql.md | 4.6K | | 插件 Vite:VitePluginService、控制面板资源包、HMR、TypeScript、控制面板中的 Vue | references/plugin-vite.md | 2.7K | | 无头与混合模式:headlessMode、GraphQL API、CORS、预览令牌、前端框架 | craft-site 技能 references/headless.md | 3.4K | | GeneralConfig(系统、路由、安全、用户、会话、搜索、资源、图像) | references/config-general.md | 8.4K | | GeneralConfig(内容、模板、性能、垃圾回收、本地化、无头模式、GraphQL、无障碍) | references/config-general-extended.md | 7.2K | | 应用配置:缓存、会话、队列、互斥锁、邮件程序/SMTP、搜索、日志记录、CORS、数据库副本 | references/config-app.md | 5.5K | | 配置引导:环境变量、别名、优先级顺序、流式 API、custom.php、db.php、routes.php | references/config-bootstrap.md | 3.6K | | 缓存:模板缓存标签、数据缓存、静态缓存(Blitz)、CDN、分层策略、失效处理 | references/caching.md | 5.2K | | 权限:内置句柄、用户组、自定义注册、Twig/PHP 检查、授权事件 | references/permissions.md | 4.7K | | 元素授权:四层防御模型、授权事件、can*() 方法、查询范围限定 | references/element-authorization.md | 4.6K | | 会话与身份验证内部机制:双层会话模型、身份验证令牌、会话失效、提升权限的会话 | references/sessions-and-auth.md | 3.0K | | SSO/预配插件的身份协议:反向通道与正向通道注销、签名算法允许列表、issuer 与租户(hd 声明)、SCIM active:false 与 PATCH 顺序、厂商与 RFC 的差异 | references/identity-protocols.md | 1.3K | | 自定义字段类型:构建模式、值生命周期、设置、输入 HTML、验证、搜索、GraphQL | references/field-types-custom.md | 3.5K | | 条件框架:BaseCondition、ElementCondition、自定义条件规则、注册规则 | references/conditions.md | 2.3K | | 电子邮件系统:系统消息、自定义消息、以编程方式发送、模板、事件、测试 | references/email.md | 2.4K | | 部署:标准流水线、项目配置部署、零停机、CI/CD、回滚 | references/deployment.md | 2.5K | | 草稿与修订:草稿类型、临时草稿、自动保存、应用、合并、修订 | references/drafts-revisions.md | 2.5K |

插件与模块的区别

插件和模块采用相同的架构模式。两者在引导和注册方面有所不同:

功能插件模块
CP 模板根目录自动注册(按句柄)通过 EVENT_REGISTER_CP_TEMPLATE_ROOTS 手动注册
站点模板根目录通过事件手动注册相同——两者都需手动注册
翻译类别自动注册(按句柄)在 init() 中手动注册 PhpMessageSource
设置模型内置 createSettingsModel()环境变量、配置文件或私有插件(_ 前缀)
安装迁移migrations/Install.php仅限内容迁移
控制台命令自动注册 controllerNamespace必须在 parent::init() 前设置,并且必须引导
CP 导航区域$hasCpSection = trueEVENT_REGISTER_CP_NAV_ITEMS
项目配置设置会自动跟踪仅手动调用 ProjectConfig::set()
命名空间别名通过 Composer 自动设置必须调用 Craft::setAlias()
模块模板根目录注册
use craft\events\RegisterTemplateRootsEvent;
use craft\web\View;

Event::on(View::class, View::EVENT_REGISTER_CP_TEMPLATE_ROOTS,
    function(RegisterTemplateRootsEvent $event) {
        $event->roots['my-module'] = __DIR__ . '/templates';
    }
);
模块翻译注册
Craft::$app->i18n->translations['my-module'] = [
    'class' => \craft\i18n\PhpMessageSource::class,
    'sourceLanguage' => 'en',
    'basePath' => __DIR__ . '/translations',
    'allowOverrides' => true,
];
模块控制台命令注册
public function init()
{
    Craft::setAlias('@mymodule', __DIR__);

    if (Craft::$app->getRequest()->getIsConsoleRequest()) {
        $this->controllerNamespace = 'modules\\mymodule\\console\\controllers';
    } else {
        $this->controllerNamespace = 'modules\\mymodule\\controllers';
    }

    parent::init(); // MUST come after setting controllerNamespace
}

必须在 config/app.php 中引导模块,才能发现其控制台命令。

评论

支持 Markdown