Categories
Security Technology wordpress

ajaxizing

Following from my previous post, I’ve come across another issue related to caching in wordpress: dynamic content. There’s a constant trade-off between caching and dynamic content. If you want your content to be truly dynamic, you can’t cache it properly. If you cache the whole page, it won’t show the latest update. W3 Total Cache, WP Super Cache and others have some workarounds for this. For example, W3TC has something called fragment caching. So if you have a widget that displays dynamic content, you can use fragment caching to prevent caching. However, from what I worked out, all it does is essentially prevent the page with the fragment from being fully cached, which defeats the purpose of caching (especially if this widget is on the sidebar of all pages).

The best solution for these cases is using ajax, to asynchronously pull dynamic content from the server using Javascript. So whilst many plugins already support ajax, and can load data dynamically for you, many others don’t. So what can you do if you have a plugin that you use, and you want to ‘ajaxize’ it?? Well, there are a few solutions out there. For example this post shows you how to do it, and works quite well.

The thing is, I wanted to take it a step further. If I can do it by following this manual process, why can’t I use a plugin that, erm, ‘ajaxizes’ other plugins?? I tried to search for solutions, but found none. So I decided to write one myself. It’s my first ‘proper’ plugin, but I think it works pretty well.

Ajaxize

The plugin allows you to take any wordpress function and ‘ajaxize’ it into a special div. Typically, all plugins and core wordpress functionality boils down to a number of php functions. If you are able to figure out which function your plugin uses to output content, you can ajaxize it. How do you find the function name? This is not that complicated. Many plugins will actually tell you which function to use. For example, if you want to embed the output in one of your templates. They will instruct you to use something like this:

<?php echo plugin_function_name(); ?>

So all you have to do is take this ‘plugin_function_name’, and ajaxize it using my plugin. The output is a div which looks like this:

<div id="ajaxize_this:plugin_function_name:68e46660f7ce3bc77a51465219df5743879544bc"></div>

Then place this div inside your page, post, widget, header, anywhere really. The ajaxize plugin adds a small javascript that will find this div, and convert it automatically into an ajax call for you!

There are a few limitations though:

  • Functions must return valid HTML – this will be called in php and returned via the Ajax call
  • Functions cannot accept any parameters (at least at the moment)
  • Functions that work within a context (e.g. of a post, page, category), will most likely lose the context information

UPDATE: version 1.1 of the plugin now handles context much better. Ajaxize is now hooking in the right place, so the ajax call is made exactly where the div element is placed. This means plugins that use a post/category/taxonomy context information can now also be ajaxized. Special thanks to One Trick Pony for helping me figure out how to hook this correctly.

This was a perfect solution for mixing caching with dynamic content. I can convert almost any plugin or widget into a div. I can also write very simple PHP functions that will show dynamic content on my pages, with zero extra javascript code. The div itself can be cached, but the content will be pulled automatically by the browser when the page loads. I also found it useful for loading plugin buttons like Facebook like and Twitter tweet. Those can take a while to load and slow the page. When converted via ajaxize, they still take a while to load, but don’t seem to hold the page content from loading first.

What about security?

Some of you may have already started thinking… “but hang on a minute. If you can ajaxize one function, what stops somebody from calling other functions on my wordpress??!!”. Very true. This is why ajaxize was built-in with security in mind. It uses a very powerful algorithm called HMAC, with a secret key, so you can use ajax on any function you like, but only those functions and not others. This also means zero-configuration. The plugin only stores one value in the database – this is your secret key! I might cover the security aspects of the plugin on a future post. I encourage people to look through the code and validate the security I’ve implemented.

Feel free to try it out and let me know what you think!

9 replies on “ajaxizing”

Will give this a go later, looks like a good solution.

Can a user whitelist the functions that he wants to make available? I see the long security string after plugin_function_name in that div but it’s not clear how that stops other functions being used.

The general principle is similar, but not exactly, since HMAC uses symmetric alogirthms. That means there’s no private/public key pairs. Instead it uses one key.

The secret key is stored internally and is used to generate and then check the HMAC signature. Since you’re the only person knowing the key, only you can generate the right signature on the div.

and to clarify even further: Yes. The signature is generated for the specific function name. If you change even one character, the signature will no longer be valid. And nobody else can generate your signature, because they would need your secret key.

Interested to hear your opinion about the plugin Donncha.

I can see how this can be useful, but without the ability to pass parameters to the PHP function its use becomes very limited.

I would, for example, love to combine this plugin and http://sixrevisions.com/wordpress/custom-fields-search/ to create an asynchronous filtering system based on custom fields. As it looks right now, though, I’d be better off doing it through jQuery’s AJAX feature.

Ajaxize is by no means a fully comprehensive solution to all ajax-related stuff. Many things you’d still have to code on your own, or plugin developers need to provide in their plugins.

I wanted to check out how to do things simply first. The aim was addressing the various plugins that display context-less information. For example, quotes, weather, top picks/posts/pages, faster load times to facebook/twitter buttons etc. It can probably be extended to accept parameters, but it might make things more complicated.

I’m trying to work out a way to draw at least some context information, e.g. from the referrer header passed to the ajax call. Then set this context info somehow so the PHP functions that get called ‘knows’ which page you are on, gets access to $POST->ID etc.

Feel free to contribute code/ideas, and I’d be happy to consider improving the plugin.

Short answer is no. You can’t have the cake and eat it. If you want the content indexed, it must be there and available without any javascript, in plain html. If you want it dynamically loaded using javascript, so you can cache the page, but still provide dynamic content to users – it won’t be indexed.

Leave a Reply

Your email address will not be published. Required fields are marked *