{"owner":"EasyCorp","repo":"EasyAdminBundle","hasSkills":true,"hasMcp":false,"mcpConfig":null,"found":["AGENTS.md"],"skills":{"AGENTS.md":"# AI Contribution Guidelines\n\nWelcome, AI assistant. Please follow these guidelines when contributing to this repository.\n\n## Project Overview\n\nEasyAdminBundle is a third-party Symfony bundle for creating admin backends. It provides CRUD controllers, dashboard management, and extensive field/filter configuration.\n\n**Requirements:** PHP 8.2+, Symfony 6.4/7.x/8.x, Doctrine ORM 2.20+ or 3.6+\n\n## General Rules\n\n- Language: American English for code, comments, commits, branches\n- Code quotes: wrap strings with single quotes in PHP, CSS, JavaScript\n- Text quotes: straight quotes only (`'` and `\"`, no typographic)\n- Security: prevent XSS, CSRF, injections, auth bypass, open redirects\n\n### Do Not Edit\n- `vendor/` - managed by Composer\n- `node_modules/` - managed by Yarn\n- `var/` - Symfony cache/logs\n- `public/bundles/` - generated assets\n- `composer.lock`, `yarn.lock` - update only via package manager commands\n\n## Architecture\n\n### Key Patterns\n- **Factory**: ActionFactory, EntityFactory, FieldFactory, FilterFactory, FormFactory\n- **Configurator Chain**: FieldConfiguratorInterface, FilterConfiguratorInterface\n- **Context Facade**: AdminContext wraps Request/Crud/Dashboard/I18n contexts\n- **DTO Layer**: Type-safe data transfer (ActionDto, EntityDto, FieldDto, etc.)\n- **Event Subscriber**: AdminRouterSubscriber, CrudAutocompleteSubscriber\n- **Registry**: AdminControllerRegistry, TemplateRegistry\n- **Provider**: AdminContextProvider, FieldProvider\n- **Typed Collections**: FieldCollection, ActionCollection, FilterCollection\n- **Argument Resolver**: AdminContextResolver, BatchActionDtoResolver\n\nDon't modify the public API in `Contracts/` lightly — it's a stable, versioned interface that third-party code depends on.\n\n### Design Principles\n- Never surface internal complexity to end users. Keep the public API small, simple, and consistent; push complexity down into internal classes (factories, configurators, DTOs), not onto the people configuring a backend.\n- Public APIs are stable contracts: prefer additive, backward-compatible changes and don't leak internal types or implementation details through them.\n\n### Backward Compatibility\nFollow [Symfony's BC policy](https://symfony.com/bc): never break public API — deprecate first, keep the old path working, remove only in the next major. Emit deprecations with `@trigger_deprecation('easycorp/easyadmin-bundle', '<version>', '<message>')`, naming the replacement and removal version.\n\n### Configuration Model\nUser-facing config uses fluent **builders** (`Config/`, `Field/`): static `new()` + chainable setters returning `self`. Each builder converts via `getAsDto()` into an immutable **DTO** (`Dto/`) for internal use. New configurable concepts follow this split — fluent builder for users, DTO internally; never expose a DTO as the config surface.\n\n### Main Namespace\n`EasyCorp\\Bundle\\EasyAdminBundle\\`\n\n## Commands\n\nThe `Makefile` is the source of truth for build/lint/test commands; its targets match what CI runs. Prefer them over hand-typed invocations. Run `make help` to list every target.\n\n### Setup\n```bash\nmake build          # composer update + yarn install (first-time setup)\ncomposer install    # PHP dependencies only\nyarn install        # JS dependencies only\n```\n\n### Before Creating a PR\nRun the full check suite (linters + tests, identical to CI):\n```bash\nmake checks-before-pr\n```\n\n### Pre-Commit Checklist\nRun the relevant target(s) for what you changed:\n\n| Changed          | Run                                                               |\n|------------------|-------------------------------------------------------------------|\n| PHP code         | `make linter-phpstan`, `make linter-cs-fixer`, `make tests`       |\n| JS / CSS         | `yarn ci`, then `make build-assets`                               |\n| Twig templates   | `make linter-twig`                                                |\n| Documentation    | `make linter-docs`                                                |\n| Translations     | keep all locales consistent; use English as placeholder if unsure |\n\nRun targeted tests with `make tests ARGS=...` (keeps the deprecation baseline and cache reset; full guide in `tests/AGENTS.md`):\n```bash\nmake tests                            # whole suite\nmake tests ARGS=\"tests/Unit/Field/\"   # one directory\nmake tests ARGS=\"--filter=testFoo\"    # one test\n```\nA bare `./vendor/bin/simple-phpunit` run skips the deprecation baseline (`tests/baseline-ignore.txt`) and the cache reset.\n\n## Git and Pull Requests\n\n### Commit Messages\n- Use imperative mood: \"Add feature\" not \"Added feature\"\n- First line: concise summary (50 chars max)\n- Reference issues when applicable: \"Fix #123\"\n- No period at end of subject line\n\n### Branch Naming\n- Feature: `<short description>` (e.g., `add_new_field_type`)\n- Bug fix: `fix_<issue number>` (e.g., `fix_123`)\n- Use lowercase with underscores\n\n## PHP Code Standards\n\nphp-cs-fixer (`@Symfony` + `@Symfony:risky`) auto-formats most style — trailing commas, braces, strict comparisons, Yoda conditions, blank lines, quotes, etc. Run `make linter-cs-fixer` and let it handle formatting. The rules below are the conventions it does **not** enforce.\n\n### Conventions\n- PHP 8.2+ syntax with constructor property promotion\n- Don't add `declare(strict_types=1);` to PHP files\n- No service autowiring — configure explicitly in `config/services.php`\n- Use enums (`UpperCamelCase` case names) instead of constants for fixed sets of values\n- Prefer project constants (`Action::EDIT`, `EA::QUERY`) over hardcoded strings\n- Avoid `else`/`elseif` after `return`/`throw` — return/throw early instead\n- `return null;` for nullable, `return;` for void\n- Use `sprintf()` for exception messages with `get_debug_type()` for class names\n- Exception/error messages: start capital, end with a period, no backticks; concise but actionable (include class names, file paths)\n- Handle exceptions explicitly (no silent catches)\n- Comments: only for complex/unintuitive code, lowercase start, no period end; never as section separators (e.g. `// === Methods for dashboards ===`)\n- Config files in PHP format (`config/services.php`, `translations/*.php`)\n\n### Naming\n- Variables/methods: `camelCase`\n- Config/routes/Twig: `snake_case`\n- Constants: `SCREAMING_SNAKE_CASE`\n- Classes: `UpperCamelCase`\n- Abstract classes: `Abstract*` (except test cases)\n- Interfaces: `*Interface`, Traits: `*Trait`, Exceptions: `*Exception`\n- Most classes add a suffix showing their type:\n  `*Controller`, `*Configurator`, `*Context`, `*Dto`, `*Event`,\n  `*Field`, `*Filter`, `*Subscriber`, `*Type`, `*Test`\n- Templates/assets: `snake_case` (e.g., `detail_page.html.twig`)\n\n### Class Organization\n1. Properties before methods\n2. Constructor first, then public, protected, private methods in that order\n\n### PHPDoc\n- No single-line docblocks\n- No `@return` for void methods\n- Group annotations by type\n\n## Templates (Twig)\n\ntwig-cs-fixer handles formatting (`make linter-twig`). Conventions it doesn't enforce:\n\n- Modern HTML5 and Twig syntax\n- Icons: FontAwesome 6.x names\n- All user-facing text via `|trans` filter (no hardcoded strings)\n- Keep translation logic in templates, not PHP (use `TranslatableInterface`)\n- Reuse components from `templates/components/` when available — see `src/Twig/Component/AGENTS.md` before adding or changing a component\n- Accessibility: `aria-*` attributes, semantic tags, labels\n\n## JavaScript\n\nbiome handles formatting (`yarn ci`). Conventions it doesn't enforce:\n\n- ES6+ syntax\n- `camelCase` for variables and functions\n\n## CSS\n\n- Standard CSS only (no SCSS/LESS)\n- Don't use nested rules — keep selectors flat\n- `kebab-case` for class names\n- Bootstrap 5.3 classes and utilities\n- Logical properties: `margin-block-end` instead of `margin-bottom`\n- Responsive design required; use only these Bootstrap breakpoints:\n  - Medium (md): ≥768px\n  - Large (lg): ≥992px\n  - Extra large (xl): ≥1200px\n\n## Documentation (doc/)\n\n- Format: reStructuredText (.rst)\n- Heading symbols: `=`, `-`, `~`, `.`, `\"` for levels 1-5\n- Line length: 72-78 characters\n- Code blocks: prefer `::` over `.. code-block:: php`\n- Separate link text from URLs (no inline hyperlinks)\n- Show config in order: YAML, XML, PHP (or Attributes)\n- Code line limit: 85 chars (use `...` for folded code)\n- Include `use` statements for referenced classes\n- Bash lines prefixed with `$`\n- Root directory: `your-project/`\n- Vendor name: `Acme`\n- URLs: `example.com`, `example.org`, `example.net`\n- Trailing slashes for directories, leading dots for extensions\n\n### Writing Style\n- American English, second person (you)\n- Gender-neutral (they/them)\n- Use contractions (it's, don't, you're)\n- Avoid: \"just\", \"obviously\", \"easy\", \"simply\"\n- Realistic examples (no foo/bar placeholders)\n- Write for non-native English speakers: use simple vocabulary, avoid idioms, and complex sentence structures\n"},"files":{"AGENTS.md":"# AI Contribution Guidelines\n\nWelcome, AI assistant. Please follow these guidelines when contributing to this repository.\n\n## Project Overview\n\nEasyAdminBundle is a third-party Symfony bundle for creating admin backends. It provides CRUD controllers, dashboard management, and extensive field/filter configuration.\n\n**Requirements:** PHP 8.2+, Symfony 6.4/7.x/8.x, Doctrine ORM 2.20+ or 3.6+\n\n## General Rules\n\n- Language: American English for code, comments, commits, branches\n- Code quotes: wrap strings with single quotes in PHP, CSS, JavaScript\n- Text quotes: straight quotes only (`'` and `\"`, no typographic)\n- Security: prevent XSS, CSRF, injections, auth bypass, open redirects\n\n### Do Not Edit\n- `vendor/` - managed by Composer\n- `node_modules/` - managed by Yarn\n- `var/` - Symfony cache/logs\n- `public/bundles/` - generated assets\n- `composer.lock`, `yarn.lock` - update only via package manager commands\n\n## Architecture\n\n### Key Patterns\n- **Factory**: ActionFactory, EntityFactory, FieldFactory, FilterFactory, FormFactory\n- **Configurator Chain**: FieldConfiguratorInterface, FilterConfiguratorInterface\n- **Context Facade**: AdminContext wraps Request/Crud/Dashboard/I18n contexts\n- **DTO Layer**: Type-safe data transfer (ActionDto, EntityDto, FieldDto, etc.)\n- **Event Subscriber**: AdminRouterSubscriber, CrudAutocompleteSubscriber\n- **Registry**: AdminControllerRegistry, TemplateRegistry\n- **Provider**: AdminContextProvider, FieldProvider\n- **Typed Collections**: FieldCollection, ActionCollection, FilterCollection\n- **Argument Resolver**: AdminContextResolver, BatchActionDtoResolver\n\nDon't modify the public API in `Contracts/` lightly — it's a stable, versioned interface that third-party code depends on.\n\n### Design Principles\n- Never surface internal complexity to end users. Keep the public API small, simple, and consistent; push complexity down into internal classes (factories, configurators, DTOs), not onto the people configuring a backend.\n- Public APIs are stable contracts: prefer additive, backward-compatible changes and don't leak internal types or implementation details through them.\n\n### Backward Compatibility\nFollow [Symfony's BC policy](https://symfony.com/bc): never break public API — deprecate first, keep the old path working, remove only in the next major. Emit deprecations with `@trigger_deprecation('easycorp/easyadmin-bundle', '<version>', '<message>')`, naming the replacement and removal version.\n\n### Configuration Model\nUser-facing config uses fluent **builders** (`Config/`, `Field/`): static `new()` + chainable setters returning `self`. Each builder converts via `getAsDto()` into an immutable **DTO** (`Dto/`) for internal use. New configurable concepts follow this split — fluent builder for users, DTO internally; never expose a DTO as the config surface.\n\n### Main Namespace\n`EasyCorp\\Bundle\\EasyAdminBundle\\`\n\n## Commands\n\nThe `Makefile` is the source of truth for build/lint/test commands; its targets match what CI runs. Prefer them over hand-typed invocations. Run `make help` to list every target.\n\n### Setup\n```bash\nmake build          # composer update + yarn install (first-time setup)\ncomposer install    # PHP dependencies only\nyarn install        # JS dependencies only\n```\n\n### Before Creating a PR\nRun the full check suite (linters + tests, identical to CI):\n```bash\nmake checks-before-pr\n```\n\n### Pre-Commit Checklist\nRun the relevant target(s) for what you changed:\n\n| Changed          | Run                                                               |\n|------------------|-------------------------------------------------------------------|\n| PHP code         | `make linter-phpstan`, `make linter-cs-fixer`, `make tests`       |\n| JS / CSS         | `yarn ci`, then `make build-assets`                               |\n| Twig templates   | `make linter-twig`                                                |\n| Documentation    | `make linter-docs`                                                |\n| Translations     | keep all locales consistent; use English as placeholder if unsure |\n\nRun targeted tests with `make tests ARGS=...` (keeps the deprecation baseline and cache reset; full guide in `tests/AGENTS.md`):\n```bash\nmake tests                            # whole suite\nmake tests ARGS=\"tests/Unit/Field/\"   # one directory\nmake tests ARGS=\"--filter=testFoo\"    # one test\n```\nA bare `./vendor/bin/simple-phpunit` run skips the deprecation baseline (`tests/baseline-ignore.txt`) and the cache reset.\n\n## Git and Pull Requests\n\n### Commit Messages\n- Use imperative mood: \"Add feature\" not \"Added feature\"\n- First line: concise summary (50 chars max)\n- Reference issues when applicable: \"Fix #123\"\n- No period at end of subject line\n\n### Branch Naming\n- Feature: `<short description>` (e.g., `add_new_field_type`)\n- Bug fix: `fix_<issue number>` (e.g., `fix_123`)\n- Use lowercase with underscores\n\n## PHP Code Standards\n\nphp-cs-fixer (`@Symfony` + `@Symfony:risky`) auto-formats most style — trailing commas, braces, strict comparisons, Yoda conditions, blank lines, quotes, etc. Run `make linter-cs-fixer` and let it handle formatting. The rules below are the conventions it does **not** enforce.\n\n### Conventions\n- PHP 8.2+ syntax with constructor property promotion\n- Don't add `declare(strict_types=1);` to PHP files\n- No service autowiring — configure explicitly in `config/services.php`\n- Use enums (`UpperCamelCase` case names) instead of constants for fixed sets of values\n- Prefer project constants (`Action::EDIT`, `EA::QUERY`) over hardcoded strings\n- Avoid `else`/`elseif` after `return`/`throw` — return/throw early instead\n- `return null;` for nullable, `return;` for void\n- Use `sprintf()` for exception messages with `get_debug_type()` for class names\n- Exception/error messages: start capital, end with a period, no backticks; concise but actionable (include class names, file paths)\n- Handle exceptions explicitly (no silent catches)\n- Comments: only for complex/unintuitive code, lowercase start, no period end; never as section separators (e.g. `// === Methods for dashboards ===`)\n- Config files in PHP format (`config/services.php`, `translations/*.php`)\n\n### Naming\n- Variables/methods: `camelCase`\n- Config/routes/Twig: `snake_case`\n- Constants: `SCREAMING_SNAKE_CASE`\n- Classes: `UpperCamelCase`\n- Abstract classes: `Abstract*` (except test cases)\n- Interfaces: `*Interface`, Traits: `*Trait`, Exceptions: `*Exception`\n- Most classes add a suffix showing their type:\n  `*Controller`, `*Configurator`, `*Context`, `*Dto`, `*Event`,\n  `*Field`, `*Filter`, `*Subscriber`, `*Type`, `*Test`\n- Templates/assets: `snake_case` (e.g., `detail_page.html.twig`)\n\n### Class Organization\n1. Properties before methods\n2. Constructor first, then public, protected, private methods in that order\n\n### PHPDoc\n- No single-line docblocks\n- No `@return` for void methods\n- Group annotations by type\n\n## Templates (Twig)\n\ntwig-cs-fixer handles formatting (`make linter-twig`). Conventions it doesn't enforce:\n\n- Modern HTML5 and Twig syntax\n- Icons: FontAwesome 6.x names\n- All user-facing text via `|trans` filter (no hardcoded strings)\n- Keep translation logic in templates, not PHP (use `TranslatableInterface`)\n- Reuse components from `templates/components/` when available — see `src/Twig/Component/AGENTS.md` before adding or changing a component\n- Accessibility: `aria-*` attributes, semantic tags, labels\n\n## JavaScript\n\nbiome handles formatting (`yarn ci`). Conventions it doesn't enforce:\n\n- ES6+ syntax\n- `camelCase` for variables and functions\n\n## CSS\n\n- Standard CSS only (no SCSS/LESS)\n- Don't use nested rules — keep selectors flat\n- `kebab-case` for class names\n- Bootstrap 5.3 classes and utilities\n- Logical properties: `margin-block-end` instead of `margin-bottom`\n- Responsive design required; use only these Bootstrap breakpoints:\n  - Medium (md): ≥768px\n  - Large (lg): ≥992px\n  - Extra large (xl): ≥1200px\n\n## Documentation (doc/)\n\n- Format: reStructuredText (.rst)\n- Heading symbols: `=`, `-`, `~`, `.`, `\"` for levels 1-5\n- Line length: 72-78 characters\n- Code blocks: prefer `::` over `.. code-block:: php`\n- Separate link text from URLs (no inline hyperlinks)\n- Show config in order: YAML, XML, PHP (or Attributes)\n- Code line limit: 85 chars (use `...` for folded code)\n- Include `use` statements for referenced classes\n- Bash lines prefixed with `$`\n- Root directory: `your-project/`\n- Vendor name: `Acme`\n- URLs: `example.com`, `example.org`, `example.net`\n- Trailing slashes for directories, leading dots for extensions\n\n### Writing Style\n- American English, second person (you)\n- Gender-neutral (they/them)\n- Use contractions (it's, don't, you're)\n- Avoid: \"just\", \"obviously\", \"easy\", \"simply\"\n- Realistic examples (no foo/bar placeholders)\n- Write for non-native English speakers: use simple vocabulary, avoid idioms, and complex sentence structures\n"},"items":[{"name":"AGENTS.md","path":"AGENTS.md","title":"AGENTS.md","content":"# AI Contribution Guidelines\n\nWelcome, AI assistant. Please follow these guidelines when contributing to this repository.\n\n## Project Overview\n\nEasyAdminBundle is a third-party Symfony bundle for creating admin backends. It provides CRUD controllers, dashboard management, and extensive field/filter configuration.\n\n**Requirements:** PHP 8.2+, Symfony 6.4/7.x/8.x, Doctrine ORM 2.20+ or 3.6+\n\n## General Rules\n\n- Language: American English for code, comments, commits, branches\n- Code quotes: wrap strings with single quotes in PHP, CSS, JavaScript\n- Text quotes: straight quotes only (`'` and `\"`, no typographic)\n- Security: prevent XSS, CSRF, injections, auth bypass, open redirects\n\n### Do Not Edit\n- `vendor/` - managed by Composer\n- `node_modules/` - managed by Yarn\n- `var/` - Symfony cache/logs\n- `public/bundles/` - generated assets\n- `composer.lock`, `yarn.lock` - update only via package manager commands\n\n## Architecture\n\n### Key Patterns\n- **Factory**: ActionFactory, EntityFactory, FieldFactory, FilterFactory, FormFactory\n- **Configurator Chain**: FieldConfiguratorInterface, FilterConfiguratorInterface\n- **Context Facade**: AdminContext wraps Request/Crud/Dashboard/I18n contexts\n- **DTO Layer**: Type-safe data transfer (ActionDto, EntityDto, FieldDto, etc.)\n- **Event Subscriber**: AdminRouterSubscriber, CrudAutocompleteSubscriber\n- **Registry**: AdminControllerRegistry, TemplateRegistry\n- **Provider**: AdminContextProvider, FieldProvider\n- **Typed Collections**: FieldCollection, ActionCollection, FilterCollection\n- **Argument Resolver**: AdminContextResolver, BatchActionDtoResolver\n\nDon't modify the public API in `Contracts/` lightly — it's a stable, versioned interface that third-party code depends on.\n\n### Design Principles\n- Never surface internal complexity to end users. Keep the public API small, simple, and consistent; push complexity down into internal classes (factories, configurators, DTOs), not onto the people configuring a backend.\n- Public APIs are stable contracts: prefer additive, backward-compatible changes and don't leak internal types or implementation details through them.\n\n### Backward Compatibility\nFollow [Symfony's BC policy](https://symfony.com/bc): never break public API — deprecate first, keep the old path working, remove only in the next major. Emit deprecations with `@trigger_deprecation('easycorp/easyadmin-bundle', '<version>', '<message>')`, naming the replacement and removal version.\n\n### Configuration Model\nUser-facing config uses fluent **builders** (`Config/`, `Field/`): static `new()` + chainable setters returning `self`. Each builder converts via `getAsDto()` into an immutable **DTO** (`Dto/`) for internal use. New configurable concepts follow this split — fluent builder for users, DTO internally; never expose a DTO as the config surface.\n\n### Main Namespace\n`EasyCorp\\Bundle\\EasyAdminBundle\\`\n\n## Commands\n\nThe `Makefile` is the source of truth for build/lint/test commands; its targets match what CI runs. Prefer them over hand-typed invocations. Run `make help` to list every target.\n\n### Setup\n```bash\nmake build          # composer update + yarn install (first-time setup)\ncomposer install    # PHP dependencies only\nyarn install        # JS dependencies only\n```\n\n### Before Creating a PR\nRun the full check suite (linters + tests, identical to CI):\n```bash\nmake checks-before-pr\n```\n\n### Pre-Commit Checklist\nRun the relevant target(s) for what you changed:\n\n| Changed          | Run                                                               |\n|------------------|-------------------------------------------------------------------|\n| PHP code         | `make linter-phpstan`, `make linter-cs-fixer`, `make tests`       |\n| JS / CSS         | `yarn ci`, then `make build-assets`                               |\n| Twig templates   | `make linter-twig`                                                |\n| Documentation    | `make linter-docs`                                                |\n| Translations     | keep all locales consistent; use English as placeholder if unsure |\n\nRun targeted tests with `make tests ARGS=...` (keeps the deprecation baseline and cache reset; full guide in `tests/AGENTS.md`):\n```bash\nmake tests                            # whole suite\nmake tests ARGS=\"tests/Unit/Field/\"   # one directory\nmake tests ARGS=\"--filter=testFoo\"    # one test\n```\nA bare `./vendor/bin/simple-phpunit` run skips the deprecation baseline (`tests/baseline-ignore.txt`) and the cache reset.\n\n## Git and Pull Requests\n\n### Commit Messages\n- Use imperative mood: \"Add feature\" not \"Added feature\"\n- First line: concise summary (50 chars max)\n- Reference issues when applicable: \"Fix #123\"\n- No period at end of subject line\n\n### Branch Naming\n- Feature: `<short description>` (e.g., `add_new_field_type`)\n- Bug fix: `fix_<issue number>` (e.g., `fix_123`)\n- Use lowercase with underscores\n\n## PHP Code Standards\n\nphp-cs-fixer (`@Symfony` + `@Symfony:risky`) auto-formats most style — trailing commas, braces, strict comparisons, Yoda conditions, blank lines, quotes, etc. Run `make linter-cs-fixer` and let it handle formatting. The rules below are the conventions it does **not** enforce.\n\n### Conventions\n- PHP 8.2+ syntax with constructor property promotion\n- Don't add `declare(strict_types=1);` to PHP files\n- No service autowiring — configure explicitly in `config/services.php`\n- Use enums (`UpperCamelCase` case names) instead of constants for fixed sets of values\n- Prefer project constants (`Action::EDIT`, `EA::QUERY`) over hardcoded strings\n- Avoid `else`/`elseif` after `return`/`throw` — return/throw early instead\n- `return null;` for nullable, `return;` for void\n- Use `sprintf()` for exception messages with `get_debug_type()` for class names\n- Exception/error messages: start capital, end with a period, no backticks; concise but actionable (include class names, file paths)\n- Handle exceptions explicitly (no silent catches)\n- Comments: only for complex/unintuitive code, lowercase start, no period end; never as section separators (e.g. `// === Methods for dashboards ===`)\n- Config files in PHP format (`config/services.php`, `translations/*.php`)\n\n### Naming\n- Variables/methods: `camelCase`\n- Config/routes/Twig: `snake_case`\n- Constants: `SCREAMING_SNAKE_CASE`\n- Classes: `UpperCamelCase`\n- Abstract classes: `Abstract*` (except test cases)\n- Interfaces: `*Interface`, Traits: `*Trait`, Exceptions: `*Exception`\n- Most classes add a suffix showing their type:\n  `*Controller`, `*Configurator`, `*Context`, `*Dto`, `*Event`,\n  `*Field`, `*Filter`, `*Subscriber`, `*Type`, `*Test`\n- Templates/assets: `snake_case` (e.g., `detail_page.html.twig`)\n\n### Class Organization\n1. Properties before methods\n2. Constructor first, then public, protected, private methods in that order\n\n### PHPDoc\n- No single-line docblocks\n- No `@return` for void methods\n- Group annotations by type\n\n## Templates (Twig)\n\ntwig-cs-fixer handles formatting (`make linter-twig`). Conventions it doesn't enforce:\n\n- Modern HTML5 and Twig syntax\n- Icons: FontAwesome 6.x names\n- All user-facing text via `|trans` filter (no hardcoded strings)\n- Keep translation logic in templates, not PHP (use `TranslatableInterface`)\n- Reuse components from `templates/components/` when available — see `src/Twig/Component/AGENTS.md` before adding or changing a component\n- Accessibility: `aria-*` attributes, semantic tags, labels\n\n## JavaScript\n\nbiome handles formatting (`yarn ci`). Conventions it doesn't enforce:\n\n- ES6+ syntax\n- `camelCase` for variables and functions\n\n## CSS\n\n- Standard CSS only (no SCSS/LESS)\n- Don't use nested rules — keep selectors flat\n- `kebab-case` for class names\n- Bootstrap 5.3 classes and utilities\n- Logical properties: `margin-block-end` instead of `margin-bottom`\n- Responsive design required; use only these Bootstrap breakpoints:\n  - Medium (md): ≥768px\n  - Large (lg): ≥992px\n  - Extra large (xl): ≥1200px\n\n## Documentation (doc/)\n\n- Format: reStructuredText (.rst)\n- Heading symbols: `=`, `-`, `~`, `.`, `\"` for levels 1-5\n- Line length: 72-78 characters\n- Code blocks: prefer `::` over `.. code-block:: php`\n- Separate link text from URLs (no inline hyperlinks)\n- Show config in order: YAML, XML, PHP (or Attributes)\n- Code line limit: 85 chars (use `...` for folded code)\n- Include `use` statements for referenced classes\n- Bash lines prefixed with `$`\n- Root directory: `your-project/`\n- Vendor name: `Acme`\n- URLs: `example.com`, `example.org`, `example.net`\n- Trailing slashes for directories, leading dots for extensions\n\n### Writing Style\n- American English, second person (you)\n- Gender-neutral (they/them)\n- Use contractions (it's, don't, you're)\n- Avoid: \"just\", \"obviously\", \"easy\", \"simply\"\n- Realistic examples (no foo/bar placeholders)\n- Write for non-native English speakers: use simple vocabulary, avoid idioms, and complex sentence structures\n","category":"root","tokens":2220}]}