.../Drupal/Core/Render/Element/StatusMessages.php | 23 ++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/core/lib/Drupal/Core/Render/Element/StatusMessages.php b/core/lib/Drupal/Core/Render/Element/StatusMessages.php index c2fa305..485718d 100644 --- a/core/lib/Drupal/Core/Render/Element/StatusMessages.php +++ b/core/lib/Drupal/Core/Render/Element/StatusMessages.php @@ -37,6 +37,15 @@ public function getInfo() { /** * #pre_render callback to generate a placeholder. * + * Ensures the same token is used for all instances, hence resulting in the + * same placeholder for all places rendering the status messages for this + * request (e.g. in multiple blocks). This ensures we can put the rendered + * messages in all placeholders in one go. + * Also ensures the same context key is used for the #post_render_cache + * property, this ensures that if status messages are rendered multiple times, + * their individual (but identical!) #post_render_cache properties are merged, + * ensuring the callback is only invoked once. + * * @see ::renderMessages() * * @param array $element @@ -49,18 +58,24 @@ public static function generatePlaceholder(array $element) { $plugin_id = 'status_messages'; $callback = get_class() . '::renderMessages'; + try { + $hash_salt = Settings::getHashSalt(); + } + catch (\RuntimeException $e) { + // Status messages are also shown during the installer, at which time no + // hash salt is defined yet. + $hash_salt = Crypt::randomBytes(8); + } + $key = $plugin_id . $element['#display']; $context = [ 'display' => $element['#display'], + 'placeholder_token' => Crypt::hmacBase64($key, $hash_salt), ]; $element['messages_placeholder'] = [ '#pre_render_cache' => [ $callback => $context, ], '#create_placeholder' => TRUE, - // Make it uncacheable. - '#cache' => [ - 'max-age' => 0, - ], ]; return $element;