0

What I'm trying to do is allow registered users to configure a few colors on public facing pages (profiles, etc.) and to do so I'm using the ColorField module and a few theme functions.

My problem is that the anonymous page cache is caching values stored in Drupal.settings, preventing changes from being visible until the page cache is cleared.

Here is the code I currently use to set Drupal.settings:

<?php
function themeName_preprocess_page(&$vars) {
  $branding = array(
      'header_bg' => '#ffffff',
      'accent' => '#0b40ac'
  );
  drupal_add_js(array('pageRebranding' => $branding), array('type' => 'setting'));
  drupal_add_js(drupal_get_path('theme', 'themeName') .'/js/branding.js');
}
?>

Disabling the anonymous page cache (globally or selectively) is not an option.

Is there a way I can pass values to Drupal.behaviors using ajax on page load, or another method to get around the anonymous page cache?

Here is my JS:

(function ($) {

    Drupal.behaviors.pageRebranding = {
        attach: function (context, settings) {
            var header_bg = Drupal.settings.pageRebranding.header_bg;
            var accent = Drupal.settings.pageRebranding.accent;
            /* Do Stuff */
        }
    };

})(jQuery);
3
  • Do not use drupal_add_js. In your preprocess function, you can use #attached to attach js and css file in a way that Drupal can cache. See the documentation for more information. – AKS Aug 30 '14 at 0:23
  • I need the CSS to be dynamic and be applied even if the page is already in the anonymous page cache. This is why I'm using jQuery to apply the colors rather than just using CSS files. Users may choose to update these settings at anytime but they do not have the ability to clear Drupal's cache. – Citricguy Aug 30 '14 at 0:28
  • If you are storing the values server side, I don't think you'll be able to use a global cache. The best way would be to use a cookie and js to make the changes client side. – AKS Aug 30 '14 at 0:30
0

You can avoid the cache by calling your file using

drupal_add_js(drupal_get_path('theme', 'themeName') .'/js/branding.js', array('cache' => FALSE));
1
  • 1
    This only works when 'type' references a JavaScript file. The settings as in drupal_add_js(array('pageRebranding' => $branding), array('type' => 'setting')); are stored with the page cache regardless of the cache setting. :( – Citricguy Sep 3 '14 at 0:43
0

Using jQuery and an AJAX callback can be used to get and apply changes to a page even if it is already in the anonymous page cache.

First create a callback function that will return JSON results.

function hook_menu() {
  $items['branding/ajax/%'] = array(
    'page callback' => '_branding_ajax_callback',
    'page arguments' => array(2),
    'access callback' => TRUE,
    'type' => MENU_CALLBACK,
  );
  return $items;
}

function _branding_ajax_callback($uid) {

  //Branding Defaults
  $branding = array(
      'header_bg' => '#ffffff',
      'accent' => '#0b40ac',
      'logo' => theme_get_setting('logo', 'theme'),
      'logo_url' => 'http://example.com',
  );

  return drupal_json_output($branding);
}

Next, create the JavaScript that will make the AJAX call and then apply the changes over the cached page.

(function ($) {
    Drupal.behaviors.hookRebranding = {
        attach: function (context, settings) {
            var json_url = 'http://example.com/branding/ajax/' + user_brand_id;

            $.ajax({
                dataType: "json",
                url: json_url,
                cache: false,
                success: function(data) {

                    $("#footer-wrapper").css( "border-top", data['accent'] + " 6px solid" );
                    $(".header-group-wrapper").css( "border-bottom", data['accent'] + " 3px solid");
                    $("#logo a img").attr("src", data['logo']);
                    $("#header-group-wrapper").css( "background-color", data['header_bg']);
                    $("h1, h2, h3, h4, h5, h6, a, a:link, a:visited").css( "color", data['accent']);
                }
            });

        }
    };
})(jQuery);

Don't forget to include the JavaScript in your theme.

function THEME_preprocess_page(&$vars) {
  drupal_add_js(drupal_get_path('theme', 'omr') .'/js/branding.js');
}

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.