Commit ff16dd6d authored by mxh's avatar mxh
Browse files

Issue #3253881 by mxh: mustache_views: Caching not properly working when using...

Issue #3253881 by mxh: mustache_views: Caching not properly working when using Mustache templates in Views
parent 0dc37503
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -95,6 +95,7 @@ Optional sub-modules included:
* "Mustache Logic-less Views" (`mustache_views`): Use Mustache variables
  including Tokens within Views configurations. For example, you can use a
  variable in the input for a fixed default argument within contextual filters.
  More about this sub-module is described in section 3.8.
* "Mustache Logic-less Templates: Even more magic" (`mustache_magic`):
  Adds more magic variable plugins to Mustache Templates, for example {{#sync}}.
  More about this module see section 3.6.
@@ -467,6 +468,23 @@ I am an english text and will be substituted by an according German translation.
{{/t.de}}
```

### 3.8 Mustache in Views

By installing the `mustache_views` sub-module, you may use Mustache variables
including Tokens within Views configurations. For example, you can use a
variable in the input for a fixed default argument within contextual filters.

**Please note**:
When using Mustache variables and Tokens from data that are provided by a
certain context, for example using the node coming from the URL, then you need
to do either one of the following:
* Disable caching for the View (click on `Caching:` within Views UI display
config and choose `None`) or...
* ...add a contextual filter for it. You can do so by choosing `Global: Null`
within contextual filters, and then select "Provide a default value" ->
"Content ID from URL". For the reason why this is necessary, have a look at
https://www.drupal.org/project/mustache_templates/issues/3253881.

## 4. API

### 4.1 How Mustache templating works in Drupal
+17 −0
Original line number Diff line number Diff line
@@ -3,10 +3,12 @@
namespace Drupal\mustache_views;

use Drupal\Core\Database\Query\AlterableInterface;
use Drupal\Core\Render\BubbleableMetadata;
use Drupal\Core\Render\RenderContext;
use Drupal\Core\Render\RendererInterface;
use Drupal\mustache\Helpers\Mustache;
use Drupal\mustache\Helpers\MustacheRenderTemplate;
use Drupal\views\ViewExecutable;

/**
 * Service for integration of Mustache templates in Views.
@@ -38,7 +40,16 @@ class MustacheViews {
   */
  public function alterQuery(AlterableInterface $query) {
    $to_evaluate = [];
    $view = $query->getMetaData('view');
    if (!($view instanceof ViewExecutable)) {
      return;
    }
    $this->collectTemplates($query, $to_evaluate);
    if (empty($to_evaluate)) {
      return;
    }

    $bubbleable_metadata = BubbleableMetadata::createFromRenderArray($view->element);
    foreach ($to_evaluate as &$text) {
      $template = MustacheRenderTemplate::build(hash('md4', $text), $text)
        ->withTokens();
@@ -46,6 +57,8 @@ class MustacheViews {
      $this->renderer->executeInRenderContext(new RenderContext(), function () use (&$build) {
        $this->renderer->render($build);
      });
      $bubbleable_metadata
        ->addCacheableDependency(BubbleableMetadata::createFromRenderArray($build));
      if (isset($build['#content'])) {
        $trimmed = trim((string) $build['#content']);
        if ($trimmed !== '') {
@@ -53,6 +66,10 @@ class MustacheViews {
        }
      }
    }
    // @todo Resolve this to be cacheable by respecting cache contexts within
    // \Drupal\views\Plugin\views\cache\CachePluginBase::generateResultsKey().
    // @see https://www.drupal.org/project/mustache_templates/issues/3253881
    $bubbleable_metadata->applyTo($view->element);
  }

  /**
+1 −0
Original line number Diff line number Diff line
@@ -411,6 +411,7 @@ class MustacheTokenProcessor {
        // want to only use "node").
        $type = end($context_data_type);
        $value = $context->getContextValue();
        $bubbleable_metadata->addCacheableDependency($context);
        if (isset($value) && !isset($token_data[$type])) {
          $token_data[$type] = $value;
        }