I would like to utilize the Rendering/Caching system to create static pages that have ESI (Edge Side Include) markup instead of the placeholders used in the caching system. This is similar to the Drupal 7 Static module (Drupal.org/project/static), which outputs static pages with ESI markup. I am working a Drupal 8 version of the Static module, which has been moved to Drupal.org/project/static_generator, in order to avoid use of the reserved word "static".

It seems the Dynamic Page Cache is creating close to what is needed, except the placeholder markup needs to be changed, similar to how Big Pipe's placeholder strategy works. Would anyone have an idea as to the best approach? I would need to create pages similar to the partial pages currently created by the Dynamic Cache module, except that the placeholders are replaced with ESI markup. I will also need to create the html fragments that are referenced by the ESI markup.

For example, to create a static file for a node, wouldn't I need to get the markup from the Dynamic Page cache (using $cache_entry = \Drupal::cache('dynamic_page_cache')->get($cid);) and then have a placeholder strategy that modifies the placeholders to be ESI's? Or perhaps I need to get the render array for the node and use a renderer service, e.g.

    $entity_type = 'node';
    $view_mode = 'full';
    $node = \Drupal::entityTypeManager()->getStorage($entity_type)->load(1);
    $node_render_array = \Drupal::entityTypeManager()
      ->getViewBuilder($entity_type)
      ->view($node, $view_mode);
    $renderer = $this->classResolver->getInstanceFromDefinition($this->mainContentRenderers['html']);
    $request = new Request();
    $response = $renderer->renderResponse($node_render_array, $request, $this->routeMatch);
    $content = $response->getContent();

Note that the content that needs ESI placeholders is different than what needs caching placeholders. ESI's are needed for any block that is displayed on more than one page, while caching placeholders are for content that changes, and therefor can not be cached.

A point of confusion is that the rendering/caching code is all request/response based. But the process needed to output the static files with ESI placeholders will not have a request for each static file generated, as they are generated on the server, so there is no request/response needed. How can the core rendering system render a page without a request? In the above code example, a dummy blank response is used, but that causes an error.

Thank for your help,

captaindav

Comments

captaindav created an issue. See original summary.

captaindav’s picture

Title: Create static pages with edge side includes using dynamic page cache. » How to generate static pages with edge side includes.
Issue summary: View changes
captaindav’s picture

Issue summary: View changes
captaindav’s picture

Issue summary: View changes
captaindav’s picture

Issue summary: View changes
captaindav’s picture

Issue summary: View changes
Wim Leers’s picture

Component: cache system » render system
Status: Active » Fixed

I would like to utilize the Rendering/Caching system to create static pages that have ESI (Edge Side Include) markup instead of the placeholders used in the caching system.

See \Drupal\Core\Render\Placeholder\PlaceholderStrategyInterface — BigPipe is also implemented as a placeholder strategy (\Drupal\big_pipe\Render\Placeholder\BigPipeStrategy). You could add an ESI placeholder strategy.

It seems the Dynamic Page Cache is creating close to what is needed, except the placeholder markup needs to be changed, similar to how Big Pipe's placeholder strategy works.

Ah, so you already found that :)

Dynamic Page Cache only caches responses that have been requested by the end user though; it does not automatically cache a response for every possible route/URL on the site.

except that the placeholders are replaced with ESI markup.

Note how \Drupal\big_pipe\Render\Placeholder\BigPipeStrategy only acts for responses with a session. You basically want to do the opposite: anonymous/sessionless responses. This condition is a bit similar to the condition for https://www.drupal.org/project/big_pipe_sessionless to activate itself.

I talked about placeholder strategies in detail at https://wimleers.com/talk/making-drupal-fly-fastest-drupal-ever-here, specifically this part of the slides: https://wimleers.com/talk-making-drupal-fly-fastest-drupal-ever-here/#/7. You may want to watch that recording.

as they are generated on the server, so there is no request/response needed. How can the core rendering system render a page without a request?

Look into subrequests. Grep Drupal core for HttpKernelInterface::SUB_REQUEST and you'll find a few places where it is used :)


Good luck!

Status: Fixed » Closed (fixed)

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