Gantry comes with 65 module positions and the ability to add more can be done with the greatest of ease. Find out more...

Home DocumentationJoomlaAdvancedCreating a New Feature

Creating a New Feature

In the Gantry framework we use the term Feature to mean a specific bit of functionality. Features are flexible enough that they can be used to perform almost any kind of logic you would need. The base GantryFeature class contains methods that can be implemented to control how your feature functions. Those methods are:

  • isEnabled() - by default this gets its state from the enabled toggle in the admin. You can override this to force the enabling of a feature without any UI interaction.
    Returns - boolean [true | false]
  • getPosition() - by default this gets its position from the position element in the admin. Again, you can override this to force a position without any UI interaction.
    Returns - string [current position name]
  • isInPosition([string $position]) - a method to determine if the feature is located in a specified position.
    Argument - [optional] string [position name to get compared with the current position of the feature] Returns - boolean [true | false] if the current position is the same as the argument
  • isOrderable() - a method that defaults to true, but can be overriden if the order of this position is not important.
    Returns - boolean [true | false]
  • setPrefix(string $prefix) - sets a prefix for handling prefixed parameters such as chained elements.
    Argument - string [prefix name - usually the name of the main chain param]
  • get($param [, $prefixed = true]) - gets a param from the feature's configuration. Can also take a prefix for more specificity. Argument - string [parameter name] Argument - [optional] boolean [true | false] Returns - mixed [the current value of the parameter]
  • init() - by default empty. Is the first method called on initialization of a feature. Used for setup or initialization
  • render() - by default empty. Used to render output in a particular position
  • finalize() - by default empty. Called at the end of the feature

All core features and any custom feature you create, should extend this GantryFeature class. To create a new feature of your own, you would just have to create a new file in your features/ folder that extended the GantryFeature class. It will automatically get picked up by the Gantry framework and be processed. The best way to see what a feature can do for you is to examine a few of the core features.

Logo Feature

First let's look at one of the core features called logo.php. As you can imagine the logo.php feature is intended to display a logo. The most important part of a feature is the actual feature PHP file. The core features are located in the YOUR_SITE/components/com_gantry/features/ folder. These should not be touched or changed. If you want to override the behavior of a core feature, simply copy the core feature in your YOUR_SITE/templates/YOUR_TEMPLATE/features folder. Gantry will automatically pick up your version of the file and use it rather than the default version if you have created one with the same name. The other part of a feature and one that is totally optional is the configuration section. As with other parts of Gantry, the configuration is handled in the templateDetails.xml. For the logo feature the section in the templateDetails.xml looks like:

<param name="logo" type="chain" label="LOGO"  description="LOGO_DESC">
    <param name="enabled" type="toggle" default="1" label="SHOW" />
    <param name="position" type="position" default="header-a" label="POSITION" />
    <param name="autosize" type="toggle" default="0" label="AUTO_SIZE" />
</param>

What this means is that in the administrator interface, there is going to be three parameters rendered. One is a toggle element that will control the 'enabled' state. The second is position element that controls the position the feature is rendered in. The third is another toggle to control the auto-resize option for this feature. By exposing these elements in the XML, we allow interaction with the user. If you wanted to add new elements in this XML section, you could and they would be available for you to use in your feature's PHP.

Next, let's look at the PHP for this feature:

<?php
/**
 * @package     gantry
 * @subpackage  features
 * @version     ${project.version} ${build_date}
 * @author      RocketTheme http://www.rockettheme.com
 * @copyright   Copyright (C) 2007 - ${copyright_year} RocketTheme, LLC
 * @license     http://www.gnu.org/licenses/gpl-2.0.html GNU/GPLv2 only
 *
 * Gantry uses the Joomla Framework (http://www.joomla.org), a GNU/GPLv2 content management system
 *
 */

defined('JPATH_BASE') or die();

gantry_import('core.gantryfeature');

/**
 * @package     gantry
 * @subpackage  features
 */
class GantryFeaturelogo extends GantryFeature {
    var $_feature_name = 'logo';
    var $_autosize = false;

    
    function render($position="") {
        global $gantry;


        // default location for custom icon is {template}/images/logo/logo.png, with 'perstyle' it's
        // located in {template}/images/logo/styleX/logo.png
        if ($gantry->get("logo-autosize")) {

            jimport ('joomla.filesystem.file');

            $path = $gantry->templatePath.DS.'images'.DS.'logo';
            $logocss = $gantry->get('logo-css','body #rt-logo');

            // get proper path based on perstyle hidden param
            $path = (intval($gantry->get("logo-perstyle",0))===1) ? $path.DS.$gantry->get("cssstyle").DS : $path.DS;
            // append logo file
            $path .= 'logo.png';

            // if the logo exists, get it's dimentions and add them inline
            if (JFile::exists($path)) {
                $logosize = getimagesize($path);
                if (isset($logosize[0]) && isset($logosize[1])) {
                    $gantry->addInlineStyle($logocss.' {width:'.$logosize[0].'px;height:'.$logosize[1].'px;}');
                }
            } 
         }

        ob_start();
        ?>
            <div class="rt-block">
                <a href="/<?php echo $gantry->baseUrl; ?>" id="rt-logo"></a>
            </div>
        <?php
        return ob_get_clean();
    }
}

As you can see the ONLY method that is used is the render() method. The other methods from the base GantryFeature class are not overridden. That means that the standard methods to get the enabled state, position, etc are being used and are pulling that data from the XML and the admin settings. You can see how custom XML parameters like autosize are easily available and are prefixed by the feature name, so you can just get logo-autosize to get the value for the 'chained' element logo -> autosize.

MooTools Feature

Next, let's have a look at a custom feature I created for the gantry-framework.org site. We wanted to use MooTools 1.2 for this site, but as we are running in Joomla 1.5, the default version of MooTools is 1.1.12. To change the version of MooTools we created our own custom feature and put it in the features/ folder of our template. The name of the feature is not important, any file found in this directory that extends GantryFeature will automatically be processed.

This feature is a bit of core functionality that doesn't need any user interaction, so we didn't create any section for it in the templateDetails.xml file. All we did was create this moo12.php file:

<?php
/**
 * @package     gantry
 * @subpackage  features
 * @version     @VERSION@ @BUILD_DATE@
 * @author      RocketTheme http://www.rockettheme.com
 * @copyright   Copyright (C) 2007 - @COPYRIGHT_YEAR@ RocketTheme, LLC
 * @license     http://www.gnu.org/licenses/gpl-2.0.html GNU/GPLv2 only
 *
 * Gantry uses the Joomla Framework (http://www.joomla.org), a GNU/GPLv2 content management system
 *
 */

defined('JPATH_BASE') or die();

gantry_import('core.gantryfeature');

/**
 * @package     gantry
 * @subpackage  features
 */
class GantryFeatureMoo12 extends GantryFeature {
    var $_feature_name = 'moo12';

    function isEnabled(){
        return true;
    }

    function isInPosition($position) {
        return false;
    }

    function isOrderable(){
        return false;
    }

    function init() {
        global $gantry;
        
        $doc =& $gantry->document;
        
        JHTML::_( 'behavior.mootools' );  
        
        //remove default mootools from default includes
        $oldmoo = JURI::root(true) .'/media/system/js/mootools.js'; 
        $newmoo = $gantry->templateUrl.'/js/mootools-1.2.4-core.js';
        
        $a = array();
        foreach ($doc->_scripts as $k => $v) {
            if ($k == $oldmoo) { $a[$newmoo] = $v; }
            else { $a[$k] = $v; }
        }
        $doc->_scripts = $a;
    }

}

as you can see we have overridden a few of the base methods. This is because we have no UI we want to hard-code some of the settings. For example, we are forcing the enabled setting to be true. Also we are setting the isInPosition() method to false. This means that this feature will be ignored by the layout rendering process as it doesn't need to be output in a position. Also the isOrderable() method is set to false, as the order of this feature in relation to other features is not important.

There is no render() implementation as this feature is not intended to be rendered in a layout like the logo feature for example, rather all it's functionality is contained in the init() method. In this case the purpose of this features is to find the old reference in the document's _script variable of the default Joomla MooTools 1.12 library, and replace it with a reference to a newer MooTools 1.2.4 version that we have provided in the template.

Have a look through all the default features that come with Gantry to see how we achieved a wide variety of functionality with these features.