Finally updating our site

July 13, 2011

Ever walk into a contractor's house? There are always a ton of things that need to be fixed or painted. Well, I've found web developers are similar. We're working on so many sites, the last thing we want to do is work on our own. :)

We've finally found time to work on our site. I hope you enjoy (or at least appreciate) the changes.

Drupal conditional page caching

January 14, 2011

One of our clients has a newspaper site in which they would like anonymous users to see full stories for 10 minutes. After this “preview” period, the anonymous user will see a limited page that only displays the first paragraph of the story and a box requesting the user to register for access.

Additionally, because of the amount of traffic that the site gets, we need to enable caching to help performance.

When caching is on, preview is broken because anonymous users get the cached page. The cached page could be a complete page or a limited page depending upon who clicked the page first. So users who are still within their 10 minute preview might see a limited page. Users who are past their 10 minute limit might see the complete page. It all depends on what version of the page is cached.

So what do we need to do? We need to check the user’s status before drupal decides whether to pull the page from cache or build it dynamically.

There is no way to disable caching on a per user basis.

One would think that hooking the boot process would be pretty easy considering there is hook_boot. However, it’s not so simple. It turns out that a cached page is already loaded before hook_boot() is invoked even though the documentation implies otherwise.

Luckily for us, Brian Cairns has developed a module called Dynamic Cache which essentially hijacks Drupal’s normal bootstrap process and completes the rest of it. This module allows our module to implement hook_boot and enable or disable cache based on our criteria.

With Brian’s Dynamic Cache installed we added the following to our module called preview:

/**

* Implementation of hook_boot()

* We need to check the user’s status before drupal decides whether to pull the page from cache or build it dynamically.

* If we don’t do this Preview mode won’t work on a site that is “behind-the-wall” because the preview user will get the cached page.

* The cached page could be the full page or the limited page depending upon who clicked the page first (after the cache was cleared).

*/

function preview_boot() {

require “./includes/path.inc”;

$my_uri = $_SERVER['REQUEST_URI'];

$my_uri = urldecode($my_uri);

if (preg_match(“/^\//”,$my_uri)) {

$my_uri = substr($my_uri,1);

}

drupal_init_language();

$url = drupal_get_normal_path($my_uri);

if (preg_match(“/^node/”,$url)) {

$parts = explode(“/”, $url);

if (preview_preview($parts[0], $parts[1])) {

$GLOBALS['conf']['cache'] = CACHE_DISABLED;

$_SESSION['Preview'] = 1;

} else {

$_SESSION['Preview'] = 0;

}

} else {

$_SESSION['Preview'] = 0;

}

}

In this hook we find out what page we’re on and if we’re on a node page like a news story (not the front page or section page) we then run our function preview_preview to see if the user should have access. Preview_preview checks cookies and a special session table that we created in order to track how much time the user has spent on the site. If the person has access we disable the page cache with:

$GLOBALS['conf']['cache'] = CACHE_DISABLED;

We also set our $_SESSION['Preview'] = 1 which is used in our template.php.

One thing to note we should probably change $_SERVER['REQUEST_URI'] to Drupal’s request_uri() function because $_SERVER['REQUEST_URI'] doesn’t work with all servers. However, our server is apache and so this works fine for us.

Also, it might be better to create a custom “drupal_get_normal_path” to convert url aliases to the internal url. drupal_get_normal_path changes a SEO friendly URL like “content/president-elected” to “node/53424.” If we created our own function retrieving the data out of the url_alias table we wouldn’t need to require includes/path.inc and we could avoid having to call drupal_init_language. Although there does not seem to be alot of overhead involved with this.

Hope this post helps others that are doing unique implementations with Drupal.

Drupal date_format

September 14, 2010

If you’re displaying a date in a node template like $node->create, don’t use php’s date function to format it. $node->create does not handle timezones.

You need to use drupal’s date_format function which calculates the timezone based on the date_default_timezone_name variable which you set in the drupal configuration.

Adding variables to your Drupal theme

September 14, 2010

I have a client who has several websites that use the same theme. We use Drupal in multisite set up so that we can update the theme and modules in one location. However, sites may want different things to appear on their particular site. For example, site abc.com might want a “Place an ad” button, while site bcd.com might not want it. How do you do this but keep a common theme?

To place a checkbox in the theme configuration page you need to add some code to template.php and theme_settings.php.

In template.php add:

/*
* Initialize theme settings
*/
if (is_null(theme_get_setting(‘placead’))) {
global $theme_key;

$defaults = array(
‘placead’ => 0,
);

// Get default theme settings.
$settings = theme_get_settings($theme_key);
// Don’t save the toggle_node_info_ variables.
if (module_exists(‘node’)) {
foreach (node_get_types() as $type => $name) {
unset($settings['toggle_node_info_' . $type]);
}
}
// Save default theme settings.
variable_set(
str_replace(‘/’, ‘_’, ‘theme_’. $theme_key .’_settings’),
array_merge($defaults, $settings)
);
// Force refresh of Drupal internals.
theme_get_setting(”, TRUE);
}

In theme_settings.php add:

function phptemplate_settings($saved_settings) {
$defaults = array(
‘placead’ => 0,
);

// Merge the saved variables and their default values
$settings = array_merge($defaults, $saved_settings);

$form['placead'] = array(
‘#type’ => ‘checkbox’,
‘#title’ => t(‘Display “Place an Ad” button’),
‘#default_value’ => $settings['placead'],
);

// Return the additional form widgets
return $form;
}

And then in you page.tpl.php you can access the variable like this:

$placead = $settings['placead'];
if ($placead == 1) {
<img src=”/images/placead.gif”>
}

 

 

Quick contact

Want to discuss your next project and get a quote? Contact us.

Tel: 1-888-WEB-0010
Email: tim@gristmillmedia.com

 

img

Follow our posts about web development in Massachusetts.

twitter.com/gristmillmedia