Skip to main content
ClaudeWave
Skill62 repo starsupdated 6d ago

craftcms

Craft CMS 5 plugin and module development — extending Craft with PHP. Covers 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. Triggers on: beforePrepare(), afterSave(), defineSources(), defineTableAttributes(), attributeHtml(), MemoizableArray, BaseNativeField, EVENT_REGISTER_*/DEFINE_*/BEFORE_*/AFTER_*, CraftVariable, registerTwigExtension, custom element type, custom field type (normalizeValue, serializeValue, inputHtml), webhook, API endpoint, queue job, batch processing, CP section, control panel, element action, element exporter, element condition, dashboard widget, utility page, registerUserPermissions, requirePermission, GraphQL custom types/mutations, schema building, defineRules, canView/canSave/canDelete authorization, session invalidation, elevated session, BaseCondition, system messages, Mailer, atomic deploy, craft up, project-config/apply, drafts, revisions, GeneralConfig, $allowAnonymous. Always use when writing, editing, or reviewing Craft CMS plugin or module PHP code, even when no specific API names are mentioned. Do NOT trigger for front-end Twig (craft-site), content modeling (craft-content-modeling), or headless GraphQL consumption from Next.js/Nuxt/Astro.

Install in Claude Code
Copy
git clone --depth 1 https://github.com/michtio/craftcms-claude-skills /tmp/craftcms && cp -r /tmp/craftcms/skills/craftcms ~/.claude/skills/craftcms
Then start a new Claude Code session; the skill loads automatically.

SKILL.md

# 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.
- **`craft-cloud`** — When the project is hosted on Craft Cloud (detect via `craft-cloud.yaml` at the repo root or `craftcms/cloud` in `composer.json`). Required for plugin Cloud-compatibility constraints — `App::isEphemeral()` guards, asset-bundle CDN publishing, 15-minute queue-job cap, `csrfInput()` function over raw token output, and the `cloud/up` deploy lifecycle events.

## Documentation

- Extend guide: https://craftcms.com/docs/5.x/extend/
- Class reference: https://docs.craftcms.com/api/v5/
- Generator: https://craftcms.com/docs/5.x/extend/generator.html

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` (Architecture section first) + `element-index.md` + `fields.md` + `migrations.md` + `cp.md`
- "Build a hierarchical/tree element type" → read `elements.md` (Architecture: One Element Class with Native Structure)
- "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-components.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 `cp-components.md` (Utility Pages) + `events.md` (Utilities section)
- "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 s
craft-code-reviewer-deepSubagent

Deep code review on Opus 4.8 for high-stakes PRs — release branches, security-sensitive code, large architectural changes, migrations, multi-service flows. Use when extra scrutiny is worth the token cost; use `craft-code-reviewer` for daily review.

craft-code-reviewerSubagent

Reviews implemented code for quality, security, and Craft CMS conventions

craft-debuggerSubagent

Tracks down bugs in Craft CMS plugins with systematic investigation

craft-feature-builderSubagent

Builds new features in Craft CMS plugins following project architecture

craft-plannerSubagent

Breaks down large tasks into manageable implementation steps for Craft CMS plugin development

craft-site-builderSubagent

Builds Craft CMS site templates, components, and content architecture

craft-cloudSkill

Craft Cloud — Pixel & Tonic's serverless hosting platform for Craft CMS. Covers craft-cloud.yaml configuration, the Build → Migrate → Release deploy pipeline, the craftcms/cloud extension package, edge image transforms via Cloudflare, edge static caching with cache.rules + ESI, Cloud-managed S3 filesystem, MySQL 8 / Postgres 15 databases (no MariaDB, no tablePrefix), Console-based command runner and scheduled cron (once-per-hour minimum), auto-handled queue jobs, custom domains and SSL, preview environments per branch, Cloud limitations (ephemeral filesystem, no SSH, no .htaccess, no built-in mail), plugin development requirements for Cloud compatibility, and self-hosted → Cloud migration. Triggers on: craft-cloud.yaml, craftcms/cloud package, cloud.esi(), php craft cloud/up, php craft cloud/setup, App::isEphemeral(), CRAFT_EPHEMERAL, edge.craft.cloud, preview.craft.cloud, CRAFT_CLOUD_PROJECT_ID, CRAFT_CLOUD_ENVIRONMENT_ID, CRAFT_CLOUD_CDN_BASE_URL, Build → Migrate → Release, Cloud filesystem, Cloud-compatible plugin, Cloudflare Images at edge, AssetsFs, static-caching rules, ESI islands, deploy to Craft Cloud, migrate to Craft Cloud, self-hosted to Cloud, Craft Cloud quotas, Craft Cloud regions. Do NOT trigger for Servd (use the servd skill) or generic Craft deployment on Forge/bare metal (craftcms/deployment.md). Do NOT trigger for general DDEV local dev unrelated to Cloud parity.

craft-content-modelingSkill

Craft CMS 5 content modeling — sections, entry types, fields, Matrix, relations, project config, and content architecture strategy. Covers everything editors and developers need to structure content in Craft: choosing section types, designing entry types and field layouts, selecting field types for specific needs, configuring Matrix and nested entries, setting up relations and eager loading, and planning multi-site propagation. Triggers on: section types (single, channel, structure), entry types, field types, field layout design, field type selection, Matrix configuration, nested entries, relatedTo, eager loading, .with(), .eagerly(), categories, tags, globals, global sets, preloadSingles, propagation, multi-site content, URI format, project config, YAML, content architecture, content strategy, taxonomy, asset volumes, filesystems, image transforms, user groups, content permissions, entries-as-taxonomy, entrify, entrification, CKEditor vs Matrix, CMS editions, site propagation, multi-language, language groups, localization, translation method, field translation, content migration, reserved handles, field instances. Always use when planning content architecture, creating sections/fields, configuring Matrix, setting up relations, choosing field types, designing field layouts, making content modeling decisions, or planning multi-site content propagation. Do NOT trigger for PHP plugin/module development, custom field type code, front-end Twig templates, or buildchain configuration.