Answers.Body: <p>I can't think of a different way to conditionally enable template caching (globally, i.e. not per <code>{% cache %}</code> tag) other than to conditionally set the <code>enableTemplateCaching</code> config setting to either <code>true</code> or <code>false</code>.</p>
  <p>To your specific use case, I wouldn't worry about simply accessing the <code>$_GET</code> superglobal to look for that <code>nocache</code> param. This is essentially all that Craft itself does under the hood, when you use <code>Craft::$app-&gt;getRequest()-&gt;getQueryParams()</code> – except that Craft will also UTF8-encode and memoize the params, which shouldn't be critical.</p>
  <p>So something like this should work fine:</p>
  <pre class="lang-php prettyprint-override"><code>use craft\helpers\App;
  
  $disableTemplateCaching = App::parseBooleanEnv($_GET['nocache']);
  
  return [
      '*' =&gt; [
           'enableTemplateCaching' = !$disableTemplateCaching,
      ],
  ];
  </code></pre>
  <p>Another option is to set the config setting a bit later in the request lifecycle. For that, you can't use <code>config/general.php</code>, but will need to <a href="https://craftcms.com/docs/3.x/extend/module-guide.html" rel="nofollow noreferrer">create a custom module</a>, adding the relevant logic within an appropriate <a href="https://craftcms.com/docs/3.x/extend/events.html" rel="nofollow noreferrer">event</a> listener (setting/overriding the config setting can be done by accessing the <a href="https://docs.craftcms.com/api/v3/craft-services-config.html" rel="nofollow noreferrer">Config service</a>).</p>
  <p>Using the <code>craft\web\Application::EVENT_INIT</code> event seems to work nicely; the below would go into your module's <code>init()</code> method:</p>
  <pre class="lang-php prettyprint-override"><code>use Craft;
  use craft\helpers\App;
  use craft\web\Application;
  use yii\base\Event;
  
  Event::on(
      Application::class,
      Application::EVENT_INIT,
      static function (Event $event) {
      
          // Get the &quot;nocache&quot; query param value
          $noCacheParamValue = Craft::$app-&gt;getRequest()-&gt;getQueryParam('nocache');
      
          // Make sure it's a boolean
          $disableTemplateCaching = App::parseBooleanEnv($noCacheParamValue);
      
          // Set the enableTemplateCaching config setting using the Config service
          Craft::$app-&gt;getConfig()-&gt;getGeneral()-&gt;enableTemplateCaching = !$disableTemplateCaching;
      
      }
  );
  </code></pre>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-03-14T09:50:33.843Z
Answers.Text: Thanks for the thoughtful response! You're right, the first approach should be alright, and using `$_GET` is indeed a bit simpler than `$_SERVER`. Though the second approach is even better, changing the config value on `init` is a great idea! Might lead to some head-scratching for other developers though, so for this approach I'll want to stick a comment in `general.php` explaining that the value might be changed by the module.
Answers.UserDisplayName: MoritzLost
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-03-14T09:34:18.930Z
Answers.LastActivityDate: 2022-03-14T11:11:26.387Z
Answers.LastEditDate: 2022-03-14T11:11:26.387Z
Answers.UserDisplayName: Mats Mikkel Rummelhoff
Body: <p>I'm looking for a way to disable the template cache (<code>{% cache %}</code> tags) for the entire request based on a specific condition (not just based on the current environment). In this case, the condition is a query parameter (something like <code>?nocache=1</code>), but I'm also looking for a general solution to this. There is, of course, the <a href="https://craftcms.com/docs/3.x/config/config-settings.html#enabletemplatecaching" rel="nofollow noreferrer"><code>enableTemplateCaching</code> general config setting</a>, which I could use to toggle the template cache on and off:</p>
  <pre class="lang-php prettyprint-override"><code>// config/general.php
  
  $someCondition = true;
  
  return [
      '*' =&gt; [
           'enableTemplateCaching' = $someCondition,
      ],
  ];
  </code></pre>
  <p>The problem is that the config is included super early during the request lifecycle, before the <code>Craft::$app</code> object is even constructed. So I can't use <code>Craft::$app-&gt;request-&gt;getQueryParam('nocache')</code> or anything else from the API. For query parameters specifically, I <em>could</em> access <code>$_SERVER['REQUEST_URI']</code> directly, but that feels kind of dirty. And it doesn't solve the problem if I need access to anything from the API to determine whether to enable caching or not.</p>
  <p>I've checked if there's a hook in the <code>TemplateCaches</code> service I could use, but it doesn't look like it. The other solution would be to include the condition in every <code>{% cache %}</code> tag manually, but that's error-prone and noisy.</p>
  <p>Is there a more general solution to turning off <code>{% cache %}</code> tags based on a specific condition for the current request?</p>
  
Tags: <templating><cache><request>
Title: Disable template cache globally based on condition
ThreadText: # Disable template cache globally based on condition
  
  (Asked by: username_0 on 2022-03-09)
  
  I'm looking for a way to disable the template cache (`{% cache %}` tags) for the entire request based on a specific condition (not just based on the current environment). In this case, the condition is a query parameter (something like `?nocache=1`), but I'm also looking for a general solution to this. There is, of course, the [`enableTemplateCaching` general config setting](https://craftcms.com/docs/3.x/config/config-settings.html#enabletemplatecaching), which I could use to toggle the template cache on and off:
  
  ```php
  // config/general.php
  
  $someCondition = true;
  
  return [
      '*' => [
           'enableTemplateCaching' = $someCondition,
      ],
  ];
  
  ```
  
  The problem is that the config is included super early during the request lifecycle, before the `Craft::$app` object is even constructed. So I can't use `Craft::$app->request->getQueryParam('nocache')` or anything else from the API. For query parameters specifically, I *could* access `$_SERVER['REQUEST_URI']` directly, but that feels kind of dirty. And it doesn't solve the problem if I need access to anything from the API to determine whether to enable caching or not.
  
  I've checked if there's a hook in the `TemplateCaches` service I could use, but it doesn't look like it. The other solution would be to include the condition in every `{% cache %}` tag manually, but that's error-prone and noisy.
  
  Is there a more general solution to turning off `{% cache %}` tags based on a specific condition for the current request?
  
  **Tags:** templating, cache, request
  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_1 on 2022-03-14. Score: 2 | Accepted answer
  
  I can't think of a different way to conditionally enable template caching (globally, i.e. not per `{% cache %}` tag) other than to conditionally set the `enableTemplateCaching` config setting to either `true` or `false`.
  
  To your specific use case, I wouldn't worry about simply accessing the `$_GET` superglobal to look for that `nocache` param. This is essentially all that Craft itself does under the hood, when you use `Craft::$app->getRequest()->getQueryParams()` – except that Craft will also UTF8-encode and memoize the params, which shouldn't be critical.
  
  So something like this should work fine:
  
  ```php
  use craft\helpers\App;
  
  $disableTemplateCaching = App::parseBooleanEnv($_GET['nocache']);
  
  return [
      '*' => [
           'enableTemplateCaching' = !$disableTemplateCaching,
      ],
  ];
  
  ```
  
  Another option is to set the config setting a bit later in the request lifecycle. For that, you can't use `config/general.php`, but will need to [create a custom module](https://craftcms.com/docs/3.x/extend/module-guide.html), adding the relevant logic within an appropriate [event](https://craftcms.com/docs/3.x/extend/events.html) listener (setting/overriding the config setting can be done by accessing the [Config service](https://docs.craftcms.com/api/v3/craft-services-config.html)).
  
  Using the `craft\web\Application::EVENT_INIT` event seems to work nicely; the below would go into your module's `init()` method:
  
  ```php
  use Craft;
  use craft\helpers\App;
  use craft\web\Application;
  use yii\base\Event;
  
  Event::on(
      Application::class,
      Application::EVENT_INIT,
      static function (Event $event) {
      
          // Get the "nocache" query param value
          $noCacheParamValue = Craft::$app->getRequest()->getQueryParam('nocache');
      
          // Make sure it's a boolean
          $disableTemplateCaching = App::parseBooleanEnv($noCacheParamValue);
      
          // Set the enableTemplateCaching config setting using the Config service
          Craft::$app->getConfig()->getGeneral()->enableTemplateCaching = !$disableTemplateCaching;
      
      }
  );
  
  ```
  
  > **Comments:**
  > **username_0**: Thanks for the thoughtful response! You're right, the first approach should be alright, and using `$_GET` is indeed a bit simpler than `$_SERVER`. Though the second approach is even better, changing the config value on `init` is a great idea! Might lead to some head-scratching for other developers though, so for this approach I'll want to stick a comment in `general.php` explaining that the value might be changed by the module.  
  
  ---
  
  