WordPress in a Subdirectory and XML-RPC

Quick Tip! If you’re experiencing problems with the WordPress mobile application because your WordPress installation is in a subdirectory¬†(for example wordpress) you should copy the xmlrpc.php¬†file to your website root so it’s accessible via example.org/xmlrpc.php and edit the boostrap path in that file to point to your subdirectory:

/** Include the bootstrap for setting up WordPress environment */
include('./wp-load.php');

Change the include path to your subdirectory, in our case it’s wordpress:

include('./wordpress/wp-load.php');

That should do the trick, although I’m still not sure why it doesn’t work out of the box, since the path to the XML-RPC discovery in the head section of the homepage is correct. Anyways, this might be a temporary solution to internal server errors (500) and not found errors (404). Enjoy :)

Custom XML-RPC Methods in WordPress

With more and more talk around WordPress 3.0 it seems that the system is gaining even more popularity than ever before due to it’s extensibility. Today I’d like to discuss a topic that might not be of much use to bloggers and basic websites, but is generally required in larger projects – XML-RPC. It’s not limited to WordPress 3.0, but as custom post types are on their way in 3.0, we’ll probably see tonnes of new ways WordPress being used.

In general terms (and as written in the Codex), XML-RPC is simply a way of pushing in and pulling out data of a WordPress blog. Used primarily in offline blogging clients such as Windows Live Writer, a few Firefox addons and mobile clients, all of which support a set of XML-RPC blogging APIs. Okay that’s fine, but not used too much, especially in complex systems, as the standard APIs don’t support:

  • Slug corrections
  • Custom taxonomy
  • Custom post types
  • Custom fields

Which of course is easier to do via the standard WordPress admin panel, especially if meta-boxes are well-designed and implemented. So today’s use of XML RPC in WordPress is limited to blogging.

Now, suppose you have some complex system, let’s say a real estate agency website, where properties are listed, locations as taxonomies and property details as custom fields (number of beds, baths, geo location, etc). There’s no way to input this stuff via the standard XML RPC clients, nor the standard XML RPC API which comes with WordPress. Not too useful I know, since when posting properties agents should be careful to the info the input, thus it’s much wiser to use a computer than a phone or something, but..

Suppose your real estate agency has a CRM they’ve been working in for years. Wouldn’t it be nice if the CRM could insert/change property info directly into the website, without having the agents even look at the WordPress admin panel? That, my friends, could be done via custom XML RPC queries.

Basically, anything could be converted into an XML-RPC query, even the most rediculous stuff, such as changing the title of the homepage. This means that if you have enough time and patience, you could build your own (could be stand-alone) admin panel for your website, fully based on XML-RPC calls. Remember those APS.NET content management systems that are managed from standalone .NET applications? ;)

One more example of XML-RPC usage, which I actually implemented a few days ago – data replication between two websites in different languages. Let’s go back to the real estate example, say this agency has two websites – one in English (.com) and one in Russian (.ru). The English agent got all the data for a new property listing so he publishes it on the .com website. As soon as the post is published, an XML-RPC query is fired at the .ru website, where all the data, filtered through Google Translator or something, is saved as a draft. This way, the Russian agents login to the system, see that there are new drafts, open them up, correct the translations and publish. Voila! No more e-mails back and forth with 4GB of photos ;) Oh, didn’t I mention? Files could also be sent via XML-RPC if done correctly!

Alright, stop the theory, let’s talk some code! The filter used to extend the currently supported XML-RPC methods is called xmlrpc_methods and is located somewhere in xmlrpc.php in your WordPress root directory. There’s a list of all supported methods there, so feel free to disable some or add your own:

add_filter('xmlrpc_methods', 'my_xmlrpc_methods');
function my_xmlrpc_methods($methods)
{
	$methods['myMethod'] = 'my_function';
	return $methods;
}

This will add a new XML-RPC method called myMethod, which would fire my_function. I think the callback function is supposed to be global here and could not be wrapped up into a class and passed on as an array. Not sure for what reason, but it seems that the WordPress environment is not fully initialized during XML-RPC calls, thus only the init and other top-level actions are being fired, perhaps there’s a reason behind that.

Anyways, the next step is to do something in my_function:

function my_function($args)
{
	// Parse the arguments, assuming they're in the correct order
	$username	= $args[0];
	$password	= $args[1];
	$data = $args[2];

	global $wp_xmlrpc_server;

	// Let's run a check to see if credentials are okay
	if ( !$user = $wp_xmlrpc_server->login($username, $password) ) {
		return $wp_xmlrpc_server->error;
	}

	// Let's gather the title and custom fields
	// At a later stage we'll send these via XML-RPC
	$title = $data["title"];
	$custom_fields = $data["custom_fields"];

	// Format the new post
	$new_post = array(
		'post_status' => 'draft',
		'post_title' => $title,
		'post_type' => 'property',
	);

	// Run the insert and add all meta values
	$new_post_id = wp_insert_post($new_post);
	foreach($custom_fields as $meta_key => $values)
		foreach ($values as $meta_value)
			add_post_meta($new_post_id, $meta_key, $meta_value);

	// Just output something ;)
	return "Done!";
}

There, it’s pretty much self-explanatory. We assume that the XML-RPC query contains the username, password and an array of data where the title and custom_fields are defined. This is pretty much all XML-RPC customizing that has to be done, and the final part is actually running the call which should be a well-formated XML-RPC query. We’ll use the xmlrpc_encode_request php function for that, and the WP_Http class to actually send the request:

$post_id = 1; // Replace with post_id you need to send
$wp_query = new WP_Query("p=" . $post_id);
if ($wp_query->have_posts())
{
	$wp_query->the_post();
	$custom_fields = get_post_custom($post_id);

	// This is the data being sent as the third argument in XML-RPC
	// Could be an associative array
	$data = array(
		"title" => $this->get_the_title(),
		"custom_fields" => $custom_fields
	);

	// Format the XML RPC query params, format the request
	// We're using myMethod which we defined above
	// Assuming the username is admin and the password is 1 ;)
	$params = array("admin", "1", $data);
	$params = xmlrpc_encode_request('myMethod', $params);

	// Initiate a new HTTP carrier and fire the request, sending the parameters
	// using the POST method. We could then capture the result by reading $result
	$request = new WP_Http;
	$result = $request->request('http://domain.org/xmlrpc.php',
		array('method' => 'POST', 'body' => $params));
}

All done! The code above clearly shows how to format a simple XML-RPC request using php and you should’t have any trouble doing this in other programming languages (perhaps for standalone software). One more thing to do is enable XML-RPC support in the Writing section under Settings in the blog that’s supposed to receive the requests (though the HTTP result usually states if there are any problems).

This is only an example, perhaps not too useful, but extending it to send over images, videos, etc automatically would speed up the whole process. Writing a special mobile client for agents would also be an awesome idea. And not only real estate! All this is applicable to any kind of products or services, anything that is slightly bigger than just a post with a title and some text ;)

So, what do you use XML-RPC for? What XML-RPC clients do you prefer? And are you willing to write a standalone application based on XML-RPC as the admin panel of a WordPress blog if your clients don’t like the usual backend?

Cheers!

Windows Live Writer

The Pro Web 2.0 Mashups book I wrote about earlier is going great and I finally got to the blogging chapters. Standalone blogging, yeah that was a news for me. I mean it is obvious that offline/standalone blogging is applicable to WordPress and other blogging systems, and that’s one of the main reasons why the XML-RPC protocol is supported by them, right? Well I just didn’t see the benefits of offline posting.

Actually, this is my very first offline post, so I’m not so sure that it’ll come out safe and sound, but I really do trust Microsoft in some ways, although I’m in love with Fedora Linux. Anyways, Microsoft Windows Live Writer seems great and has lots of cool features. It’s not just a plain-text editor that’ll post through XML-RPC, so I suggest you check it out: http://get.live.com/writer/overview. It supports most of the blogging systems that we use today.

I’m currently experiencing problems linking it to my russian weblog, maybe it’s because I self-customized the theme (losing some meta tags), or just no wordpress 2.6.2 support. I’ll be sure to upgrade and check that out next week.

UPD 5 minutes later: Yup yup! ;)