Drupal programming considerations (varnish)

Ajax & Varnish working together

Varnish will cache all your output, unless told differently.

Ajax content should be excluded.

Always use the /ajax/mymodule/idontknwowhatelse path for your ajax hooks.

Varnish will then know the path has ajax and will not cache the output.

Not doing this will result in awkward behavior.

Varnish needs the following in vcl_fetch

if (req.url ~ "^/ajax/") {

set beresp.cacheable = false;

return (pass);

}

Purging/Clearing the cache

Clearing the varnish cache in drupal is easy. If you configured your varnish console correctly it is done in one line:

if (module_exists('varnish')) { 

module_load_include('module', 'varnish');

_varnish_terminal_run('url.purge ' . $base_url);

}

Time to live

Different types of content can have a different ttl. This can be possible if you know the paths of this content. You can set this in the varnish config. /articles* can have a different ttl than /blog* else

if (req.url ~ "^/article/") {

set beresp.ttl = 5m; // article ttl 5 minutes 

} else {

set beresp.ttl = 30m; // default ttl 45 minutes

}

Varnish and cookies

Varnish can work with cookies perfectly. You can choose wich ones should be excluded/included.

As mentioned before, one line is needed for the google analitycs : in vcl_recv add:

set req.http.Cookie = regsuball(req.http.Cookie, "(^|;\s*)(__[a-z]+|has_js)=[^;]*", "");

If you want logged in users not to be cached, add the following in vcl_recv:

if (req.http.Cookie ~ "(VARNISH|DRUPAL_UID|LOGGED_IN|NO_CACHE|DrupalAdminToolbar)") { return (pass); }

About the php coding now. In the following case the cookie will never be set.

$language = $_COOKIE['SiteLang'];

if ($language) {

drupal_goto($language);

}

$langs = locale_language_list('native');

$language = $_GET['l'];

if ($language && in_array($language, array_keys($langs))) {

setcookie('SiteLang', $language, time() + 3600*24*30*12, '/');

drupal_goto("");

}

This will only redirect the user to the front page, the language will be the language set by the first browse (and thus wrong).

Knowing that lang.php is excluded from the caching, making this work kan easily be done by changing it to the following.

$language = $_COOKIE['SiteLang'];

if ($language) {

drupal_goto($language);

}

$langs = locale_language_list('native');

$language = $_GET['l'];

if ($language && in_array($language, array_keys($langs))) {

setcookie('SiteLang', $language, time() + 3600*24*30*12, '/');

drupal_goto("lang.php",array("l"=>$language));

}

It will force you back to lang.php. lang.php will add the set-cookie headers. Once that is done, lang.php will redirect you to the front page of (the language of) your choosing. User never sees lang.php again, and only gets properly cached content.