Skip to content

Annotations UI

Submodule of Annotations. Provides the annotation editing UI for writing and managing annotation content entities across all opted-in annotation_target targets.


Requirements

  • annotations (core Annotations module)

Installation

ddev drush en annotations_ui
ddev drush cr

This module is optional. Sites where annotation content ships via default_content in a recipe can leave annotations_ui disabled, or enable it only when editing is needed.


What it does

Landing page — /admin/content/annotations

Lists all opted-in annotation_target entities grouped by entity type. Each target row has a dropbutton with three operations:

  • Add new annotations — shows missing annotation slots
  • Edit existing annotations — embeds the annotations_target view for that target
  • Delete annotations — bulk-delete all annotations for the target

Per-target collection page — /admin/content/annotations/{target}

Embeds the annotations_target view, listing all existing annotation entities for the target with Edit and Delete operation links per row.

Add-new page — /admin/content/annotations/{target}/add

Shows a table of annotation slots that are not yet filled. Each row is a field (or the target overview) with Add buttons for each missing annotation type. The first row is always Overview — the bundle-level slot covering the target as a whole. When all slots are filled, a link to the edit view is shown instead.

For fieldable targets, an optional collapsible "Target details" panel lists all annotatable fields with their scope status.

Annotation edit form — /admin/content/annotations/value/{annotation}/edit

Full entity form for a single annotation. When annotations_workflows is installed, the moderation control widget is injected automatically. Language tabs appear when content translation is enabled for annotations.


Fieldable annotation entities

annotation is a fully fieldable Drupal content entity. The standard annotation fields (target_id, field_name, type_id, value, uid, changed) are base fields, but site-builders can attach arbitrary field config to any annotation type bundle.


Revision history

Full revision history is available at /admin/content/annotations/value/{annotation}/revisions. Stock Drupal controllers handle revision view, revert, and delete.

When the diff module is present, a "Compare with previous" operation link is added to each row in the revision history table.


Multilingual / translation

annotation is always multilingual-ready — the four-table schema is created on install regardless of whether content_translation is installed.

To enable annotation translation on a multilingual site, go to /admin/config/regional/content-language and enable translations for Annotation. No extra module is required beyond content_translation.


Permissions

Permission Notes
edit any annotation Supersedes all per-type edit permissions.
delete any annotation Supersedes all per-type delete permissions. Gates bulk-delete routes.
access annotation collection Read access to /admin/content/annotations, the annotations list view, and the add-type picker. Grant to any role that can edit annotations.
edit {type} annotations Per annotation type (e.g. edit editorial annotations). Covers write and create. Generated dynamically.
delete {type} annotations Per annotation type (e.g. delete editorial annotations). Generated dynamically.
consume {type} annotations Controls which annotation types appear in context output. Used by ContextAssembler in annotations_context.
view annotation revisions View the revision history and individual revision pages. Does not grant revert or delete.

Dynamic permissions require a cache rebuild after new annotation types are created.

Typical role setup

Role Permissions
Drupal admin administer annotations covers everything
Content editor access annotation collection + edit editorial annotations
Developer access annotation collection + edit technical annotations
Project manager access annotation collection only (read-only listing)

See DEVELOPING.md for the overview slot storage sentinel, translation internals, revision route generation, and the content_moderation state cleanup workaround.