Shopping Basket


 x 

Cart empty


Log In

Find Us Elsewhere

SSL

Forum Search

Keyword

If you are a Joomla! developer you are probably already aware that you are not restricted to generating html output from an extension. In fact it is possible for the CMS to output any type of content that you want, simply by creating a view for it in your component using the appropriate format.

The purpose of this article is to explore how to do this when the output type is not among those currently supported in the Joomla core. In fact this is not a problem, as I will show. I will do this in the context of generating an SVG (scalable vector graphics) image, but the principles will be the same for any output type.

In the examples I assume that we have already grabbed the image data in some way, without specifying where it comes from, in order to concentrate on how to output it. However the nice thing about SVG is that it is just XML, so it could quite easily be generated dynamically by the CMS using data from a database table.

Creating a View

In order to generate the output, you need to create a view for it, and place it in the Joomla views folder, in the same way as for a normal Joomla html page. Instead of calling the view 'view.html.php', we name it after the output type we want, eg 'view.svg.php'.

svg view

In this example, to actually load the generated image we use the url index.php?option=com_example&view=item&id=1&format=svg. Simply by adding the url parameter 'format=svg' we tell Joomla that the output will be of type svg. This trick will work with any Joomla url, in order to obtain the output in an alternative form to html, for example we can often use 'format=feed' to get an RSS feed of a page. All that is required is a corresponding view of the correct type.

So how does this work? Joomla's output is normally handled through the JDocument class, which includes several predefined document types as child classes, such as 'feed', 'xml','json'. If the type corresponds to one of these predefined classes then Joomla will know to load that document class, and the class will render the output through its own render() method. Joomla does not include any support for SVG documents, however if the format parameter does not correspond to a known document type then the document will be set to a special type of 'raw', which allows great flexibility in the type of output that can be generated.

Displaying the Output

The file view.svg.php must contain a display() method, just like an html view, and it is this method that generates the output. There are actually several ways of approaching it, depending on how sophisticated you want to be.

Simple Example of a Display Method

	public function display($tpl = null)
{ do{
//clean all output buffers
} while(@ob_end_clean());
$this->data = $this->get('Data'); header ( "Content-Type: image/svg+xml; charset = utf-8", true); echo $this->data; jexit(); }

Notice that we first try to clear all the output buffers, that is to try and stop any other data being accidentally sent along with the data that we want to output. For the same reason we put jexit() at the end of method. Ideally this should not be necessary, but a lot can happen during the generation of a Joomla page, for example system plugins designed to work on Joomla html pages can modify the output and often the developers do not think to check the output type. SVG images are XML, which will be invalidated by such things as adding extra tags, or whitespace.

This method is simple and will normally work, but is a bit unsatisfactory. It is a bit of a hack really, and essentially bypasses the Joomla document by forcing the output directly.

A more 'Joomla' way of doing things is this:-

Example 2

	public function display($tpl = null)
{
$this->document = JFactory::getDocument();
$this->document->setMimeEncoding('image/svg+xml');
$this->document->setBuffer($this->data);

echo $this->document->render();
jexit(); }

I would still put jexit() at the end, just in case. Notice that we still have to force the mime type as 'image/svg+xml', otherwise Joomla will send the mime encoding header as text/html.

Example 3

In many cases this will be all that you need. Still it might be nice if we could actually create our own SVG document type, and have Joomla use it when the document object is instantiated, then we would not need to remember to force the mime encoding because the document object would handle this itself. It turns out that this is perfectly possible, we can create our own JDocumentSvg class which extends the base JDocument class. All that we need to do is to create the class, put it in a file called for example 'svg.php', then tell the Joomla autoloader where to find it, this is an example of the code that you use for this:-

JLoader::register("JDocumentSvg",JPATH_SITE."/components/com_example/classes/svg.php");

Then when the document object is instantiated, Joomla is smart enough to load the correct class.

Unfortunately you cannot register the class in the view display method, the reason being that by then the Joomla document will already have been created. Because the autoloader at that point will not know where to find the classes, the document will be given the fall-back type of 'raw'. If you want to register your own document class, you will need to do this in a system plugin, in the onAfterInitialise() method, like this:-

class PlgSystemExample extends JPlugin {

 	public function onAfterInitialise()
 	{

 		JLoader::register("JDocumentSvg",JPATH_SITE."/components/com_example/classes/svg.php");

 	}
}

The Joomla document object should not yet exist when the onAfterInitialise system event is called, so this should normally work. Of course now we need to create the document class, it will look something like this:-

class JDocumentSvg extends JDocument {

 	public function __construct($options = array())
 	{
 		parent::__construct($options);
 		// Set mime type
 		$this->_mime = 'image/svg+xml';
 		// Set document type
 		$this->_type = 'svg';
 	} 	 

  public function render($cache = false, $params = array())
  {
 		parent::render(); 
		return $this->getBuffer();
  }
}

So then in the view.svg.php display method, all that you need to do is to grab the data, and output it:-

	public function display($tpl = null)
{ $this->data = $this->get('Data'); $this->document = JFactory::getDocument(); $this->document->setBuffer($this->data); echo $this->document->render(); }

This approach can be used with any non-standard Joomla document type.