Allow modules to add operations to the Canvas content list

Overview

The operations in the Canvas content list (the pages panel in the sidebar) are a fixed set. ApiContentControllers::getEntityOperations() builds a hardcoded list (edit, delete, duplicate, set as homepage, publish, unpublish) with no alter hook or event, and the UI only renders links it knows by name: hasPermission() in PageList.tsx (and the same in Navigation.tsx) maps each operation to a fixed link relation and ignores any other link.

So a contrib module has no way to add an operation to a page in the Canvas UI, even though Drupal's own listings allow this through hook_entity_operation().

Use case

Canvas Translate adds a working translation UI for Canvas pages. In Drupal's pages listing it now adds "Edit translation" and a page-aware "Translate" operation (canvas_translate #3623308, !12). Inside Canvas, translators have to leave the editor, open the Translate extension and find the page again. A "Translate" operation on each page in the Canvas sidebar, linking to /canvas/app/canvas_translate/page/{id}, would remove that step.

The same applies to other modules that act on pages, e.g. TMGMT ("Request translation"), content moderation or clone modules.

Proposed resolution

  1. Backend: add hook_canvas_content_operation(EntityInterface $entity): array, the Canvas counterpart of hook_entity_operation(). Operations use the same shape (title, url, optional weight). ApiContentControllers::getEntityOperations() adds those the current user can access to the content links, sorted by weight.
  2. The content API exposes their labels in an optional linkLabels object (link relation type → label). Responses without module operations are unchanged.
  3. Frontend: the pages panel and the page navigation menu render these operations as links, between Canvas's own operations and "Delete page".

Remaining tasks

  • Implement the hook, with documentation in canvas.api.php.
  • Document linkLabels in openapi.yml.
  • Render module operations in both page menus.
  • Tests: kernel test for access and weight order; unit test for the UI helper.

API changes

New hook_canvas_content_operation(). New optional linkLabels property on content entities in the content API.

Related

  • #3591932: translation operations in the language dropdown, same gap for translation links.
Edited by Fons Vandamme