Quantcast
Channel: Issues for Drupal core
Viewing all articles
Browse latest Browse all 298914

Add Attachment Collector to ensure #attached assets are not lost during render caching

$
0
0

Problem/Motivation

For proper render caching it is very important that not only the markup is saved, but also the accompanying assets ('#attached').

Currently both the block cache and Drupal core's render cache do loose attachments during the cache process.

While drupal_render_collect_attached() tries to mitigate this problem, it has several edge cases where it fails to work, mainly in the interaction with the theme system (early rendering) and it only works if no custom or contrib code ever calls drupal_add_js() / drupal_add_css(). (which in 2016 still has not happened)

Proposed resolution

The reason this is happening is that Drupal 7 mostly still relies on global state for adding attachments (drupal_add_*).

The idea to resolve this is to use a standard subscriber-pattern to collect these global state calls as attachments.

The caching code is then responsible to collect the Attachments that have been added after the cache miss until the cache is finally set.

The API looks like this:

$attachments_collector = new DrupalAttachmentsCollector();
// ... do the work to render the things ...
$attachments = $attachments_collector->getAttachments();
unset($attachments_collector);
// ... now store the attachments in the render array

This also allows views or other modules that used a diff based approach to collect attachments, to properly work and is also e.g. very useful for row based views caching.

Remaining tasks

- Port the relevant part of #2754245: [META] Explore how to backport render context and #cache properties from Drupal 8 to empower contrib to this issue.
- Fix documentation
- Get reviews
- Commit

User interface changes

- None

API changes

- Only API additions


Viewing all articles
Browse latest Browse all 298914

Latest Images

Trending Articles



Latest Images

<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>