Create an Ajax service

What is an Ajax service?

An Ajax service collects and returns data as an XML file. This service will be called dynamically via an Ajax request and will be processed by some Javascript to update a part of a Doctlear administration page. This is, for instance, what is used to display the list of tags when writing a post. When clicking See all tags link, the associated Ajax service is called, returns the list of tags, and this list is displayed to the user.

Prerequisites

To create an Ajax service, you will need to:

  • Create a public and static PHP function. This function will be the one returning the expected results.
  • Declare the new service to Dotclear.
  • Call the service and process the data using Javascript.

Note:

In the following part, we will create a service to dynamically display, on the post creation page, the time left before a scheduled post is put online.

Service creation

The function name will be the service identifier. Be careful not to choose a name that is already used by another service. In our case, we will call it getPostRemainingTime.

<?php
 
class myPluginRestMethods
{
	public static function getPostRemainingTime($core,$get)
	{
 
	}
}
 
?>

Note:

As a convention, we will write our services code in the _services.php file, in the plugin root. If you wish to use several services, they can all be written there.

To retrieve the wanted information, we need the current post ID. We will get it using the id parameter that is passed in the URL. We also need the $core object to retrieve the post associated to this ID. In order to do this, we will use the parameters of the method defined earlier:

$id = isset($get['id']) ? $get['id'] : null;
 
$rs = $core->blog->getPost(array('post_id' => $id));
 
$date = strtotime($rs->post_dt);
 
# Time difference (in seconds) between now and the publication date
$delta = $date - time();

Now we have the information we need, it is possible to manipulate it to use the format we want. We can for instance pass the format we want as a parameter in the URL and convert the $delta accordingly. After that we have to return this data as an XML. For this, Dotclear has a special xmlTags class allowing to create this kind of structure very easily. As a convention, our responses will be encapsulated in a rsp node:

# Creation of the wrapper
$rsp = new xmlTag();
# Add the "value" node in the "rsp" node containing the $delta variable
$rsp->value($delta);
 
# Return everything
return $rsp;

The generated XML file will look like this:

<rsp status="ok">
	<value>65765432456</value>
</rsp>

Note:

It is possible to add attributes to the node, and to combine them. For more details, you can check the other plugins using this system, or you can check Dotclear itself!

Service declaration

Dotclear uses its own generic service dispatcher in the services.php file. To use it, the service has to be declared to Dotclear using the following method:

$core->rest->addFunction('getPostRemainingTime',array('myPluginRestMethods','getPostRemainingTime'));

This code has to be put in the plugin _prepend.php file. Now our service is declared, we can access it throught the ADMIN_URL/services.php?f=getPostRemainingTime&id=1 URL. Check if it works correctly before going further.

Note:

Don't forget to load the _services.php file before declaring the service.

Data processing

We will now go through the Ajax part of the service. The Javascript shown here will allow us to request data to the service and to display the response in the page without reloading it. We are going to use jQuery, which is bundled with Dotclear:

$(function(){
	$('#remaining-time').click(function(){
		$.get('services.php',
		{f: 'getPostRemainingTime',id: $('#id').val()},
		function(rsp){
			$('#remaining-time-display').html('<p>Remaining time before online publishing:'+$(rsp).find('value').text()+'</p>');
		});
	});
});

When clicking on the element with ID remaining-time, a request is made to the getPostRemainingTime service, passing the service we want to use and the current post ID (retrieved using the hidden id field of the form) as parameters. The response is displayed in the block with ID remaining-time-display.

Error handling

The code above does not handle errors that may happen when requesting the service. The advantage of using the xmlTags class to generate the XML is that if an exception is raised, the returned XML will look like:

<rsp status="err">
	<message>Exception message</message>
</rsp>

For instance, for our service, if no ID is passed in parameter, we will raise an exception to inform the user:

$id = isset($_GET['id']) ? $_GET['id'] : null;
 
if ($id === null) {
	throw new Exception(__('No ID given')); 
}

It is therefore very easy to catch this kind of XML to handle it differently. For instance:

$(function(){
	$('#remaining-time').click(function(){
		$.get('services.php',
		{f: 'getPostRemainingTime',id: $('#id').val()},
		function(data){
			var rsp = $(data).children('rsp')[0];
			if (rsp.attributes[0].value == 'ok') {
				$('#remaining-time-display').html('<p>Remaining time before online publishing:'+$(rsp).find('value').text()+'</p>');
			} else {
				alert($(rsp).find('message').text());
			}
		});
	});
});

This code will inform the user through an alert() message that an error appeared when requesting the service, or during the service processing.

Wiki powered by Dokuwiki.