Publishing a canvas_page via auto-save API drops all non-default-language translations
## Problem When a `canvas_page` is published using the Canvas auto-save API (`ApiAutoSaveController`), existing non-default-language translations are lost. The controller deserializes the entity from auto-save JSON, which only contains the default language version. It then saves a new revision without copying translations from the previous revision, effectively deleting all non-default translations. ## Why other entities are not affected Entities edited via the standard Drupal form layer go through `ContentTranslationHandler`, which automatically copies translations from the previous revision before saving. Because Canvas uses a custom REST-style auto-save API that bypasses the form layer entirely, this automatic translation copying never happens. ## Steps to reproduce 1. Create a canvas_page with a non-default-language translation (e.g., Spanish) 2. Edit the page in the Canvas editor (auto-save runs in background) 3. Click Publish in the Canvas UI (triggers ApiAutoSaveController) 4. Check the published entity **Expected**: All translations from the previous revision are preserved **Actual**: All non-default-language translations are gone ## Root cause In `ApiAutoSaveController::publishEntity()` (approx. line 367), the entity is deserialized from auto-save data. The deserialized entity only contains the default language. No code copies existing translations from the previous revision before saving, so they are silently dropped. ## Suggested fix Before saving the deserialized entity, load the unchanged original and copy any translation langcodes not present on the deserialized entity: ```php if ($entity instanceof TranslatableInterface) { $original = $this->entityTypeManager->getStorage($entity->getEntityTypeId()) ->loadUnchanged($entity->id()); if ($original instanceof TranslatableInterface) { foreach ($original->getTranslationLanguages(FALSE) as $langcode => $language) { if (!$entity->hasTranslation($langcode)) { $entity->addTranslation($langcode, $original->getTranslation($langcode)->toArray()); } } } } ``` We can test this fix my creating a test like `\Drupal\canvas\Controller\ApiAutoSaveController::post` where we also update a Page that we have also programmatically created a translation for ## Possible follow-ups A related problem exists for JSON:API saves — programmatic saves do not automatically preserve or flag translations. That broader issue is better addressed in Drupal core rather than in Canvas.
issue