AJAX Loading of any Block

For sites that like to use a cache to serve the full page (boost, drupal core cache, ect...), but still would like to have more dynamic content in a block; loading of blocks via ajax seems like a good way to accomplish this. I've already accomplished this with the boost module and I'm wondering if/how I should abstract this out to be a generalized solution.

Simple way

Below is the simple way to do it, for one or 2 blocks it works. For anything more then that it would probably have a negative impact since it's doing a full bootstrap for each block.

Notes:
Grabbing the info from the block cache is another way to do it; one that doesn't require a full bootstrap.
If JSON returns 'NULL' I have it set to hide that block.
Reason I add nocache=1 to the getJSON request url is because boost will soon be able to cache JSON objects. This tells boost to not cache that url.

So, whats the point?

Question is should we, the Drupal community pursue this idea of ajax blocks? It seems like it could be fairly useful for sites that use full page caching. All thats needed is a admin interface to load up module_invoke(). I'm throwing this out here as I don't have the time currently to do this; and it's useful in it's current form.

Comments

The Authcache module currently uses extensive use of Ajax to serve dynamic content for cached pages in this manner. While I have not encounter any serious limiations to using Ajax, there are still those who are against JavaScript having such a vital role in serving content.

If you take a look at ajax_authcache.php, there are a few methods it uses that may be good starting point:

Attempting to perform everything in a single request, instead of using multiple or separate, confined PHP files.

This allows the Ajax phase to be fairly modular for easy updating and so developers may add their own custom dynamic content.

All these steps may seem like a fairly lengthy/slow process, but with the continued improvement of JavaScript engines in modern browsers and CPU speed increasing every year, it is actually fairly responsive (Authcache example: http://authcache.httpremix.com/).

Yeah I forgot about authcache. The demo seems to do 2 ajax requests and the content type is of text/html. I just fixed my boost code so it uses drupal_json() instead of json_encode() / drupal_to_js(); you might want to do the same. Is there anyway to get your code down to 1 request per page? Also adding in a menu hook called ajax_authcache.php would be a nice trick, something I also just recently did; allows for the lazy to not have to copy the php file to the webroot.

Calling php functions from javascript seems a little scary to me (even with the authcache prefix); although it does allow for a lot.

Right now authcaches seems overly complicated, but then again I'll I'm doing is updating/populating a div with a blocks contents.

It may appear to be doing a second request because of the example block, but it is only doing one request since the example block Ajax request is cached by the browser (since that content can be cached and the first request cannot). Yeah, it's using drupal_to_js() in beta7, though I do need to change the content-type header, thanks for pointing that out!

Using hook_menu seems like a nice trick... but since it is going through the Drupal menu system, a full Drupal bootstrap is performed, and ajax_authcache.php needs to be as fast as possible since it is called on every Drupal page view when a user is logged in.

The overcomplication is really due to caching pages for authenticated users... there are so many little dynamic elements that must be accounted for! Upgrading for Drupal 7 is probably going to be pain, hah.

The hook_menu idea just inspired me on a new way to include ajax_authcache.php... since Authcache requires $conf['cache_inc'] to be defined, it can instead use Drupal's index.php bootstrap to include ajax_authcache.php and then exit before it finishes and return the JSON!

Is there a roadmap for Boost regarding caching pages for logged-in users? I am toying with the idea of what it would take to allow Authcache + Boost to run side-by-side (Authcache is actually two layers: preparing the final HTML for caching and then using a caching system to save/retrieve it).

There are no plans to have boost handle logged in users. It's hard enough only having to serve 1 version of a page. Boost & Authcache should be compatible, since they operate at a different level on the server. I enabled boost to work with drupal core cache, so there shouldn't be any issues.

Boost & Authcache should be compatible, since they operate at a different level on the server.

On the handbook page on Drupal performance resources, I've just added some detail on complementing Boost with the new Authcache module, using them for non-logged in and logged in users, respectively. I hope it's correct to assume that Authcache can be used in Cache Router's file or db modes in the case of shared hosting.

I like this idea and have thought about doing this. You don't have to do do it with JS of course - you could use iFrames for your blocks. Is there any reason you chose JS over iFrame?

One large-ish site I run has rotating ads on the left and/or random image. If I turn on caching then these become fixed on a per-page basis for anonymous users which isn't the best so a solution as described here would be nicer.

That said, I'd like to see some smarter mechanism that had all the rest of the page pre-built and only replaced certain sections within that page (the blocks for example). This could be a simple preg_replace call and should be pretty quick. I'm not smart enough to figure out how/if/when this could be done though, but caching of all but a couple of specific parts of a page would be nice for these cases.

The magic of javascript is I only have to do 1 request, and that will populate as many div's as I want. With an iframe each content block will require a new http request. Using an iframe as a fall-back could be an option. Using javascript to replace the old stale content is another option; one that I like better then multiple iframes for performance reasons. Being able to choose the degradation method, would be ideal; let the site owner choose.

This approach has advantages, but be aware that by using DRUPAL_BOOTSTRAP_FULL, you have bootstrapped Drupal fully TWICE for every page load. If you have more of such blocks, you will have more bootstraps, hence more work server side.

The sum may be a net gain or net loss depending on the complexity of the bootstrap vs. the savings from boost's caching.

When I try to do this simple trick, my server gives me a 500 error when trying to access the PHP file. The PHP file is accessible, but it appears that the 'includes' directory can't be accessed? I'm not sure why it isn't working. Can anyone help? Please ask me the right questions if I haven't told you the right info.

If I replace the contents of the PHP file with

<?phpprint "hello world";?>

it can be accessed just fine.

Even if I give the 'includes' directory and contents full 777 access, the bootstrap file still cannot be viewed in my browser. (403 error)

Real nice tutorial. What if I don't need to load a block, just a variable? I'd like to dynamically retrieve the subtotal from Ubercart on page load, then tell the customer how much more they need to purchase to get FREE shipping. See example here (i.e. yellow box msg in middle-right):

Try adding your lines of code one at a time. Which one causes it to fail? If it's the include, then I suppose it could be permissions. If it's the module_invoke call, try another module/block/delta combination - or even a custom block.

The 1.1 version of the Ajaxify Regions module is a lot better then the 1.0 version.

Configuration is at admin/settings/performance/ajaxify-regions. It works by the block ID from what I can tell.
Example is I have a view with blocks called homepage_sponsors. If I wanted to ajax 2 blocks I would put this in the "Ajax replace specific blocks:" section.views-homepage_sponsors-block_*

The css ID for these blocks are
block-views-homepage_sponsors-block_1
block-views-homepage_sponsors-block_2

HI ALL
I need some help regarding a feature that is present in http://easypetmd.com/node/57. When you click on a body part its features are presented in a pop up .Content is loaded via ajax in two tables present on right side when we select an option from right side. I need the same feature. Can anyone give me some similar example in jquery or javascript which i can use?

Then on uc_ajax_cart.module, on line 358 put a false on the condition because they check for the cached block all the time. Basically what this does is disables the block caching for the ajax cart and always returns dynamic content.