Problem/Motivation
Reusable block support was deprecated in 9.1.2 and reintroduced as deprecated-only in 9.1.3 (#3587714: Revert Reusable Block Support Removal Until Later Release) to provide a migration window. The original removal (#3516918: Remove Reusable Block Support) committed to migration tooling ("needs to be explored and implemented") but none was delivered.
Sites with existing reusable block content need an automated path for converting placements to inline equivalents before the code is permanently removed. Without tooling, operators must manually recreate each reusable block placement in Layout Builder — a process that is error-prone and does not scale for sites with many placements.
Steps to reproduce
- Install Patternkit 9.1.3 with
enable_reusable_blocks: true. - Create reusable Patternkit block entities and place them in Layout Builder layouts.
- Upgrade to 9.2.0.
- Observe: reusable block placements render as Drupal's
brokenblock. No automated conversion path exists.
Proposed resolution
Provide a Drush migration command and re-execute the reusable block code removal for the 9.2.0 release.
1. Migration command
drush patternkit:migrate:reusable
Converts reusable block placements (UUID-based derivatives) to inline pattern-based equivalents using a targeted identification strategy.
Constraint: Full database scans of all Layout Builder layouts are not feasible on large sites. The command uses an entity-first approach:
- Query
patternkit_blockentities for reusable entries (byreusablecolumn or UUID cross-reference against known pattern derivative IDs). - Use entity UUIDs as targeted lookup keys against Layout Builder section storage (
layout_builder__layoutfield tables) andblock.block.*config entities. - Convert matched placements without loading every entity with layout overrides.
This reduces significantly reduces the scope of what needs to be loaded and traversed for the process.
2. Dry-run mode
--dry-run flag reports what would be migrated without making changes.
3. Code removal
Re-execute the reusable block code removal (restoring the scope of commit dff037f against the 9.2.0 branch state).
4. Update hooks
patternkit_update_10309drops thereusablecolumn (restored from no-op status in 9.1.3).- Consider a new update hook that documents the migration step or provides a pre-update requirements check.
5. Change record
Publish a change record for the 9.2.0 removal confirming migration tooling availability and documenting the upgrade path.
Remaining tasks
- Implement
drush patternkit:migrate:reusablewith targeted identification. - Add
--dry-runaudit mode. - Handle config entity migration (
block.block.*). - Handle translations and define revision policy.
- Re-execute code removal.
- Restore
patternkit_update_10309. - Publish 9.2.0 change record.
- Update upgrade documentation.
- Review and test the merge request.
- CI validation.
User interface changes
The reusable block checkbox, deprecation warnings, and reusable block administration pages are removed. Layouts that previously displayed reusable blocks will show inline equivalents after migration, or Drupal's broken block placeholder if migration was not run.
API changes
- The
PatternkitBlockderivative loader no longer produces UUID-based derivative definitions for reusable block entities. ReusableBlockHooksand associated route subscriber are removed.- The
enable_reusable_blocksservice parameter is removed. - A new Drush command
patternkit:migrate:reusableis added (available before the removal to allow pre-upgrade migration).
Data model changes
The reusable column is dropped from the patternkit_block entity base table via patternkit_update_10309. Existing patternkit_block entity rows (with pattern_id, data, and revision fields) are preserved; orphaned entities can optionally be cleaned up after migration.
Release notes snippet
Reusable block support has been removed in Patternkit 9.2.0. Sites that used reusable Patternkit blocks should run drush patternkit:migrate:reusable before upgrading to convert reusable block placements to inline equivalents. A --dry-run flag is available to preview changes before applying them. See the change record for detailed upgrade instructions.
Comments
Comment #2
sluceroMR !190 (#3587714) is open for 9.1.3 and establishes the migration window. The following summarizes what this issue will need to clean up and implement for 9.2.0.
Update hook number
The next available hook is
patternkit_update_10311. Hooks 10308–10310 are used by the 9.1.3 migration window.Required guard pattern for the removal hook
patternkit_update_10310may restore thereusablecolumn on sites that had it dropped prematurely. The 9.2.0 removal hook must guard against a missing field definition to handle all upgrade paths:Files to delete
src/Hook/ReusableBlockHooks.phpsrc/EventSubscriber/PatternkitReusableBlocksRouteSubscriber.phpsrc/Plugin/Block/PatternkitBlock.phpsrc/Plugin/Derivative/PatternkitBlock.phptests/src/Functional/ReusableBlocksEnabledTest.phptests/src/Functional/ReusableBlocksDisabledTest.phptests/src/Kernel/ReusableBlockHooksRequirementsTest.phptests/src/Kernel/ReusableBlocksUpdateHooksTest.php(10308–10310 tests are no longer relevant)Files to modify
patternkit.module: removepatternkit_entity_type_alter,patternkit_local_tasks_alter, andpatternkit_menu_local_actions_alterhook bridges; remove theReusableBlockHooksdelegate frompatternkit_contextual_links_alterpatternkit.install: removepatternkit_requirements()patternkit.services.yml: removeenable_reusable_blocksparameter andpatternkit.subscriber.route.reusable_blocksservicepatternkit.links.action.yml,patternkit.links.contextual.yml,patternkit.links.task.yml,patternkit.routing.yml: remove all reusable block routes and links (each marked@todo Remove … #3587730)src/PatternkitEnvironment.php: removeFEATURE_ENABLE_REUSABLE_BLOCKSconstantsrc/Entity/PatternkitBlock.php: removereusablebase field definition and@seereferences toReusableBlockHooksandPatternkitReusableBlocksRouteSubscriberphpstan-baseline.neon: remove all suppression entries added for the deprecated reusable block classes. TheglobalDrupalDependencyInjection.useDependencyInjectionentry forsrc/FormElement/PatternkitJson.phpis unrelated and should be retained.Migration tooling
patternkit_update_10308(9.1.3) logs a warning for each placed config block whose plugin could not be resolved, rather than halting. Sites that have accumulated unresolvable plugin references will have these warnings in their logs after the 9.1.3 upgrade. The migration tooling for this issue should surface these cases and help operators remove or convert reusable block entities before upgrading.Minimum viable scope: a Drush command that lists all reusable block entities with their placement status. A conversion path (reusable → standard block content) would reduce data loss risk but scope can be confirmed during design.
Change record
A 9.2.0 change record should be authored at release time. After it is published, update node/3517440 with a link to it.