Trash
Provides soft-delete (trash bin) functionality for Drupal content entities, allowing deleted content to be restored rather than permanently removed.
trash
Install
composer require 'drupal/trash:^3.0'
Overview
The Trash module implements a "soft-delete" mechanism for Drupal content entities. When users delete content, instead of being permanently removed, entities are marked with a deletion timestamp and hidden from normal site operation. This allows content to be recovered from a centralized trash bin interface.
The module works by dynamically generating custom storage classes for enabled entity types that intercept the delete operation. When an entity is "deleted," it sets an internal timestamp field rather than actually removing the entity from the database. Trashed entities are hidden from entity queries, Views, and direct access through entity access hooks.
Trash supports automatic purging of old trashed content after a configurable time period, entity-type-specific handlers for special behaviors, and integration with Drupal's Workspaces module. The module provides both a web interface for managing trashed content and Drush commands for bulk operations.
Features
- Soft-delete functionality for any SQL-based content entity type
- Centralized trash bin admin interface at /admin/content/trash for viewing and managing deleted content
- Restore deleted entities to their original state with all data intact
- Permanently purge (delete) trashed entities when no longer needed
- Configurable auto-purge functionality to automatically delete trashed content after a specified time period (e.g., 30 days)
- Per-entity-type and per-bundle configuration for enabling trash functionality
- Dynamic storage class generation using Twig templates to intercept delete operations
- Entity query and Views query alteration to hide trashed entities from normal listings
- Entity access control to prevent unauthorized viewing of trashed content
- Workspace integration for handling trashed entities in workspace contexts
- Search API integration to exclude trashed entities from search indexes
- Path alias integration to automatically trash and restore associated URL aliases
- Menu link content handler for proper menu tree management
- Drush commands for bulk restore and purge operations
- Extensible trash handler system for entity-type-specific behaviors
- Three trash contexts: active (normal operation), inactive (working with trash), ignore (bypass trash)
Use Cases
Recovering accidentally deleted content
A content editor accidentally deletes an important article. Instead of being permanently lost, the article is moved to the trash bin. An administrator navigates to Administration > Content > Trash, finds the article in the list, and clicks 'Restore' to recover it with all its data, revisions, and URL aliases intact.
Scheduled content cleanup
A large news site generates hundreds of articles daily. Configure auto-purge to automatically delete trashed content after 30 days. Editors can delete outdated content knowing it will be available for recovery for a month, but won't accumulate indefinitely. Run 'drush trash:purge --all' for immediate bulk cleanup if needed.
Multi-entity type trash management
A site uses nodes, media entities, and custom content entities. Enable trash for all relevant entity types. The trash bin provides a unified interface with tabs for each entity type, allowing content managers to review and manage all deleted content from a single location.
Workspace-aware content deletion
Content is being edited in a workspace before going live. When content is trashed in the workspace, it remains visible in Live until the workspace is published. After publishing, the trash state is propagated to Live, and associated menu links are properly cleaned up.
Bulk operations via Drush
A developer needs to clean up test content from a staging environment. Use 'drush trash:purge node' to permanently delete all trashed nodes, or 'drush trash:restore --all' to recover all trashed content across all entity types after a problematic deployment.
Bundle-specific trash configuration
A site has Article and Page content types, but only wants trash functionality for Articles (pages are rarely deleted). Configure trash to enable only the Article bundle for nodes, leaving Pages to be deleted normally without going through trash.
Tips
- Use the '?in_trash=true' query parameter on entity canonical URLs to view trashed entities directly (requires appropriate permissions)
- The trash context can be temporarily changed using \Drupal::service('trash.manager')->executeInTrashContext('ignore', function() { ... }) for operations that need to access all entities regardless of trash status
- Trash creates new revisions when entities are trashed and restored, maintaining a complete revision history
- The 'Deleted by' column in the trash listing shows who deleted the entity (for revisionable entities)
- Consider enabling 'Compact overview' if you have many entity types enabled to simplify the trash interface
- Entity queries can use ->addMetaData('trash', 'inactive') to explicitly query trashed entities
- Custom trash handlers can be created by implementing TrashHandlerInterface and tagging the service with 'trash_handler'
Technical Details
Admin Pages 2
/admin/config/content/trash
Configure which entity types can use the trash bin and set up automatic purging of old trashed content.
/admin/content/trash
View and manage all trashed (soft-deleted) content entities. Lists deleted items with options to restore or permanently purge them.
Permissions 5
Hooks 8
hook_entity_pre_trash_delete
Act before an entity is soft-deleted (moved to trash).
hook_ENTITY_TYPE_pre_trash_delete
Act before a specific entity type is soft-deleted.
hook_entity_trash_delete
Respond after an entity has been soft-deleted (moved to trash).
hook_ENTITY_TYPE_trash_delete
Respond after a specific entity type has been soft-deleted.
hook_entity_pre_trash_restore
Act before an entity is restored from trash.
hook_ENTITY_TYPE_pre_trash_restore
Act before a specific entity type is restored from trash.
hook_entity_trash_restore
Respond after an entity has been restored from trash.
hook_ENTITY_TYPE_trash_restore
Respond after a specific entity type has been restored from trash.
Drush Commands 2
drush trash:restore [entity_type_id] [entity_ids]
Restores trashed entities from the trash bin back to active status.
drush trash:purge [entity_type_id] [entity_ids]
Permanently deletes trashed entities from the system.
Troubleshooting 6
Verify that trash is enabled for the specific entity type and bundle in the Trash settings (/admin/config/content/trash). Also check that the entity type uses SQL-based storage.
Ensure Views are not explicitly querying the 'deleted' field. The Trash module automatically alters queries, but custom conditions on the deleted field will bypass this. Check if the trash context has been set to 'ignore' somewhere in custom code.
For path aliases, this occurs when another alias with the same path already exists. Delete or modify the conflicting alias first. For other entity types, check for entity-specific validation in trash handlers.
Verify that cron is running properly and that auto-purge is enabled in settings. Check that the auto_purge.after value is a valid time expression (e.g., '30 days'). Review Drupal logs for any queue processing errors.
If you have a custom storage class, ensure it's compatible with the TrashStorageTrait methods. Trash dynamically generates classes that extend your storage class. Consider extending from Trash's generated class instead.
Check that PHP storage is writable. Trash uses PhpStorageFactory to save generated classes. Clear caches and check file permissions on the generated PHP storage directory.
Security Notes 4
- The 'view deleted entities' permission should be granted carefully as it allows viewing content that was intentionally removed from public access
- The 'purge' permission permanently deletes data with no recovery option - assign only to trusted roles
- Auto-purge runs via cron and permanently deletes data - ensure the retention period is appropriate for your compliance requirements
- Trashed entities are excluded from search results and normal queries, but the data remains in the database until purged