2

I'm trying to get a value of GET variable in hook_preprocess_page(), but I'm having problems with the cache. Only the first time the code is executed, I can get the value of the variable to put it in a cookie; if I try to load the same page with different values, the code doesn't execute.

I need to put this value in cookie to identify the source of leads.

  • In D7 you'd need to put this into hook_boot or hook_exit or in the settings.php file. So you are using the wrong hook; I just don't know what it'd be in D8. – mikeytown2 Feb 5 '16 at 21:09
  • Use event subscriber instead of this hook and make sure it runs before page cache. – user21641 Feb 5 '16 at 21:18
3

If your preprocess doesn't affect the result of the page, and needs to execute even when the page is served from the page cache, you should move your logic to a Kernel Event subscriber, which replaces hook_boot() and hook_exit() from Drupal 7.

DrupalizeMe has an article on Event Subscribers, but the basic components are creating a class that implements EventSubscriberInterface, and then registering it as a service.

MYMODULE/EventSubscriber/MyEventSubscriber.php

class MyEventSubscriber implements EventSubscriberInterface {
  static function getSubscribedEvents() {
    $events[KernelEvents::RESPONSE][] = ['onResponse'];
    return $events;
  }
  public function onResponse(FilterResponseEvent $event) {
    $request = $event->getRequest();
    $response = $event->getResponse();

    $parameter_value = $request->query->get('parameter_name');
    $response->headers->setCookie(new Cookie('cookie_name', 'cookie_value'));
  }
}

MYMODULE/MYMODULE.services.yml

MYMODULE.my_event_subscriber:
  class: Drupal\MYMODULE\EventSubscriber\MyEventSubscriber
  arguments: []
  tags:
    - { name: event_subscriber }

The request event can modify the request before other components receive it, but cannot affect the response. The response event cannot modify the request, but is able to alter the response after it has been composed.
If you need to do both, your service object can store some state during the request event, and then alter the response based on that state during the response event.

  • Thanks gapple, in this moments the value of the cookie change every time the page is load – javiregpa Feb 7 '16 at 11:03
  • 1
    This doesn't answer the question though. It gives a solution to the problem, but doesn't help out future people having issues with preprocess caching. – Matt Fletcher Sep 1 '16 at 8:45
1

To bust the cache in a preprocess hook in Drupal 8 you simply can add your desired cache context to the $variables. In the following example your code now is going to be cached per session.

/**
 * Implements template_preprocess_page().
 */
function MYMODULE_preprocess_page(&$variables) {

  // Your code ...
  // ...
  // ...

  // Ensure the cache varies correctly.
  $variables['#cache']['contexts'][] = 'session';
}

Read the docs for more available contexts: Cache contexts.


Alternatively you can set your own tag like answered in a similar question: Remove cache in hook_preprocess_node

0

If you want disable cache in hook_preprocess_hook - you can simply add cache element to variables. Example:

function MYMODULE_preprocess_page(&$variables) {
  // prevent caching certain element
  $variables['my_custom_element'] = [
    '#markup' => t('My message'),
    '#cache' => ['max-age' => 0],
  ];
  // or prevent caching all page
  $variables['#cache']['max-age'] = 0;
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.