Rapid Development Techniques – Templates Within Templates!
Have you ever been frustrated with Joomla!’s linear approach to templates? I’ve developed several web applications in Joomla! where it would have been useful to be able to include a template inside of another template – an internal menu system, a special footer for specific components, etc – and in the past I’ve gotten around this limitation with good old fashioned PHP include statements. While this method works we can have much prettier and more maintainable code by extending Joomla!’s JView class to support this functionality.
Note: This article is slanted toward people doing custom development for their own individual Joomla! installs. If you’re doing third-party extension development you’ll need to get a bit more creative with your solution.
If you recall I wrote an article several months ago about extending Joomla!’s internal classes to alleviate repetitive tasks – if you haven’t done this before I would suggest that you go and read that original article. This isn’t going to be rehash of why you should extend the core classes but rather a look at a real-world example that will yield some benefit to your development.
In the original article about extending Joomla!’s MVC architecture, we created a new library called “Custom” in the libraries folder and created a “CustomView” class that extended JView. We’ll be using that same class today and creating a new method called “loadSubTemplate”, which we will base off of JView’s “loadTemplate” method.
So what do we need to do inside of our new method, “loadSubTemplate”? What we’ll shoot for is loading a separate template file and capturing all of the output instead of doing a straight “echo” – this will be useful for a number of reasons, but it does mean you’ll need to explicitly “echo” the output yourself wherever you want the sub-template to appear.
Since these templates will be shared across the component, I usually keep these sub-templates clustered into a separate folder called “shared” within my view folder. There isn’t any particular need for this – I simply see it as good organization but the big thing here is consistency: if you’re developing multiple extensions then consistency in design will serve you well in the long run, especially as you extend the Joomla! framework to suit your needs.
Here’s the code for “loadSubTemplate”, tested on Joomla! 1.5.
class CustomView extends JView
public function loadSubTemplate($name)
jimport( 'joomla.filesystem.path' );
//Find the sub-template file
$fileToFind = $this->_createFileName('template', array('name' => $name));
$subTemplate = JPath::find($this->_basePath.DS.'views'.DS.'shared', $fileToFind);
//Prepare to capture sub-template output
//Include the sub-template
//Get the output
$output = ob_get_contents();
//Clean the output buffer so we don't pollute later renders
//Return the output
return JError::raiseError( 500, 'Sub-Template "' .$name. '" not found.' );
Now, for your view class make sure that you are extending CustomView instead of JView, otherwise we won't have access to this method! In the directory structure of your component, inside of "views", create a folder called "shared" and a file inside called "subpage1.php". You can treat this file as if it were a regular template and it will have access to the same methods and variables that a normal template would. Here's the code for including the sub-template.<?php echo $this->loadSubTemplate('subpage1'); ?>
One thing to note before we go any further is that we aren’t loading separate view classes for each sub-template – we are only loading templates. This means that the view you create originally is the “master view” for the entire process, including any sub-templates. You will be able to use any variables you pushed to the template using assign() or assignRef() in the view class.
You may have noticed already but the code I’ve provided doesn’t support template overrides. This is an easy fix, but I’ll leave it to you as a challenge to get template overrides working properly. That’s all! You have successfully nested a template within another!