Skip to content

Commit c94e919

Browse files
authored
Merge pull request #15 from itk-dev/feature/issue-7-drupal-skill
Add Drupal development skill
2 parents 3751e0a + 0cb4a88 commit c94e919

2 files changed

Lines changed: 338 additions & 0 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
### Added
1111

12+
- Drupal development skill for code auditing, module/theme development, and configuration management (Drupal 10/11)
1213
- ADR (Architecture Decision Record) skill for creating and managing architectural decisions
1314
- Auto-release workflow for MCP dependency updates
1415
- Daily scheduled check for new MCP releases (8:30 UTC)

skills/itkdev-drupal.md

Lines changed: 337 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,337 @@
1+
---
2+
name: itkdev-drupal
3+
description: Drupal development assistance for ITK Dev projects. Use when working with Drupal 10/11 codebases, creating modules/themes, running drush commands, auditing code quality, or managing configuration. Activates for projects with *.info.yml files or web/modules structure.
4+
---
5+
6+
# Drupal Development Guide
7+
8+
You are assisting with Drupal 10/11 development. This skill covers code auditing, module/theme development, drush commands, and configuration management.
9+
10+
## Project Detection
11+
12+
Recognize Drupal projects by:
13+
- `*.info.yml` files in modules/themes
14+
- `web/modules` or `web/themes` directory structure
15+
- `composer.json` with `drupal/core` dependency
16+
- `docker-compose.yml` with ITK Dev Docker setup
17+
- `Taskfile.yml` with defined tasks
18+
19+
## ITK Dev Docker Environment
20+
21+
**IMPORTANT:** ITK Dev projects run in Docker containers. Never run commands directly on the host - always use `itkdev-docker-compose` or Taskfile tasks.
22+
23+
### itkdev-docker-compose Commands
24+
25+
The `itkdev-docker-compose` CLI wraps docker-compose and provides Drupal-specific commands:
26+
27+
```bash
28+
# Drush (runs inside phpfpm container)
29+
itkdev-docker-compose drush cr # Clear cache
30+
itkdev-docker-compose drush cex -y # Export config
31+
itkdev-docker-compose drush cim -y # Import config
32+
itkdev-docker-compose drush updb -y # Run updates
33+
34+
# Composer (runs inside phpfpm container)
35+
itkdev-docker-compose composer install
36+
itkdev-docker-compose composer require drupal/module_name
37+
38+
# PHP (runs inside phpfpm container)
39+
itkdev-docker-compose php script.php
40+
41+
# Database
42+
itkdev-docker-compose sql:cli # MySQL CLI
43+
itkdev-docker-compose sync:db # Sync database from remote
44+
itkdev-docker-compose sync:files # Sync files from remote
45+
itkdev-docker-compose sync # Sync both db and files
46+
47+
# Utilities
48+
itkdev-docker-compose url # Print site URL
49+
itkdev-docker-compose open # Open site in browser
50+
51+
# Any vendor/bin command
52+
itkdev-docker-compose vendor/bin/phpcs # Run PHP CodeSniffer
53+
itkdev-docker-compose vendor/bin/phpunit # Run PHPUnit
54+
```
55+
56+
### Taskfile.yml
57+
58+
Projects typically have a `Taskfile.yml` defining common workflows. **Always check for and use Taskfile tasks first** before running raw commands.
59+
60+
Common task patterns:
61+
```bash
62+
task # List available tasks
63+
task dev:setup # Initial project setup
64+
task dev:reset # Reset local environment
65+
task ci # Run CI checks (coding standards, tests)
66+
task ci:coding-standards
67+
task ci:phpunit
68+
task config:export # Export Drupal configuration
69+
task config:import # Import Drupal configuration
70+
```
71+
72+
**Convention:** If a Taskfile.yml exists, prefer `task <name>` over direct `itkdev-docker-compose` commands, as tasks often chain multiple commands and handle edge cases.
73+
74+
## Xdebug
75+
76+
ITK Dev Docker environments include Xdebug for step debugging PHP code.
77+
78+
### Enabling Xdebug
79+
80+
Xdebug is typically controlled via environment variables in the Docker setup:
81+
82+
```bash
83+
# Check if Xdebug is enabled
84+
itkdev-docker-compose php -m | grep xdebug
85+
86+
# Enable Xdebug (if using XDEBUG_MODE environment variable)
87+
# Add to docker-compose.override.yml or .env file:
88+
XDEBUG_MODE=debug
89+
```
90+
91+
Common `XDEBUG_MODE` values:
92+
- `off` - Disable Xdebug (default for performance)
93+
- `debug` - Enable step debugging
94+
- `coverage` - Enable code coverage analysis
95+
- `debug,coverage` - Enable both
96+
97+
### IDE Configuration
98+
99+
#### VS Code
100+
101+
1. Install the **PHP Debug** extension by Xdebug
102+
2. Create `.vscode/launch.json`:
103+
104+
```json
105+
{
106+
"version": "0.2.0",
107+
"configurations": [
108+
{
109+
"name": "Listen for Xdebug",
110+
"type": "php",
111+
"request": "launch",
112+
"port": 9003,
113+
"pathMappings": {
114+
"/app": "${workspaceFolder}"
115+
}
116+
}
117+
]
118+
}
119+
```
120+
121+
#### PHPStorm
122+
123+
1. Go to **Settings → PHP → Servers**
124+
2. Add a server with:
125+
- Host: Your local Docker URL (e.g., `project.docker.localhost`)
126+
- Port: 80
127+
- Debugger: Xdebug
128+
- Path mappings: `/app` → project root
129+
3. Go to **Settings → PHP → Debug**
130+
- Debug port: 9003
131+
4. Click **Start Listening for PHP Debug Connections**
132+
133+
### Debugging Workflow
134+
135+
1. Set breakpoints in your IDE
136+
2. Start listening for debug connections
137+
3. Trigger the code (via browser, drush, or CLI)
138+
4. Step through code using IDE controls
139+
140+
### Debugging Drush Commands
141+
142+
```bash
143+
# Run drush with Xdebug enabled
144+
XDEBUG_MODE=debug itkdev-docker-compose drush <command>
145+
```
146+
147+
### Troubleshooting
148+
149+
- **Xdebug not connecting**: Check that `xdebug.client_host` points to your host machine (usually `host.docker.internal`)
150+
- **Wrong path mappings**: Ensure IDE path mappings match Docker volume mounts (typically `/app`)
151+
- **Performance issues**: Set `XDEBUG_MODE=off` when not debugging
152+
153+
## Code Audit
154+
155+
When reviewing Drupal code, check for:
156+
157+
### Drupal Coding Standards
158+
- Follow [Drupal.org coding standards](https://www.drupal.org/docs/develop/standards)
159+
- Use proper namespacing: `Drupal\module_name\...`
160+
- Service-based architecture over procedural code
161+
- Dependency injection in classes
162+
163+
### Security Review
164+
- **SQL Injection**: Use Database API with placeholders, never concatenate user input
165+
- **XSS Prevention**: Use `#markup` with `Xss::filter()`, `#plain_text`, or Twig auto-escaping
166+
- **CSRF Protection**: Use Form API with tokens for state-changing operations
167+
- **Access Control**: Implement proper permission checks
168+
- **Input Sanitization**: Use `\Drupal\Component\Utility\Html::escape()`
169+
170+
### Debug Code Detection
171+
Flag and remove before commit:
172+
- `var_dump()`, `print_r()`, `dd()`
173+
- `dpm()`, `dsm()`, `kint()`
174+
- `\Drupal::logger()` with debug level in production code
175+
176+
### Deprecated API Detection
177+
178+
**Drupal 10 Deprecations** (removed in 11):
179+
- `drupal_set_message()` → use `\Drupal::messenger()->addMessage()`
180+
- `file_unmanaged_*` functions → use file system service
181+
- `entity_load()` → use entity type manager
182+
- `db_query()` → use Database service
183+
184+
**Drupal 11 Changes**:
185+
- Symfony 7 compatibility required
186+
- PHP 8.3+ required
187+
- Check `*.info.yml` for `core_version_requirement`
188+
189+
### Code Quality
190+
- SOLID principles in custom code
191+
- Single responsibility for services
192+
- Proper use of hooks vs. event subscribers
193+
- Render arrays over direct HTML
194+
- Configuration over hardcoded values
195+
196+
## Module Development
197+
198+
### Creating a New Module
199+
200+
Basic structure:
201+
```
202+
modules/custom/module_name/
203+
├── module_name.info.yml
204+
├── module_name.module
205+
├── module_name.services.yml
206+
├── module_name.routing.yml
207+
├── module_name.permissions.yml
208+
├── src/
209+
│ ├── Controller/
210+
│ ├── Form/
211+
│ ├── Plugin/
212+
│ └── Service/
213+
├── config/
214+
│ ├── install/
215+
│ └── schema/
216+
└── templates/
217+
```
218+
219+
### info.yml Template
220+
```yaml
221+
name: 'Module Name'
222+
type: module
223+
description: 'Module description'
224+
package: Custom
225+
core_version_requirement: ^10 || ^11
226+
dependencies:
227+
- drupal:node
228+
```
229+
230+
### Service Definition
231+
```yaml
232+
services:
233+
module_name.example_service:
234+
class: Drupal\module_name\Service\ExampleService
235+
arguments: ['@entity_type.manager', '@current_user']
236+
```
237+
238+
## Theme Development
239+
240+
### Creating a New Theme
241+
242+
Basic structure:
243+
```
244+
themes/custom/theme_name/
245+
├── theme_name.info.yml
246+
├── theme_name.libraries.yml
247+
├── theme_name.theme
248+
├── css/
249+
├── js/
250+
├── images/
251+
└── templates/
252+
```
253+
254+
### Theme info.yml Template
255+
```yaml
256+
name: 'Theme Name'
257+
type: theme
258+
description: 'Theme description'
259+
package: Custom
260+
core_version_requirement: ^10 || ^11
261+
base theme: stable9
262+
libraries:
263+
- theme_name/global-styling
264+
```
265+
266+
## Drush Commands
267+
268+
**Always run drush via itkdev-docker-compose** (or use Taskfile tasks if available):
269+
270+
```bash
271+
# Cache
272+
itkdev-docker-compose drush cr # Clear all caches
273+
itkdev-docker-compose drush cc render # Clear render cache only
274+
275+
# Configuration
276+
itkdev-docker-compose drush cex -y # Export configuration
277+
itkdev-docker-compose drush cim -y # Import configuration
278+
itkdev-docker-compose drush config:get system.site # Get specific config
279+
280+
# Database
281+
itkdev-docker-compose drush sql:dump > backup.sql # Database backup
282+
itkdev-docker-compose sql:cli # Database CLI (direct command)
283+
284+
# Updates
285+
itkdev-docker-compose drush updb -y # Run database updates
286+
itkdev-docker-compose drush entity:updates # Apply entity schema updates
287+
288+
# Development
289+
itkdev-docker-compose drush en module_name -y # Enable module
290+
itkdev-docker-compose drush pmu module_name -y # Uninstall module
291+
292+
# Generate (requires drush generators)
293+
itkdev-docker-compose drush generate module # Generate module scaffold
294+
itkdev-docker-compose drush generate controller # Generate controller
295+
```
296+
297+
## Configuration Management
298+
299+
### Workflow
300+
1. Make changes in development environment
301+
2. Export: `task config:export` or `itkdev-docker-compose drush cex -y`
302+
3. Review changes in `config/sync/`
303+
4. Commit configuration files
304+
5. On deployment: `task config:import` or `itkdev-docker-compose drush cim -y`
305+
306+
### Config Split
307+
For environment-specific configuration:
308+
- `config/sync/` - Shared configuration
309+
- `config/dev/` - Development overrides
310+
- `config/prod/` - Production overrides
311+
312+
### Schema Definition
313+
Always define schema for custom configuration in `config/schema/module_name.schema.yml`:
314+
```yaml
315+
module_name.settings:
316+
type: config_object
317+
label: 'Module settings'
318+
mapping:
319+
enabled:
320+
type: boolean
321+
label: 'Enabled'
322+
api_key:
323+
type: string
324+
label: 'API Key'
325+
```
326+
327+
## ITK Dev Conventions
328+
329+
When working on ITK Dev Drupal projects:
330+
- **Always use Docker**: Run all commands via `itkdev-docker-compose` or Taskfile tasks
331+
- **Check Taskfile.yml first**: Use `task` to list available tasks before running raw commands
332+
- Follow `itkdev-github-guidelines` for commits and PRs
333+
- Check for project-specific `CLAUDE.md` guidelines
334+
- Configuration should be exportable and version controlled
335+
- Custom modules go in `web/modules/custom/`
336+
- Custom themes go in `web/themes/custom/`
337+
- Run `task ci` (or equivalent) before creating PRs to ensure code quality

0 commit comments

Comments
 (0)