Skillquality 0.47

craftcms

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, beh

Price
free
Protocol
skill
Verified
no

What it does

Craft CMS 5 — Extending (Plugins & Modules)

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.

Companion Skills — Always Load Together

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.

Documentation

Use WebFetch on specific doc pages when a reference file doesn't cover enough detail.

Common Pitfalls (Cross-Cutting)

  • Always use addSelect() in beforePrepare() — it's the Craft convention and safely additive when multiple extensions contribute columns.
  • Queue workers run in primary site context — use ->site('*') for cross-site queries.
  • Including id in getConfig() — project config uses UIDs, never database IDs.
  • Business logic in models or controllers — services are where logic belongs.
  • Modules need manual template root, translation, and controllerNamespace registration — nothing is automatic.
  • DateTimeHelper in elements/queries, Carbon in services — never mix in the same class.
  • Hardcoding /admin in CP URLs — cpTrigger is configurable. Use UrlHelper::cpUrl() in PHP, cpUrl() in Twig.
  • Passing $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.

Reference Files

Read the relevant reference file(s) for your task. Multiple files often apply together.

Task examples:

  • "Build a custom element type" → read elements.md + element-index.md + fields.md + migrations.md + cp.md
  • "Add a webhook endpoint" → read controllers.md + events.md
  • "Create a queue job that syncs elements" → read queue-jobs.md + elements.md + debugging.md
  • "Add a settings page with form fields" → read controllers.md + cp.md + architecture.md
  • "Register a custom field type" → read fields.md + events.md
  • "Fix PHPStan errors" → read quality.md
  • "Add a dashboard widget" → read cp.md (Dashboard Widgets) + events.md (Widget Types section)
  • "Expose template variables for plugin users" → read events.md (Twig Extensions section)
  • "Attach custom methods to entries" → read events.md (Behaviors section)
  • "Build a CP utility page" → read events.md (Utilities section) + cp.md
  • "Set up Vite for a plugin's CP assets" → read plugin-vite.md + load craft-garnish skill
  • "Add drag-to-reorder or interactive JS to a CP page" → load craft-garnish skill
  • "Write CP JavaScript for a custom field type" → read fields.md + load craft-garnish skill
  • "Build a headless Craft API" → read graphql.md + load craft-site skill for headless.md
  • "Configure preview for a Next.js front-end" → load craft-site skill for headless.md
  • "Set up Pest tests for a plugin" → read testing.md
  • "Write a test for a controller action" → read testing.md
  • "Configure Redis for caching and sessions" → read config-app.md
  • "Set up environment variables for production" → read config-bootstrap.md
  • "Find a GeneralConfig setting" → read config-general.md
  • "Read a config value in plugin code (App::env, parseEnv, GeneralConfig)" → read config-bootstrap.md + config-general.md
  • "Check if allowAdminChanges is enabled in plugin code" → read config-general.md + cp.md (Read-Only Mode)
  • "Resolve env vars in plugin settings ($MY_API_KEY)" → read config-bootstrap.md (App::parseEnv)
  • "Understand CRAFT_* env var conventions" → read config-bootstrap.md
  • "Configure mail transport / SMTP" → read config-app.md
  • "Set up custom URL routes" → read config-bootstrap.md
  • "Configure search to find short words" → read config-app.md
  • "Set up GraphQL tokens and schemas" → read graphql.md + config-general.md
  • "Set up caching for a high-traffic site" → read caching.md
  • "Register custom permissions for my plugin" → read permissions.md
  • "Check user permissions in templates" → read permissions.md
  • "Set up plugin editions / feature gating" → read architecture.md (Plugin Editions section)
  • "Upgrade a plugin from Craft 4 to 5" → read quality.md (Rector section)
  • "Set up CI for a Craft plugin" → read quality.md (CI/CD Integration section)
  • "Create sections or fields in a migration" → read migrations.md (Content Migrations section)
  • "Set up database read replicas" → read config-app.md (Database Replicas section)
  • "Register a module in app.php" → read config-app.md (Module Registration section)
  • "Create a custom validator" → read architecture.md (Custom Validators section)
  • "Create a custom filesystem type" → read events.md (Filesystem Types section)
  • "Build a custom condition rule for an element index" → read cp.md (Condition Builders section)
  • "Build a tri-state on/inherit/off control" → read cp.md (CP UI Patterns — Tri-State Inheritance)
  • "Add tabbed settings page to a plugin" → read cp.md (Tabbed Settings Pages)
  • "Show an 'overrides global' warning on a field" → read cp.md (CP UI Patterns — Field Warning Parameter)
  • "What CSS variables does Craft CP use?" → read cp.md (CP UI Patterns — Craft CSS Custom Properties)
  • "Set up pre-commit hooks for code quality" → read quality.md (Pre-Commit Hooks section)
  • "Restrict element access by user group" → read element-authorization.md + permissions.md
  • "Scope CP element index by permission" → read element-authorization.md (Layer 3: Query Scoping)
  • "Add authorization events to a custom element" → read element-authorization.md + elements.md
  • "Build defense-in-depth for a security plugin" → read element-authorization.md (Defense Patterns)
  • "Force-logout a user from all devices" → read sessions-and-auth.md (Plugin Patterns)
  • "Understand how Craft sessions work" → read sessions-and-auth.md
  • "Implement password reset required" → read sessions-and-auth.md (passwordResetRequired Gap)
  • "Add a column to the Users element index" → read element-index.md (Extending Element Indexes via Events)
  • "Add a bulk action to an element index" → read element-index.md (Adding a custom bulk action)
  • "Add a custom sidebar source to the element index" → read element-index.md (Adding a sidebar source)
  • "Build a custom field type" → read field-types-custom.md + fields.md
  • "Build a relation field type" → read field-types-custom.md (Relation Fields)
  • "Add a condition rule to the entry index" → read conditions.md + element-index.md
  • "Build a custom condition rule" → read conditions.md
  • "Send email from a plugin" → read email.md
  • "Register a custom system message" → read email.md (Registering Custom System Messages)
  • "Configure SMTP transport" → read config-app.md + email.md
  • "Deploy Craft CMS to production" → read deployment.md
  • "Set up CI/CD for a Craft project" → read deployment.md (CI/CD Patterns)
  • "Zero-downtime deploy" → read deployment.md (Zero-Downtime)
  • "Roll back a failed deploy" → read deployment.md (Rollback Strategies)
  • "Work with drafts and revisions" → read drafts-revisions.md
  • "Create a draft programmatically" → read drafts-revisions.md (Creating Drafts)
  • "Skip side effects for drafts in afterSave" → read drafts-revisions.md (Plugin Considerations)
  • "Add generated fields to a custom element" → read elements.md (Generated Fields)
  • "Customize how my element appears as a chip or card" → read element-index.md (Element Display Modes)
  • "Make plugin settings read-only when allowAdminChanges is off" → read cp.md (Read-Only Mode)
TaskRead
Element core: lifecycle, queries, status, authorization, drafts, revisions, propagation, field layouts, eventsreferences/elements.md
Element index: sources, table/card attributes, sort, conditions, actions, exporters, sidebar, metadata, extending via events (columns, sources, bulk actions, condition rules, sort)references/element-index.md
Services, models, records, project config, MemoizableArray, events, API clients, custom validatorsreferences/architecture.md
Controllers: CP CRUD, webhooks, API endpoints, action routing, authorizationreferences/controllers.md
CP templates, form macros, admin changes, VueAdminTable, asset bundles, CP layout, permissions. For CP JavaScript interactions, also load craft-garnish skill.references/cp.md
Database migrations, Install.php, foreign keys, indexes, idempotency, deploymentreferences/migrations.md
Queue jobs, BaseJob, TTR, retry, progress, batch jobs, site contextreferences/queue-jobs.md
Console commands, arguments, options, progress bars, output helpers, resave actionsreferences/console-commands.md
Debugging, performance, query strategy, profiling, Xdebug, caching, loggingreferences/debugging.md
PHPStan, ECS, code review checklistreferences/quality.md
Testing: Pest setup, element factories, HTTP/queue/DB assertions, mocking, multi-site, console, eventsreferences/testing.md
Field types, native fields, BaseNativeField, field layout elements, FieldLayoutBehaviorreferences/fields.md
Events: registration, lifecycle, naming conventions, custom events, behaviors, Twig extensions, utilities, widgets, filesystems, discovering eventsreferences/events.md
GraphQL types, queries, mutations, directives, schema components, resolversreferences/graphql.md
Plugin Vite: VitePluginService, CP asset bundles, HMR, TypeScript, Vue in CPreferences/plugin-vite.md
Headless & hybrid: headlessMode, GraphQL API, CORS, preview tokens, front-end frameworkscraft-site skill references/headless.md
GeneralConfig (system, routing, security, users, sessions, search, assets, images)references/config-general.md
GeneralConfig (content, templates, performance, GC, localization, headless, GraphQL, accessibility, preview, dev, dangerous interactions)references/config-general-extended.md
App config: cache, session, queue, mutex, mailer/SMTP, search, logging, CORS, DB replicas, web/console splitreferences/config-app.md
Config bootstrap: env vars, aliases, priority order, fluent API, custom.php, db.php, routes.php, htmlpurifierreferences/config-bootstrap.md
Caching: template cache tag, data cache, static caching (Blitz), CDN, layered strategy, invalidationreferences/caching.md
Permissions: built-in handles, user groups, custom registration, Twig/PHP checking, authorization events, strategiesreferences/permissions.md
Element authorization: four-layer defense model, authorization events, can*() methods, EVENT_BEFORE_PREPARE query scoping, controller enforcementreferences/element-authorization.md
Sessions & auth internals: dual-layer session model, auth tokens, session invalidation, passwordResetRequired, elevated sessions, plugin patternsreferences/sessions-and-auth.md
Custom field types: build pattern, value lifecycle, settings, input HTML, validation, search, GraphQL, relation fieldsreferences/field-types-custom.md
Conditions framework: BaseCondition, ElementCondition, custom condition rules, registering rules, condition builder UIreferences/conditions.md
Email system: system messages, custom messages, programmatic sending, templates, events, testingreferences/email.md
Deployment: standard pipeline, project config deploy, zero-downtime, CI/CD, rollback, environment managementreferences/deployment.md
Drafts & revisions: draft types, provisional drafts, autosave, applying, merge, revisions, plugin considerationsreferences/drafts-revisions.md

Plugin vs Module Differences

Plugins and modules share the same architecture patterns. The differences are in bootstrapping and registration:

FeaturePluginModule
CP template rootAutomatic (by handle)Manual via EVENT_REGISTER_CP_TEMPLATE_ROOTS
Site template rootManual via eventSame — manual for both
Translation categoryAutomatic (by handle)Manual PhpMessageSource in init()
Settings modelBuilt-in createSettingsModel()Env vars, config files, or private plugin (_ prefix)
Install migrationmigrations/Install.phpContent migrations only
Console commandsAutomatic controllerNamespaceMust set before parent::init(), must be bootstrapped
CP nav section$hasCpSection = trueEVENT_REGISTER_CP_NAV_ITEMS
Project configSettings auto-trackedManual ProjectConfig::set() only
Namespace aliasAutomatic via ComposerMust call Craft::setAlias()

Module Template Root Registration

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';
    }
);

Module Translation Registration

Craft::$app->i18n->translations['my-module'] = [
    'class' => \craft\i18n\PhpMessageSource::class,
    'sourceLanguage' => 'en',
    'basePath' => __DIR__ . '/translations',
    'allowOverrides' => true,
];

Module Console Command Registration

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.

Capabilities

skillsource-michtioskill-craftcmstopic-agent-skillstopic-claude-codetopic-claude-code-plugintopic-claude-code-skillstopic-claude-skillstopic-content-modelingtopic-craft-cmstopic-craft-cms-5topic-craftcmstopic-ddevtopic-phptopic-twig

Install

Installnpx skills add michtio/craftcms-claude-skills
Transportskills-sh
Protocolskill

Quality

0.47/ 1.00

deterministic score 0.47 from registry signals: · indexed on github topic:agent-skills · 39 github stars · SKILL.md body (14,628 chars)

Provenance

Indexed fromgithub
Enriched2026-05-01 18:56:49Z · deterministic:skill-github:v1 · v1
First seen2026-04-18
Last seen2026-05-01

Agent access