Problem/Motivation

We currently use drupal_process_attached in order to add css/js to the render flow, while we do have the information
first on the render array, could then

Proposed resolution

  • Make css/jss/libraries available on the fragment. Yes, we would actually like to have proper asset support, though that issue won't move
    forward for a while, so we could do it like poormans but still make quite nice progress.
  • Construct the page and fragment using that information, both for blocks and the main controller

Remaining tasks

User interface changes

API changes

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

dawehner’s picture

Status: Active » Needs work
FileSize
9.69 KB

I am aware that this will conflict with #2256365: Factor render->fragment code out to a service though I would like to throw it out in order to get an issue created so that
it is more clear what needs to be done.

Crell’s picture

Thanks, dawehner!

+++ b/core/lib/Drupal/Core/Page/HtmlFragment.php
@@ -234,4 +243,40 @@ public function isCacheable() {
+  public function &getCss() {
+    return $this->css;
+  }
+
+  public function setCss($css) {
+    $this->css = $css;
+    return $this;
+  }

These need to be turned into add*() methods, like addLinkElement() and addMetaElement(). There's no reason for style and script tags to be handled differently at this level than any other header. That means they come out of the constructor, too.

Crell’s picture

Fabianx’s picture

+++ b/core/lib/Drupal/Core/Controller/HtmlControllerBase.php
@@ -73,11 +75,37 @@ protected function createHtmlFragment($page_content, Request $request) {
     $cache = !empty($page_content['#cache']['tags']) ? array('tags' => $page_content['#cache']['tags']) : array();
-    $fragment = new HtmlFragment($content, $cache);
+    $fragment = new HtmlFragment($content, $cache, $js, $css, $library);

I do think JS and CSS belong there, maybe even html_head, but adding library, will be a problem as there can be arbitrary things in attached now at this moment, see drupal_process_attached(), and this should parse the libraries down to CSS / JS.

As that is all that e.g. an ESIFragmentRenderer should care about.

Crell’s picture

There's nothing special about CSS and JS as far as *adding* them. Honestly I don't even think $cache belongs in the constructor here. This is a setter-filled object. Use 'em.

Fabianx’s picture

I agree they probably don't belong in the constructor, however given how browsers work, and if I understand the plan correctly that you want to e.g. use a ESIHtmlFragment, what you want to do is:

- Special case CSS, you need to e.g. queue them via JS if retrieving a ESI fragment as it can no longer change the original assets. You then want to get them in aggregated form of what CSS is not yet present on the page.
- Special case JS, you need to queue them for a ESI case, but for a Big Pipe workflow case you probably want to just put them in the original JS, but output in the footer. You want to possible combine them with the existing aggregates.
- Process all other #attached things and convert to JS / CSS.

Another special case is html_head, which just is queued via JS and then attached to the element, I cannot see currently why an ESIFragment would like to change the HTML head though.

Also cache is a very important information for an HTMlFragment, not only the #cache tags, but also the 'header' or a TTL of the content and usually also the global cache granularity (per page, per role, per user). I know we now have generally cache contexts, but the granularity is still important for determining if an ESI Fragment could be cached, especially if talking of recursive caching.

Just my thoughts, FWIW, I am prototyping some things of this in contrib.

dawehner’s picture

True,

dawehner’s picture

Status: Needs work » Needs review

muh.

The last submitted patch, 1: 2334029-fragment-1.patch, failed testing.

Status: Needs review » Needs work

The last submitted patch, 7: html_fragment-2334029-6.patch, failed testing.

The last submitted patch, 7: html_fragment-2334029-6.patch, failed testing.

dawehner’s picture

Status: Needs work » Needs review
Issue tags: +WSSCI
FileSize
12.2 KB
4.98 KB

Let's work on make it actually render something.

Status: Needs review » Needs work

The last submitted patch, 13: htmlfragment-2334029-13.patch, failed testing.

Crell’s picture

  1. +++ b/core/lib/Drupal/Core/Controller/HtmlControllerBase.php
    @@ -73,11 +75,40 @@ protected function createHtmlFragment($page_content, Request $request) {
    +    $fragment = (new HtmlFragment($content, $cache))
    +      ->setCss($css)
    +      ->setJs($js)
    +      ->setLibraries($library);
    

    That syntax is lovely, but only works on PHP 5.5. :-(

  2. +++ b/core/lib/Drupal/Core/Page/HtmlFragment.php
    @@ -234,4 +240,55 @@ public function isCacheable() {
    +  public function &getJs() {
    +    return $this->js;
    +  }
    +
    +  public function addJs($js) {
    +    $this->js[] = $js;
    +    return $this;
    +  }
    +
    +  public function setJs($js) {
    +    $this->js = $js;
    +    return $this;
    +  }
    

    CSS and JS should be modelled with a StyleElement and ScriptElement, like Link and Meta. Those two in particular also allow for bodies.

    Mutating the array form of a render array's asset definitions to the object form should be RenderHtmlRenderer's job. (As soon as that finally lands...)

dawehner’s picture

That syntax is lovely, but only works on PHP 5.5. :-(

Wow, I taught crell something about PHP: http://3v4l.org/Vjnst

Crell’s picture

Wha? I thought that was added in 5.5. Carry on then! (But then I don't know what the fatal is about.)

dawehner’s picture

We talked in IRC and we are kind of sure that we should not reference Script and Style elements but rather domain objects for CSS/JS/Libraries.

Sadly I doubt that these domain objects are solveable easily, unless we have #1762204: Introduce Assetic compatibility layer for core's internal handling of assets going in.
This just tracks work, no big progress.

andypost’s picture

looks outdated

dawehner’s picture

Status: Needs work » Fixed

Totally

Status: Fixed » Closed (fixed)

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