Issue #3583742: Add one-click Check Empathy field widget action and content-moderation gating
Summary
Closes #3583742
Adds a one-click Check Empathy button to text-field widgets and an optional content-moderation publish gate, so content editors can assess empathy quality without leaving the content form — and, optionally, block low-empathy content from being published.
Delivered as an optional submodule (ai_empathy_field_action) so the Field Widget Actions dependency never touches the main module.
What's included
Check Empathy field widget action (src/Plugin/FieldWidgetAction/CheckEmpathyAction.php)
#[FieldWidgetAction]plugin attached to text widgets (string_textfield,string_textarea,text_textfield,text_textarea,text_textarea_with_summary) / field types (string,string_long,text,text_long,text_with_summary).- On click, scores the field's current text via the existing scenario-less
EmpathyScoringService::scoreResponseGeneral()and shows empathy + explanation-quality scores as colour-coded badges (green / orange / red) in a modal. Nothing is written to the field. - Badge colours are driven by the global
empathy_alignment_thresholdin AI Empathy settings.
Content-moderation publish gate (src/Service/EmpathyModerationGate.php, src/Hook/AiEmpathyFieldActionHooks.php)
- A
hook_form_altervalidation handler blocks transitions to a published moderation state when the empathy score is below threshold. - Activates only when core
content_moderationis installed (moduleExistsguard + optional@?content_moderation.moderation_informationinjection) and the gate is enabled in config. - Fails open: if scoring is unavailable, publishing is never blocked.
Supporting pieces: settings form (FieldActionSettingsForm) + route/menu link, theme hook + Twig template + badge CSS, config schema/defaults, submodule README.md, and an "Optional integrations" note in the main README.md.
Decisions
- Widget action and moderation gating shipped together in one submodule.
- Badge colours and the publish gate reuse the existing global
empathy_alignment_threshold(no new threshold config).
Handling of known field_widget_actions issues
- #3567974 (required-field validation on button click) — the base class's ajax button sets
suppress_required_fields_validation, so the check works on incomplete forms. - #3578204 (checkbox/radio widgets unsupported) — we target text widgets only.
- Pinned to
^1.3(stable 1.3.0), which includes the suggestion.js event fix (#3578820); deprecatedmultipleattribute param not used.
Testing
Automated (all passing):
- Unit —
badgeState()threshold mapping; fullEmpathyModerationGatedecision matrix (disabled, module absent, below/at threshold, fail-open, non-published state). - Kernel —
check_empathyplugin discovery with correct widget/field types; result theme hook registered. - Functional — settings form access control + save.
Manual:
composer require drupal/field_widget_actions:^1.3; enableai_empathy,ai_empathy_field_action,field_widget_actions,field_ui; set a scoring provider/model in AI Empathy settings.- Manage form display on a content type → enable Check Empathy on a text field. Edit content, click the button, confirm the modal shows scores + colour badges.
- Enable
content_moderationon the type, enable the gate at AI Empathy → Field Action and list the field(s); confirm publishing low-empathy content is blocked and high-empathy content publishes.
This submodule builds on Field Widget Actions and requires ^1.3:
- #3568300** — Create a stable version** (fixed, 1.3.0): provides the stable release this submodule depends on, rather than pinning a dev branch.
- #3567974** — Action-buttons cause required-field validation errors** (open): accounted for — our action uses the ajax-callback path, so the base class's
suppress_required_fields_validationlets the button work on incomplete forms. - #3578204** — Support for checkboxes/radio buttons** (open): the reason the Check Empathy action is scoped to text widgets only.