Craft CMS 5 plugin and module development — extending Craft with PHP. Covers the full extend surface: elements, element queries, services, models, records, project config, controllers, CP templates, migrations, queue jobs, console commands, field types, native fields, events, behaviors, Twig extensions, utilities, widgets, filesystems, permissions, debugging, testing, GraphQL, and Craft configuration (config/app.php, config/general.php, Redis, SMTP, database replicas). Triggers on: beforePrepare(), afterSave(), defineSources(), defineTableAttributes(), attributeHtml(), MemoizableArray, getConfig(), handleChanged, $allowAnonymous, $enableCsrfValidation, BaseNativeField, EVENT_DEFINE_NATIVE_FIELDS, FieldLayoutBehavior, EVENT_REGISTER, EVENT_DEFINE, EVENT_BEFORE, EVENT_AFTER, CraftVariable, registerTwigExtension, DefineConsoleActionsEvent, PHPStan, Pest, plugin development, module development, custom element type, custom field type, webhook, API endpoint, queue job, batch processing, data sync, migration, CP section, control panel, Craft plugin, Craft module, extending Craft, element action, element exporter, element condition, dashboard widget, utility page, permissions, registerUserPermissions, requirePermission, GraphQL custom types, GraphQL custom mutations, GraphQL schema building, Rector, Craft 4 to 5, upgrade plugin, CI/CD, GitHub Actions, GitLab CI, custom validator, defineRules, EVENT_AUTHORIZE_VIEW, EVENT_AUTHORIZE_SAVE, canView, canSave, canDelete, element authorization, defense-in-depth, query scoping, EVENT_BEFORE_PREPARE, session invalidation, passwordResetRequired, elevated session, Table::SESSIONS, custom field type build, field type development, normalizeValue, serializeValue, inputHtml, BaseCondition, ElementCondition, condition rule, condition builder, system messages, composeFromKey, email sending, Mailer, deployment, zero-downtime deploy, atomic deploy, craft up, project-config/apply, allowAdminChanges, drafts, revisions, provisional draft, canCreateDrafts, applyDraft, getIsDraft, getIsRevision, App::env, App::parseEnv, CRAFT_CP_TRIGGER, CRAFT_DEV_MODE, CRAFT_ALLOW_ADMIN_CHANGES, GeneralConfig, config precedence, cpTrigger, statusLabelHtml, Cp::statusLabelHtml, status pill, EVENT_DEFINE_ACTION_MENU_ITEMS, getActionMenuItems, disclosure menu, per-element action menu, EVENT_DEFINE_EDIT_SCREENS, DefineEditUserScreensEvent, UsersController, user edit screen, user edit tab. Always use when writing, editing, or reviewing any Craft CMS plugin or module PHP code — even when the user asks about plugin architecture, Craft internals, or extending Craft without naming specific APIs. Do NOT trigger for front-end Twig templates, content modeling decisions, site-building without PHP, or consuming GraphQL/headless APIs from front-end frameworks (Next.js, Nuxt, Astro) — those belong in craft-site.
npx claudepluginhub michtio/craftcms-claude-skills --plugin craftcms-claude-skillsThis skill uses the workspace's default tool permissions.
Reference for extending Craft CMS 5 through plugins and modules. Covers everything from elements and services to controllers, migrations, fields, and events.
references/architecture.mdreferences/caching.mdreferences/conditions.mdreferences/config-app.mdreferences/config-bootstrap.mdreferences/config-general-extended.mdreferences/config-general.mdreferences/console-commands.mdreferences/controllers.mdreferences/cp-components.mdreferences/cp-ui-patterns.mdreferences/cp.mdreferences/debugging.mdreferences/deployment.mdreferences/drafts-revisions.mdreferences/element-authorization.mdreferences/element-index.mdreferences/elements.mdreferences/email.mdreferences/events.mdCraft CMS 5 front-end Twig development — atomic design, template architecture, component patterns, Vite buildchain. Covers the full site template surface: atoms, molecules, organisms, props/extends/block pattern, layout chains, view routing, content builders, image presets, Tailwind named-key collections, multi-brand CSS tokens, JavaScript boundaries (Alpine/DataStar/Vue, tabs, accordions, interactive components), Vite asset loading, and front-end auth (login, registration, password reset, user profiles). Triggers on: {% include ... only %}, {% embed %}, _atoms/, _molecules/, _organisms/, _views/, _builders/, _boilerplate/, component--variant.twig, _component--props.twig, image presets, Tailwind class collections, collect({}), utilities prop, multi-brand theming, data-brand, hero sections, card components, content builders, Matrix block rendering, craft.vite.script, vite.php, vite.config.ts, nystudio107, buildchain, asset loading, per-page scripts, Blitz, static caching, page caching, dynamic caching with Sprig, ImageOptimize, Imager-X, responsive images, srcset, image transforms, SEOmatic, meta tags, OpenGraph, JSON-LD, Sprig, htmx, multi-language site, language switcher, hreflang, localization, Formie, form styling, login form, registration form, user authentication front-end, RSS feed, Atom feed, JSON Feed, XML sitemap, feed.xml, sitemap.xml, |rss, |atom, search page, search results, .search(), search index, search form, search configuration, headless, headless CMS, GraphQL queries, preview tokens, Next.js, Nuxt, Astro, consuming GraphQL API, front-end framework integration. Always use when creating, editing, or reviewing any Craft CMS front-end Twig template, component, layout, view, builder, buildchain configuration, or front-end auth flow — including plugin template integration (Blitz, SEOmatic, Sprig, Formie, Imager-X). Do NOT trigger for PHP plugin/module development or content modeling decisions.
Develops WordPress plugins with structure patterns, hooks, security (nonces, sanitization, prepared $wpdb queries), REST API, custom post types, and Settings API.
Supports complete WordPress development workflow: theme and plugin creation, WooCommerce integration, performance optimization, security hardening, and WP 7.0 features like Real-Time Collaboration, AI Connectors. Use for production sites.
Share bugs, ideas, or general feedback.
Reference for extending Craft CMS 5 through plugins and modules. Covers everything from elements and services to controllers, migrations, fields, and events.
This skill is scoped to extending Craft — building plugins, modules, custom element types, field types, and backend integrations. For site/platform development (content modeling, sections, entry types, Twig templating, plugin selection), see the craft-site skill.
When this skill triggers, also load:
craft-php-guidelines — PHPDoc standards, section headers, naming conventions, class organization, ECS/PHPStan, verification checklist. Required for any PHP code.ddev — All commands run through DDEV. Required for running ECS, PHPStan, scaffolding, and tests.craft-garnish — When working on CP JavaScript, asset bundles, or interactive CP components. Covers Garnish's class system, UI widgets (Modal, HUD, DisclosureMenu, Select), drag system, and the Craft.* JS class pattern.Use WebFetch on specific doc pages when a reference file doesn't cover enough detail.
addSelect() in beforePrepare() — it's the Craft convention and safely additive when multiple extensions contribute columns.->site('*') for cross-site queries.id in getConfig() — project config uses UIDs, never database IDs.DateTimeHelper in elements/queries, Carbon in services — never mix in the same class./admin in CP URLs — cpTrigger is configurable. Use UrlHelper::cpUrl() in PHP, cpUrl() in Twig.$request->getBodyParams() directly to savePluginSettings() on split-settings pages — only submitted keys persist, other settings are silently dropped. Load the full settings model first, update properties, then save.Read the relevant reference file(s) for your task. Multiple files often apply together.
Task examples:
elements.md + element-index.md + fields.md + migrations.md + cp.mdcontrollers.md + events.mdqueue-jobs.md + elements.md + debugging.mdcontrollers.md + cp.md + architecture.mdfields.md + events.mdquality.mdcp-components.md (Dashboard Widgets) + events.md (Widget Types section)events.md (Twig Extensions section)events.md (Behaviors section)cp-components.md (Utility Pages) + events.md (Utilities section)plugin-vite.md + load craft-garnish skillcraft-garnish skillfields.md + load craft-garnish skillgraphql.md + load craft-site skill for headless.mdcraft-site skill for headless.mdtesting.mdtesting.mdconfig-app.mdconfig-bootstrap.mdconfig-general.mdconfig-bootstrap.md + config-general.mdconfig-general.md + cp.md (Read-Only Mode)config-bootstrap.md (App::parseEnv)config-bootstrap.mdconfig-app.mdconfig-bootstrap.mdconfig-app.mdgraphql.md + config-general.mdcaching.mdpermissions.mdpermissions.mdarchitecture.md (Plugin Editions section)quality.md (Rector section)quality.md (CI/CD Integration section)migrations.md (Content Migrations section)config-app.md (Database Replicas section)config-app.md (Module Registration section)architecture.md (Custom Validators section)events.md (Filesystem Types section)cp-ui-patterns.md (Condition Builders)cp-ui-patterns.md (Tri-State Inheritance Controls)cp.md (Tabbed Settings Pages)cp-ui-patterns.md (Field Warning Parameter)cp-ui-patterns.md (Craft CSS Custom Properties)quality.md (Pre-Commit Hooks section)element-authorization.md + permissions.mdelement-authorization.md (Layer 3: Query Scoping)element-authorization.md + elements.mdelement-authorization.md (Defense Patterns)sessions-and-auth.md (Plugin Patterns)sessions-and-auth.mdsessions-and-auth.md (passwordResetRequired Gap)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.mdfield-types-custom.md (Relation Fields)conditions.md + element-index.mdconditions.mdemail.mdemail.md (Registering Custom System Messages)config-app.md + email.mddeployment.mddeployment.md (CI/CD Patterns)deployment.md (Zero-Downtime)deployment.md (Rollback Strategies)drafts-revisions.mddrafts-revisions.md (Creating Drafts)drafts-revisions.md (Plugin Considerations)elements.md (Generated Fields)element-index.md (Element Display Modes)elements.md (Extending User Edit Screens)cp.md (Read-Only Mode)Load only the reference files your task needs — each file costs input tokens on every turn.
| Task | Read | ~Tokens |
|---|---|---|
| Element core: lifecycle, queries, status, authorization, drafts, revisions, propagation, field layouts, user edit screens, events | references/elements.md | 8.4K |
| Element index: sources, table/card attributes, status pills, sort, conditions, actions (bulk + per-element action menu), exporters, sidebar, metadata, extending via events | references/element-index.md | 6.1K |
| Services, models, records, project config, MemoizableArray, events, API clients, custom validators | references/architecture.md | 6.0K |
| Controllers: CP CRUD, webhooks, API endpoints, action routing, authorization | references/controllers.md | 3.9K |
| CP templates, form macros, settings pages, navigation, permissions, read-only mode | references/cp.md | 7.2K |
| CP components: dashboard widgets, utility pages, slideout editors, ajax, alerts | references/cp-components.md | 1.8K |
| CP UI patterns: tri-state controls, status indicators, CSS variables, condition builders, asset bundles | references/cp-ui-patterns.md | 2.4K |
| Database migrations, Install.php, foreign keys, indexes, idempotency, deployment | references/migrations.md | 3.9K |
| Queue jobs, BaseJob, TTR, retry, progress, batch jobs, site context | references/queue-jobs.md | 4.2K |
| Console commands, arguments, options, progress bars, output helpers, resave actions | references/console-commands.md | 6.0K |
| Debugging, performance, query strategy, profiling, Xdebug, caching, logging | references/debugging.md | 4.6K |
| PHPStan, ECS, code review checklist | references/quality.md | 3.5K |
| Testing: Pest setup, element factories, HTTP/queue/DB assertions, mocking, multi-site, console, events | references/testing.md | 2.9K |
| Field types, native fields, BaseNativeField, field layout elements, FieldLayoutBehavior | references/fields.md | 3.6K |
| Events: registration, lifecycle, naming conventions, custom events, behaviors, Twig extensions, utilities, widgets, filesystems | references/events.md | 4.4K |
| GraphQL types, queries, mutations, directives, schema components, resolvers | references/graphql.md | 4.6K |
| Plugin Vite: VitePluginService, CP asset bundles, HMR, TypeScript, Vue in CP | references/plugin-vite.md | 2.7K |
| Headless & hybrid: headlessMode, GraphQL API, CORS, preview tokens, front-end frameworks | craft-site skill references/headless.md | 3.4K |
| GeneralConfig (system, routing, security, users, sessions, search, assets, images) | references/config-general.md | 8.4K |
| GeneralConfig (content, templates, performance, GC, localization, headless, GraphQL, accessibility) | references/config-general-extended.md | 7.2K |
| App config: cache, session, queue, mutex, mailer/SMTP, search, logging, CORS, DB replicas | references/config-app.md | 5.5K |
| Config bootstrap: env vars, aliases, priority order, fluent API, custom.php, db.php, routes.php | references/config-bootstrap.md | 3.6K |
| Caching: template cache tag, data cache, static caching (Blitz), CDN, layered strategy, invalidation | references/caching.md | 5.2K |
| Permissions: built-in handles, user groups, custom registration, Twig/PHP checking, authorization events | references/permissions.md | 4.7K |
| Element authorization: four-layer defense model, authorization events, can*() methods, query scoping | references/element-authorization.md | 4.6K |
| Sessions & auth internals: dual-layer session model, auth tokens, session invalidation, elevated sessions | references/sessions-and-auth.md | 3.0K |
| Custom field types: build pattern, value lifecycle, settings, input HTML, validation, search, GraphQL | references/field-types-custom.md | 3.5K |
| Conditions framework: BaseCondition, ElementCondition, custom condition rules, registering rules | references/conditions.md | 2.3K |
| Email system: system messages, custom messages, programmatic sending, templates, events, testing | references/email.md | 2.4K |
| Deployment: standard pipeline, project config deploy, zero-downtime, CI/CD, rollback | references/deployment.md | 2.5K |
| Drafts & revisions: draft types, provisional drafts, autosave, applying, merge, revisions | references/drafts-revisions.md | 2.5K |
Plugins and modules share the same architecture patterns. The differences are in bootstrapping and registration:
| Feature | Plugin | Module |
|---|---|---|
| CP template root | Automatic (by handle) | Manual via EVENT_REGISTER_CP_TEMPLATE_ROOTS |
| Site template root | Manual via event | Same — manual for both |
| Translation category | Automatic (by handle) | Manual PhpMessageSource in init() |
| Settings model | Built-in createSettingsModel() | Env vars, config files, or private plugin (_ prefix) |
| Install migration | migrations/Install.php | Content migrations only |
| Console commands | Automatic controllerNamespace | Must set before parent::init(), must be bootstrapped |
| CP nav section | $hasCpSection = true | EVENT_REGISTER_CP_NAV_ITEMS |
| Project config | Settings auto-tracked | Manual ProjectConfig::set() only |
| Namespace alias | Automatic via Composer | Must call 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
}
The module must be bootstrapped in config/app.php for console commands to be discoverable.