Problem/Motivation

When blocks are created using existing patterns on a site, the pattern's schema and template are cached in the database for use with that block moving forward until it is updated to use a new pattern version. This process helps to maintain stability in the content by preventing breakage to existing content when a pattern may be updated later.

This also introduces an issue, however, when we consider the types of changes that may be introduced when a pattern is updated. If new fields are added to a pattern's schema in new versions, updates to existing content face no issues. If instead, an existing field is changed that may have content in existing blocks, the content saved for those blocks would also need to be changed to match the new schema structure. Unfortunately, there is no easy way to do this at this time.

This issue proposes the introduction of event dispatching during the pattern update process to allow event subscribers to react to, and alter the content of an affected block. If this process is effectively consolidated to always fire when a block's pattern instance is updated, then the same operation for altering a specific pattern's content during updates could be supported regardless how the block's update process was triggered whether that be from the block edit form or a Drush command.

See the related change record for an example implementation.

Proposed resolution

  • Unify the pattern update operation into the block plugin
  • Implement a pattern update event supporting pattern content alteration
  • Dispatch and apply changes from the event during pattern updates

Remaining tasks

  • Code review
  • Testing
  • Provide example event subscriber

User interface changes

None

API changes

  • Additional "--pattern" filter may be provided to drush patternkit:libUpdate to limit updates to only a single pattern ID.
    • Example: drush pklu --pattern='@patternkit/atoms/example/src/example'
  • New getData() method added to the Entity\PatternkitBlock class which returns the block entity's content decoded into an array.
  • New PatternUpdateEvent named patternkit.pattern_update is dispatched when a block plugin's pattern entity is being updated.
  • Plugin\Block\PatternkitBlock now exposes an updatePattern() method for updating the block's pattern entity to the latest or a provided base pattern version. This method is responsible for dispatching the new pattern update event.
  • UpdateHelper::updateBlockComponents() now expects an array of filter parameters instead of only the library name to filter by.
  • UpdateHelper::updateBlockComponentPattern() no longer accepts a library name parameter for filtering. All filtering of components should be performed beforehand using the new UpdateHelper::filterComponent() method.

Data model changes

None

CommentFileSizeAuthor
#8 DAT-3926_Retest.odt1007.08 KBminsharm

Issue fork patternkit-3360832

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

slucero created an issue. See original summary.

slucero’s picture

Issue summary: View changes
slucero’s picture

Issue summary: View changes

slucero’s picture

Issue summary: View changes
Status: Active » Needs review
slucero’s picture

Issue summary: View changes
slucero’s picture

I've uploaded an additional event subscriber within the patternkit_test submodule. This event subscriber tests during the update process to alter the "text" field value of the "@patternkit/atoms/example/src/example" pattern and append " (Altered)" to the existing value. WIth this enabled, manual testing to confirm the functionality should be easier.

Since this module exists within the tests folder, the following will need to be added to the site's settings.local.php file:

$settings['extension_discovery_scan_tests'] = TRUE;

After adding this, a cache clear should make the module available:

drush en -y patternkit_test

Now updating any patternkit block using the "@patternkit/atoms/example/src/example" pattern should also update the "text" field value as well.

minsharm’s picture

StatusFileSize
new1007.08 KB

Tested the flow with an event subscriber which has been added by Stephen within the patternkit_test submodule. This event subscriber tests during the update process to alter the "text" field value of the "@patternkit/atoms/example/src/example" pattern and append " (Altered)" to the existing value.

Steps to retest -

1) Add the following line to the site's settings.local.php file:

$settings['extension_discovery_scan_tests'] = TRUE;

2) Enable the module using the below command:

drush en -y patternkit_test

3) Add "[Patternkit] Example" block and run the below query to force it to show as having an update available.

UPDATE pattern_revision
SET hash = 'ALTERED', version = 'OLD'
WHERE revision IN (
SELECT revision
FROM pattern
);

3) Now update the above existing PK block using the "@patternkit/atoms/example/src/example" pattern.

Result : Updating the pattern has triggered the event and alter the content of the "Text" field.

Screenshots attached

slucero’s picture

Status: Needs review » Reviewed & tested by the community

Since this has passed testing by a couple of people already, I'm going to go ahead and mark it as reviewed and merged in. I'd like to follow it up later with a supplementary issue to continue improving the developer experience in working with this. Example improvements could include:

  • Add tools to ease debugging update failures
    • Improved logging of validation failures with more context
    • Option to bypass validation during content assignment? (Thinking about incremental updates spread across multiple event subscribers that may not validate on their own.)
  • Add a base class for event subscribers to extend from
    • Define a static run priority for the event that could be overridden on child implementations
    • Implement the getSubscribedEvents() function such that inheritors don't have to uniquely define it
    • Add helper methods for common interactions with the event object
    • Separate out methods for defining logic to determine if a specific event subscriber should be applied (test patterns and content matching rules)
    • Add a typical method for applying transformations to content that could be applied at the top level pattern or any depth in the case of nested patterns
  • Add documentation and examples for working with updates within nested patterns

slucero credited krisahil.

slucero’s picture

  • slucero committed 5fc4f326 on 9.1.x
    Issue #3360832 by slucero, minsharm, krisahil: Enable Altering Content...
slucero’s picture

Status: Reviewed & tested by the community » Fixed

  • slucero committed 5fc4f326 on 3371647-support-for-twig
    Issue #3360832 by slucero, minsharm, krisahil: Enable Altering Content...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.