-
Notifications
You must be signed in to change notification settings - Fork 11
Add AI guidance assets for Drupal best practices #6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| # AI Contribution Guide | ||
|
|
||
| - Follow the Drupal 10+ best practices documented in `README.md`, especially sections 2 (Site building) and 3 (Theming, templates). | ||
| - Keep generated guidance tool-agnostic whenever possible; mention specific CLIs (drush, ddev, composer, git) only when necessary. | ||
| - Prefer concise, actionable bullet points over long prose for skills, rules, and commands. | ||
| - When writing validation scripts, fail fast if required tools (e.g., `drush`) are missing and provide clear messaging. | ||
| - Do not introduce Drupal 7.x-only guidance. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| # AI Resources for Drupal Best Practices | ||
|
|
||
| This folder contains AI-friendly assets derived from `README.md` (Sections 2 and 3) to help coding assistants apply Drupal 10+ best practices. | ||
|
|
||
| - `AGENTS.md`: contributor guidance for AI-generated content. | ||
| - `skills/claude-code-skills.md`: per-subsection skills aligned to site building and theming. | ||
| - `rules/best-practice-rules.md`: tool-agnostic rules for any CLI or IDE integration. | ||
| - `commands/commands.md`: slash-command triggers that map directly to best-practice sections. | ||
| - `scripts/validate-site-building.sh`: drush-based checks for section 2 topics (nodes, blocks, taxonomy, etc.). | ||
| - `scripts/validate-theming.sh`: drush-based checks for section 3 theming guidelines. | ||
|
|
||
| Ensure the project uses Drupal 10+ conventions; Drupal 7.x-only rules are intentionally omitted. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| # AI Command Triggers for Drupal Best Practices | ||
|
|
||
| Use these slash commands (or similar triggers) to request focused guidance mapped to `README.md` subsections. | ||
|
|
||
| - `/drupal-best-practices-nodes` → 2. Site building > 2.1 Nodes | ||
| - `/drupal-best-practices-blocks` → 2. Site building > 2.2 Blocks | ||
| - `/drupal-best-practices-taxonomy` → 2. Site building > 2.3 Taxonomy | ||
| - `/drupal-best-practices-content-entities` → 2. Site building > 2.4 Other content entities | ||
| - `/drupal-best-practices-fields` → 2. Site building > 2.5 Fields | ||
| - `/drupal-best-practices-views` → 2. Site building > 2.6 Views | ||
| - `/drupal-best-practices-forms` → 2. Site building > 2.7 Forms | ||
| - `/drupal-best-practices-editors` → 2. Site building > 2.8 Text formats and editors | ||
| - `/drupal-best-practices-users` → 2. Site building > 2.10 Users, roles & permissions | ||
| - `/drupal-best-practices-theming` → 3. Theming, templates |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| # Tool-Agnostic Rules for Drupal 10+ Best Practices | ||
|
|
||
| Use these rules across AI coding helpers, CLIs, and IDE automations. They mirror `README.md` sections 2 and 3. | ||
|
|
||
| ## Site building (Section 2) | ||
| - Machine names for bundles, fields, blocks, and views must be singular, human-meaningful, and free of suffix clutter (e.g., drop `_1`). | ||
| - Prefer custom entities or block types over overloading nodes; create new bundles only for distinct display/logic needs. | ||
| - Provide descriptions for content types, fields, and Views; document access via permissions rather than roles. | ||
| - Reuse fields only when identical across bundles; set deterministic upload directories and avoid `gif` unless required. | ||
| - Views should use content-based rows with view modes, explicit titles, tags, and non-AJAX defaults; disable unused displays. | ||
| - Standardize on a single HTML format with CKEditor; keep admins aligned with author-capable formats and avoid insecure content via UI. | ||
| - Model roles by persona with concise machine names; each module must declare its own permissions and expose dashboards tailored to roles. | ||
|
|
||
| ## Theming, templates (Section 3) | ||
| - Use one-word machine names for themes without base-theme suffixes or the word `theme`; prefer Classy base or cloned contrib themes. | ||
| - Follow Atomic design, SCSS, and common breakpoints; avoid panels-family modules. | ||
| - Favor twig templates and preprocess functions for structure and classes; include key pages (404/403/maintenance/login). | ||
| - Avoid styling based on path aliases or non-semantic classes; use functional prefixes (`twig-`, `js-`) and mixins instead of utility elements. | ||
| - Override only necessary CSS/JS, comment mixins/functions, and organize templates by module/entity with minimal folder sprawl. | ||
| - Support modern browsers per Drupal 10+ guidance; keep admin theme overrides minimal and core-focused. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,96 @@ | ||
| #!/usr/bin/env bash | ||
| set -euo pipefail | ||
|
|
||
| # Validate Drupal 10+ site-building best practices for section 2. | ||
| # Usage: ./validate-site-building.sh [section] | ||
| # Sections: nodes blocks taxonomy entities fields views forms editors users | ||
|
|
||
| section="${1:-all}" | ||
| project_root="${PROJECT_ROOT:-$(pwd)}" | ||
| config_dir="${CONFIG_DIR:-${project_root}/config/sync}" | ||
|
|
||
| if ! command -v drush >/dev/null 2>&1; then | ||
| echo "[WARN] drush not found. Install drush or set PATH so checks can run." >&2 | ||
| exit 1 | ||
| fi | ||
|
|
||
| run_drush() { | ||
| local cmd="$1" | ||
| echo "[INFO] drush ${cmd}" >&2 | ||
| drush ${cmd} | ||
| } | ||
|
|
||
| check_nodes() { | ||
| echo "[CHECK] 2.1 Nodes: singular names, minimal bundles, consistent view modes" | ||
| run_drush "eval 'print json_encode(\\Drupal\\node\\Entity\\NodeType::loadMultiple());'" \ | ||
| | jq 'keys[]' >/dev/null | ||
| } | ||
|
|
||
| check_blocks() { | ||
| echo "[CHECK] 2.2 Blocks: custom block types via code and clean machine names" | ||
| run_drush "eval 'print json_encode(\\Drupal\\block_content\\Entity\\BlockContentType::loadMultiple());'" \ | ||
| | jq 'keys[]' >/dev/null | ||
| } | ||
|
|
||
| check_taxonomy() { | ||
| echo "[CHECK] 2.3 Taxonomy: singular vocabularies and purpose beyond filtering" | ||
| run_drush "eval 'print json_encode(\\Drupal\\taxonomy\\Entity\\Vocabulary::loadMultiple());'" \ | ||
| | jq 'keys[]' >/dev/null | ||
| } | ||
|
|
||
| check_entities() { | ||
| echo "[CHECK] 2.4 Other content entities: paragraphs/media revisions and generic image styles" | ||
| run_drush "eval 'print json_encode(\\Drupal\\image\\Entity\\ImageStyle::loadMultiple());'" \ | ||
| | jq 'keys[]' >/dev/null | ||
| } | ||
|
|
||
| check_fields() { | ||
| echo "[CHECK] 2.5 Fields: naming patterns and descriptions" | ||
| run_drush "eval 'print json_encode(array_keys(\\Drupal\\field\\Entity\\FieldStorageConfig::loadMultiple()));'" \ | ||
| | jq '[]' >/dev/null | ||
| } | ||
|
|
||
| check_views() { | ||
| echo "[CHECK] 2.6 Views: clean machine names, per-display instances, permissions" | ||
| run_drush "views:list" >/dev/null | ||
| } | ||
|
|
||
| check_forms() { | ||
| echo "[CHECK] 2.7 Forms: prefer Webform over core Contact for complex needs" | ||
| run_drush "pm:list webform" >/dev/null | ||
| } | ||
|
|
||
| check_editors() { | ||
| echo "[CHECK] 2.8 Text formats and editors: single HTML format with CKEditor" | ||
| run_drush "eval 'print json_encode(\\Drupal\\filter\\Entity\\FilterFormat::loadMultiple());'" \ | ||
| | jq 'keys[]' >/dev/null | ||
| } | ||
|
|
||
| check_users() { | ||
| echo "[CHECK] 2.10 Users: persona-based roles and module-defined permissions" | ||
| run_drush "role:list" >/dev/null | ||
| } | ||
|
|
||
| case "${section}" in | ||
| all) | ||
| check_nodes | ||
| check_blocks | ||
| check_taxonomy | ||
| check_entities | ||
| check_fields | ||
| check_views | ||
| check_forms | ||
| check_editors | ||
| check_users | ||
| ;; | ||
| nodes) check_nodes ;; | ||
| blocks) check_blocks ;; | ||
| taxonomy) check_taxonomy ;; | ||
| entities) check_entities ;; | ||
| fields) check_fields ;; | ||
| views) check_views ;; | ||
| forms) check_forms ;; | ||
| editors) check_editors ;; | ||
| users) check_users ;; | ||
| *) echo "Unknown section: ${section}" >&2; exit 1 ;; | ||
| esac | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,55 @@ | ||
| #!/usr/bin/env bash | ||
| set -euo pipefail | ||
|
|
||
| # Validate Drupal 10+ theming best practices for section 3. | ||
| # Usage: ./validate-theming.sh [check] | ||
| # Checks: themes css twig assets | ||
|
|
||
| check="${1:-all}" | ||
|
|
||
| if ! command -v drush >/dev/null 2>&1; then | ||
| echo "[WARN] drush not found. Install drush or set PATH so checks can run." >&2 | ||
| exit 1 | ||
| fi | ||
|
|
||
| run_drush() { | ||
| local cmd="$1" | ||
| echo "[INFO] drush ${cmd}" >&2 | ||
| drush ${cmd} | ||
| } | ||
|
|
||
| check_themes() { | ||
| echo "[CHECK] 3 Theming: machine names, base theme choice, and breakpoints" | ||
| run_drush "theme:list" >/dev/null | ||
| } | ||
|
|
||
| check_css() { | ||
| echo "[CHECK] 3 Theming: SCSS usage, Atomic structure, and limited overrides" | ||
| find themes -maxdepth 2 -type f \( -name '*.scss' -o -name '*.sass' \) >/dev/null | ||
| } | ||
|
|
||
| check_twig() { | ||
| echo "[CHECK] 3 Theming: preprocess coverage and template organization" | ||
| run_drush "ev 'print json_encode(array_keys(\\Drupal\\theme_handler\\ThemeHandler::defaultThemeList()));'" \ | ||
| | jq 'keys[]' >/dev/null | ||
|
Comment on lines
+31
to
+34
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The twig validation runs Useful? React with 👍 / 👎. |
||
| } | ||
|
|
||
| check_assets() { | ||
| echo "[CHECK] 3 Theming: browser support and utility-first frameworks used selectively" | ||
| run_drush "ev 'print json_encode(\\Drupal\\core\\Asset\\LibraryDiscovery::getInfo());'" \ | ||
| | jq 'keys[]' >/dev/null | ||
|
Comment on lines
+37
to
+40
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The assets check calls Useful? React with 👍 / 👎. |
||
| } | ||
|
|
||
| case "${check}" in | ||
| all) | ||
| check_themes | ||
| check_css | ||
| check_twig | ||
| check_assets | ||
| ;; | ||
| themes) check_themes ;; | ||
| css) check_css ;; | ||
| twig) check_twig ;; | ||
| assets) check_assets ;; | ||
| *) echo "Unknown check: ${check}" >&2; exit 1 ;; | ||
| esac | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,55 @@ | ||
| # Claude Code Skills for Drupal 10+ Best Practices | ||
|
|
||
| These skills mirror the repository's best practices so Claude-based tools can deliver focused help per subsection. | ||
|
|
||
| ## 2. Site building | ||
|
|
||
| ### Skill: 2.1 Nodes | ||
| - Enforce singular machine names for node bundles and fields; avoid conflicts or ambiguous prefixes. | ||
| - Recommend custom entities or block types instead of using nodes for dynamic blocks. | ||
| - Limit new bundles to cases with distinct displays or behavior; align view modes across types and document content type purpose. | ||
|
|
||
| ### Skill: 2.2 Blocks | ||
| - Generate custom block types or plugins with concise machine names (no theme/region hints and no `block_` prefix). | ||
| - Treat block fields and view modes like other content entities; prefer code-generated block types for stability. | ||
| - Avoid hardcoding UUID-based blocks; use plugins for static blocks. | ||
|
|
||
| ### Skill: 2.3 Taxonomy | ||
| - Use singular vocabulary names and reserve taxonomies for categorized pages rather than simple filters. | ||
| - Prefer list fields for filtering-only needs and consider node references when authorization, fields, or displays are required. | ||
|
|
||
| ### Skill: 2.4 Other content entities | ||
| - Apply node rules to paragraphs, media, comments, etc.; watch translation/revision behavior (especially paragraphs). | ||
| - Name image styles generically (e.g., `large_wide`) instead of dimension-specific machine names. | ||
|
|
||
| ### Skill: 2.5 Fields | ||
| - Advocate clear, reusable machine names: `field_[content_type]_[short_name]` for specific fields and generic prefixes for shared ones. | ||
| - Require field descriptions, meaningful upload directories (avoid date-based defaults), and removal of `gif` unless necessary. | ||
| - Encourage consistent prefixes when projects mandate them and reuse fields only when truly identical across bundles. | ||
|
|
||
| ### Skill: 2.6 Views | ||
| - Normalize machine names (remove `_1` suffixes) and create one View per display when possible. | ||
| - Use `Show: Content` with view modes, provide titles, descriptions, tags, access by permission, and no default AJAX. | ||
| - Disable unused Views, supply "No results" text, and avoid blanket custom CSS classes. | ||
|
|
||
| ### Skill: 2.7 Forms | ||
| - Recommend Webform for custom forms; use core Contact form only for minimal needs without stored submissions. | ||
|
|
||
| ### Skill: 2.8 Text formats and editors | ||
| - Standardize on one HTML editor format with CKEditor, aligned buttons and allowed tags; avoid insecure content via UI. | ||
| - Prevent role-based format hopping and keep admins aligned with authors' editable formats. | ||
|
|
||
| ### Skill: 2.10 Users, roles & permissions | ||
| - Model roles by persona, avoid overpowered authenticated roles, and keep machine names short. | ||
| - Ensure each module declares its own permissions with verb-led names; prefer Masquerade for permission testing. | ||
| - Provide custom admin dashboards and limit duplicate admin accounts. | ||
|
|
||
| ## 3. Theming, templates | ||
|
|
||
| ### Skill: 3 Theming fundamentals | ||
| - Use one-word theme machine names without `theme` or base-theme suffixes; prefer Classy base theme or cloned contrib themes without inheritance. | ||
| - Align CSS with Atomic design, SCSS, and consistent breakpoints; avoid panels family modules. | ||
| - Rely on preprocess functions and targeted twig templates (including 404/403/maintenance/login) instead of DB theme settings for teams. | ||
| - Avoid path-alias-based styling and non-semantic CSS classes; use functional prefixes (`twig-`, `js-`) and mixins over utility elements. | ||
| - Override only necessary CSS/JS, favor utility-first frameworks selectively, comment mixins/functions, and organize templates by module/entity. | ||
| - Support modern browser guidance (Drupal 10+ drops IE11) and keep admin theme mostly core with light overrides. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The forms validation uses
drush pm:list webform, butpm:list(pml) does not take module names as positional arguments—it only accepts options like--typeor--status. Passingwebformcauses Drush to exit with a “too many arguments” error, and withset -ethe entire site-building validation halts whenever the forms check (orall) is selected.Useful? React with 👍 / 👎.