class BubbleableMetadata
Same name in other branches
- 8.9.x core/lib/Drupal/Core/Render/BubbleableMetadata.php \Drupal\Core\Render\BubbleableMetadata
- 10 core/lib/Drupal/Core/Render/BubbleableMetadata.php \Drupal\Core\Render\BubbleableMetadata
- 11.x core/lib/Drupal/Core/Render/BubbleableMetadata.php \Drupal\Core\Render\BubbleableMetadata
Value object used for bubbleable rendering metadata.
Hierarchy
- class \Drupal\Core\Cache\CacheableMetadata implements \Drupal\Core\Cache\RefinableCacheableDependencyInterface uses \Drupal\Core\Cache\RefinableCacheableDependencyTrait
- class \Drupal\Core\Render\BubbleableMetadata extends \Drupal\Core\Cache\CacheableMetadata implements \Drupal\Core\Render\AttachmentsInterface uses \Drupal\Core\Render\AttachmentsTrait
Expanded class hierarchy of BubbleableMetadata
See also
\Drupal\Core\Render\RendererInterface::render()
67 files declare their use of BubbleableMetadata
- Actions.php in core/
lib/ Drupal/ Core/ Render/ Element/ Actions.php - AjaxResponse.php in core/
lib/ Drupal/ Core/ Ajax/ AjaxResponse.php - AliasPathProcessor.php in core/
modules/ path_alias/ src/ PathProcessor/ AliasPathProcessor.php - AliasPathProcessorTest.php in core/
modules/ path_alias/ tests/ src/ Unit/ PathProcessor/ AliasPathProcessorTest.php - AttachedRenderingBlock.php in core/
modules/ system/ tests/ modules/ render_attached_test/ src/ Plugin/ Block/ AttachedRenderingBlock.php
File
-
core/
lib/ Drupal/ Core/ Render/ BubbleableMetadata.php, line 13
Namespace
Drupal\Core\RenderView source
class BubbleableMetadata extends CacheableMetadata implements AttachmentsInterface {
use AttachmentsTrait;
/**
* Creates a new bubbleable metadata object by merging this one with another.
*
* @param \Drupal\Core\Cache\CacheableMetadata $other
* The other bubbleable metadata object.
*
* @return static
* A new bubbleable metadata object, with the merged data.
*/
public function merge(CacheableMetadata $other) {
$result = parent::merge($other);
// This is called many times per request, so avoid merging unless absolutely
// necessary.
if ($other instanceof BubbleableMetadata) {
if (empty($this->attachments)) {
$result->attachments = $other->attachments;
}
elseif (empty($other->attachments)) {
$result->attachments = $this->attachments;
}
else {
$result->attachments = static::mergeAttachments($this->attachments, $other->attachments);
}
}
return $result;
}
/**
* Applies the values of this bubbleable metadata object to a render array.
*
* @param array &$build
* A render array.
*/
public function applyTo(array &$build) {
parent::applyTo($build);
$build['#attached'] = $this->attachments;
}
/**
* Creates a bubbleable metadata object with values taken from a render array.
*
* @param array $build
* A render array.
*
* @return static
*/
public static function createFromRenderArray(array $build) {
$meta = parent::createFromRenderArray($build);
$meta->attachments = isset($build['#attached']) ? $build['#attached'] : [];
return $meta;
}
/**
* Creates a bubbleable metadata object from a depended object.
*
* @param \Drupal\Core\Cache\CacheableDependencyInterface|mixed $object
* The object whose cacheability metadata to retrieve. If it implements
* CacheableDependencyInterface, its cacheability metadata will be used,
* otherwise, the passed in object must be assumed to be uncacheable, so
* max-age 0 is set.
*
* @return static
*/
public static function createFromObject($object) {
$meta = parent::createFromObject($object);
if ($object instanceof AttachmentsInterface) {
$meta->attachments = $object->getAttachments();
}
return $meta;
}
/**
* {@inheritdoc}
*/
public function addCacheableDependency($other_object) {
parent::addCacheableDependency($other_object);
if ($other_object instanceof AttachmentsInterface) {
$this->addAttachments($other_object->getAttachments());
}
return $this;
}
/**
* 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:
*
* @code
* jQuery.extend(true, {}, $settings_items[0], $settings_items[1], ...)
* @endcode
*
* This means integer indices are preserved just like string indices are,
* rather than re-indexed as is common in PHP array merging.
*
* Example:
* @code
* 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'].
* @endcode
*
* 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.
*
* @param array $a
* An attachments array.
* @param array $b
* Another attachments array.
*
* @return array
* The merged attachments array.
*/
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;
}
}
Members
Title Sort descending | Modifiers | Object type | Summary | Overriden Title |
---|---|---|---|---|
AttachmentsTrait::$attachments | protected | property | The attachments for this response. | |
AttachmentsTrait::addAttachments | public | function | ||
AttachmentsTrait::getAttachments | public | function | ||
AttachmentsTrait::setAttachments | public | function | ||
BubbleableMetadata::addCacheableDependency | public | function | Overrides RefinableCacheableDependencyTrait::addCacheableDependency | |
BubbleableMetadata::applyTo | public | function | Applies the values of this bubbleable metadata object to a render array. | Overrides CacheableMetadata::applyTo |
BubbleableMetadata::createFromObject | public static | function | Creates a bubbleable metadata object from a depended object. | Overrides CacheableMetadata::createFromObject |
BubbleableMetadata::createFromRenderArray | public static | function | Creates a bubbleable metadata object with values taken from a render array. | Overrides CacheableMetadata::createFromRenderArray |
BubbleableMetadata::merge | public | function | Creates a new bubbleable metadata object by merging this one with another. | Overrides CacheableMetadata::merge |
BubbleableMetadata::mergeAttachments | public static | function | Merges two attachments arrays (which live under the '#attached' key). | |
CacheableDependencyTrait::$cacheContexts | protected | property | Cache contexts. | |
CacheableDependencyTrait::$cacheMaxAge | protected | property | Cache max-age. | |
CacheableDependencyTrait::$cacheTags | protected | property | Cache tags. | |
CacheableDependencyTrait::setCacheability | protected | function | Sets cacheability; useful for value object constructors. | |
CacheableMetadata::getCacheContexts | public | function | The cache contexts associated with this object. | Overrides CacheableDependencyTrait::getCacheContexts |
CacheableMetadata::getCacheMaxAge | public | function | The maximum age for which this object may be cached. | Overrides CacheableDependencyTrait::getCacheMaxAge |
CacheableMetadata::getCacheTags | public | function | The cache tags associated with this object. | Overrides CacheableDependencyTrait::getCacheTags |
CacheableMetadata::setCacheContexts | public | function | Sets cache contexts. | |
CacheableMetadata::setCacheMaxAge | public | function | Sets the maximum age (in seconds). | |
CacheableMetadata::setCacheTags | public | function | Sets cache tags. | |
RefinableCacheableDependencyTrait::addCacheContexts | public | function | ||
RefinableCacheableDependencyTrait::addCacheTags | public | function | ||
RefinableCacheableDependencyTrait::mergeCacheMaxAge | public | function |
Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.