function BubbleableMetadata::mergeAttachments
Same name in other branches
- 9 core/lib/Drupal/Core/Render/BubbleableMetadata.php \Drupal\Core\Render\BubbleableMetadata::mergeAttachments()
- 8.9.x core/lib/Drupal/Core/Render/BubbleableMetadata.php \Drupal\Core\Render\BubbleableMetadata::mergeAttachments()
- 10 core/lib/Drupal/Core/Render/BubbleableMetadata.php \Drupal\Core\Render\BubbleableMetadata::mergeAttachments()
Merges two attachments arrays (which live under the '#attached' key).
The values under the 'drupalSettings' key are merged in a special way, to match the behavior of:
jQuery.extend(true, {}, $settings_items[0], $settings_items[1], ...)
This means integer indices are preserved just like string indices are, rather than re-indexed as is common in PHP array merging.
Example:
function module1_page_attachments(&$page) {
$page['a']['#attached']['drupalSettings']['foo'] = [
'a',
'b',
'c',
];
}
function module2_page_attachments(&$page) {
$page['#attached']['drupalSettings']['foo'] = [
'd',
];
}
// When the page is rendered after the above code, and the browser runs the
// resulting <SCRIPT> tags, the value of drupalSettings.foo is
// ['d', 'b', 'c'], not ['a', 'b', 'c', 'd'].
By following jQuery.extend() merge logic rather than common PHP array merge logic, the following are ensured:
- Attaching JavaScript settings is idempotent: attaching the same settings twice does not change the output sent to the browser.
- If pieces of the page are rendered in separate PHP requests and the returned settings are merged by JavaScript, the resulting settings are the same as if rendered in one PHP request and merged by PHP.
Parameters
array $a: An attachments array.
array $b: Another attachments array.
Return value
array The merged attachments array.
11 calls to BubbleableMetadata::mergeAttachments()
- AjaxResponse::addCommand in core/
lib/ Drupal/ Core/ Ajax/ AjaxResponse.php - Add an AJAX command to the response.
- AttachedRenderingBlock::build in core/
modules/ system/ tests/ modules/ render_attached_test/ src/ Plugin/ Block/ AttachedRenderingBlock.php - Builds and returns the renderable array for this block plugin.
- AttachmentsTrait::addAttachments in core/
lib/ Drupal/ Core/ Render/ AttachmentsTrait.php - BubbleableMetadata::merge in core/
lib/ Drupal/ Core/ Render/ BubbleableMetadata.php - Creates a new bubbleable metadata object by merging this one with another.
- BubbleableMetadataTest::testMergeAttachmentsHtmlHeadLinkMerging in core/
tests/ Drupal/ Tests/ Core/ Render/ BubbleableMetadataTest.php - Tests html_head_link asset merging.
File
-
core/
lib/ Drupal/ Core/ Render/ BubbleableMetadata.php, line 147
Class
- BubbleableMetadata
- Value object used for bubbleable rendering metadata.
Namespace
Drupal\Core\RenderCode
public static function mergeAttachments(array $a, array $b) {
// If both #attached arrays contain drupalSettings, then merge them
// correctly; adding the same settings multiple times needs to be
// idempotent.
if (!empty($a['drupalSettings']) && !empty($b['drupalSettings'])) {
$drupalSettings = NestedArray::mergeDeepArray([
$a['drupalSettings'],
$b['drupalSettings'],
], TRUE);
// No need for re-merging them.
unset($a['drupalSettings']);
unset($b['drupalSettings']);
}
// Optimize merging of placeholders: no need for deep merging.
if (!empty($a['placeholders']) && !empty($b['placeholders'])) {
$placeholders = $a['placeholders'] + $b['placeholders'];
// No need for re-merging them.
unset($a['placeholders']);
unset($b['placeholders']);
}
// Apply the normal merge.
$a = array_merge_recursive($a, $b);
if (isset($drupalSettings)) {
// Save the custom merge for the drupalSettings.
$a['drupalSettings'] = $drupalSettings;
}
if (isset($placeholders)) {
// Save the custom merge for the placeholders.
$a['placeholders'] = $placeholders;
}
return $a;
}
Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.