Ineffective when using page caching - ajax solution?
mr.j - October 25, 2007 - 00:54
| Project: | IP to Country |
| Version: | 5.x-1.0 |
| Component: | Code |
| Category: | feature request |
| Priority: | normal |
| Assigned: | sugree |
| Status: | closed |
Jump to:
Description
I'm trying to use this module to display different information in a block on my homepage based on the visitor's country.
It works, but only the first time the homepage is accessed. Then the homepage gets cached and subsequent visitors see the cached version which was based on the country of the first visitor.
Disabling page caching is not an option due to performance considerations.
I'm not sure there is really anything that can be done about this on the server - perhaps you could add an ajax capability so that the country can be determined in javascript after the cached page has loaded, and I can hide the data I don't want to show using javascript?

#1
Alright this bugged me enough to roll my own solution so here it is.
Apologies for no patch file, but the additions to the module are so minor it should be easy to do.
First up, add this snippet to the ip2cc_menu() function in the module. It sets up a menu callback that allows us to call ip2cc using the path "http://www.yoursite.com/ip2cc_get_country_js". It won't appear a menu anywhere - its just drupal's way of allowing you to map a custom URL to a php callback.
if ($may_cache) {
//.... other stuff ....
$items[] = array(
'path' => 'ip2cc_get_country_js',
'title' => t('Get Country as JSON'),
'callback' => 'ip2cc_get_country_js',
'access' => user_access('access content'),
'type' => MENU_CALLBACK
);
}
Now add the callback function we defined above elsewhere in the module. The function returns the whole $country object as a json string, which can later be converted to a javascript object on the client.
function ip2cc_get_country_js() {$country = ip2cc_get_country($_SERVER['REMOTE_ADDR']);
print drupal_to_js($country);
exit;
}
So now if you want to call this callback using ajax on your page or block its quite simple. This is part of a bit of php I have inserted into a block. My block displays two tabs, and I want one of them initially selected for US visitors, and the other for everyone else:
$inline_js = '$(document).ready(' .'function() { ' .
'$.get("ip2cc_get_country_js", function(json) { ' .
'var ip2cc_country = eval("(" + json + ")"); ' .
'if (ip2cc_country.country_code != "US") {}; // <-- do something here ' .
'} );' .
'});';
drupal_add_js($inline_js, 'inline', 'header', false, true);
What it does is calls that callback function we added to the module via ajax when the page loads and the callback returns a json string, which we then eval() into a javascript object. Works like a charm.
I highly recommend that this is added to the module code.
#2
Great idea! I adjusted your patch a little bit. The url is changed to "ip2cc/get_country/json".
$inline_js = '$(document).ready(' .'function() { ' .
'$.get("ip2cc/get_country/json", function(json) { ' .
'var ip2cc_country = eval("(" + json + ")"); ' .
'if (ip2cc_country.country_code != "US") {}; // <-- do something here ' .
'} );' .
'});';
drupal_add_js($inline_js, 'inline', 'header', false, true);
#3
Automatically closed -- issue fixed for two weeks with no activity.