Actions

Advanced topics

From Joomla! Documentation

Revision as of 17:36, 18 December 2012 by Tom Hutchison (Talk | contribs)

Contents

How are templates executed?

Templates are executed in a 2-phase process that makes full use of the PHP parser to provide considerable flexibility and performance to the template designer. Templates are executed in the context of the document object so that the $this object is always the instantiation of the JDocument class.

Before template execution begins, the component will have been executed and its output buffered for later use.

Template execution then proceeds as follows:-

  • template parameters (if any) are loaded.
  • template language (if any) is loaded.
  • if legacy mode is on then the configuration variables are copied as globals.
  • the template file (index.php) is loaded and executed (by PHP). The output is buffered. This is phase 1 of the 2-phase process. Everything between <?php and ?> tags is executed as PHP code. Everything outside of these tags is output but otherwise ignored. As the output is being buffered, nothing is sent to the client web browser at this stage.
  • a favicon.ico file is looked for, first in the Joomla! root directory, then in the template root directory. The latter will override the former if found.
  • the output that was buffered in phase 1 is now parsed for <jdoc:include> elements. This is phase 2 of the process. For each jdoc element found, the appropriate renderer class is loaded and its render method is called. The output from the render method replaces the <jdoc:include> element itself in the output buffer. In the case of module renderer classes this triggers the execution of the modules and the buffering of their output.
  • Certain template-specific HTTP headers are added to the list of headers to be output.
  • Control is then passed back to the JApplication object which will handle the rest of the process of getting the now rendered web page back to the client web browser.

System error pages

Error Page Templates

By default Joomla! uses special templates when it needs to raise an error response. These are located in the templates/system directory. For server-level status codes these are named for the status code that is being raised. The default system error pages are:

  • templates/system/403.php (Status code: 403 Forbidden)
  • templates/system/404.php (Status code: 404 Not Found)
  • templates/system/500.php (Status code: 500 Internal Server Error)

In addition, these system error pages are also available:

  • templates/system/component.php (not sure when this is used)
  • templates/system/offline.php is used to render the "site is offline" message.

Note that jdoc:include elements are not parsed in these error pages.

The status codes are defined as part of the HTTP protocol in RFC2616. For further information on HTTP status codes see: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html

Styling the Error Pages

These pages can be styled using the following CSS classes:

  • errorboxheader
  • errorboxbody
  • techinfo


Custom error pages

Joomla! uses the templates/system/error.php file to handle several HTTP Status errors, including "403 Forbidden", "404 Not Found", and "500 Internal Server" errors. You can style the error results, if desired.

It is important to understand that error.php is an independent file from the Joomla! CMS but dependent on the Joomla! Platform. Plugins do not run on the file. You cannot include modules or use <jdoc:include> statements.

Overriding the System Error Results

To override the system error results, copy the templates/system/error.php file into your templates/<template-name> directory.

If it finds one, Joomla! will use the error.php file from the current template, in place of the system file.

You can format the page, as desired, to match your template.

Overriding the System Styling

If you want to change the styling, copy the templates/system/css/error.css file into your templates/<template-name>/css directory.

Next, update your templates/<template-name>/error.php file to reference the new location of the stylesheet by changing this line, accordingly:

<link rel="stylesheet" href="<?php echo $this->baseurl; ?>/templates/system/css/error.css" type="text/css" />

Then, simply change the error.css, as desired, for your styling requirements.

Customizing Error Messages

You can add conditional logic to vary the message returned, dependent upon the specific error code.

Here is an example of how to trap a 404 error and provide a custom message.

<?php  if ($this->error->getcode() == '404') { ?>
        <div id="errorboxheader">Page not found</div>
                <div id="errorboxbody"><p>Sorry! That page cannot be found.</p>
                </div>
        </div>
<?php } ?>

HTTP Status Code

When a request is made for a page on your site, the server returns an HTTP status code in response to the request. Joomla! returns a '200 - the server successfully returned the page' for error pages. This is problematic for those working with Google Webmaster Services and trying to get a sitemap resolved.

If you want Joomla! to return a status code for the error, you can do so by adding logic before the DOCTYPE line, as follows:

<?php 
if ($this->error->getcode() == '404') {
        header("HTTP/1.0 404 Not Found");
} ?>

More HTTP Status Code Information

Using Theme Header and Footer on Standard Error Page

Joomla 1.5 If you want to see the error page in theme design and don't like redirecting to error page URL or duplicating HTML in the error page template, here is a way to apply your theme template to the error page.

First, put the following code in templates/<template-name>/error.php:

<?php
// no direct access
defined( '_JEXEC' ) or die( 'Restricted access' );
 
include dirname(__FILE__) . "/index.php";
?>

Then make the following edits to templates/<template-name>/index.php::

1. Find the following code in index.php

<jdoc:include type="head" />

and replace it with the following

<?php if (!$this->error->code) : ?>
<jdoc:include type="head" />
<?php else : ?> 
<title><?php echo $this->error->code ?> - <?php echo $this->title; ?></title>
<?php endif; ?>

2. Find the following code in index.php

<jdoc:include type="component" />

and replace it with the following

<?php if ($this->error->code) : /* check if we are on error page, if yes - display error message */ ?>
  <p><strong><?php echo $this->error->code ?> - <?php echo $this->error->message ?></strong></p>
  <p><strong><?php echo JText::_('JERROR_LAYOUT_NOT_ABLE_TO_VISIT'); ?></strong></p>
  <ol>
    <li><?php echo JText::_('JERROR_LAYOUT_AN_OUT_OF_DATE_BOOKMARK_FAVOURITE'); ?></li>
    <li><?php echo JText::_('JERROR_LAYOUT_SEARCH_ENGINE_OUT_OF_DATE_LISTING'); ?></li>
    <li><?php echo JText::_('JERROR_LAYOUT_MIS_TYPED_ADDRESS'); ?></li>
    <li><?php echo JText::_('JERROR_LAYOUT_YOU_HAVE_NO_ACCESS_TO_THIS_PAGE'); ?></li>
    <li><?php echo JText::_('JERROR_LAYOUT_REQUESTED_RESOURCE_WAS_NOT_FOUND'); ?></li>
    <li><?php echo JText::_('JERROR_LAYOUT_ERROR_HAS_OCCURRED_WHILE_PROCESSING_YOUR_REQUEST'); ?></li>
  </ol>
  <p><strong><?php echo JText::_('JERROR_LAYOUT_PLEASE_TRY_ONE_OF_THE_FOLLOWING_PAGES'); ?></strong></p>
 
  <ul>
  <li><a href="<?php echo $this->baseurl; ?>/index.php" title="<?php echo JText::_('JERROR_LAYOUT_GO_TO_THE_HOME_PAGE'); ?>"><?php echo JText::_('JERROR_LAYOUT_HOME_PAGE'); ?></a></li>
  </ul>
 
  <p><?php echo JText::_('JERROR_LAYOUT_PLEASE_CONTACT_THE_SYSTEM_ADMINISTRATOR'); ?>.</p>
<?php else : ?>
  <jdoc:include type="component" />
<?php endif; ?>

Now your theme template is applied to error pages too.

Note: Module includes in template will not work on error page created by this method (but will work on other pages).

Adding JavaScript

JavaScript (also known as ECMAScript) is a scripting language primarily used in client-side web site development to extend and enhance an end-user's experience. Joomla provides developers with easy-to-use mechanisms to include JavaScript in their extensions using existing API methods.

There are a number of methods for including JavaScript in your Joomla extensions; some of these are described below.

Usage

There are three methods for embedding JavaScript into your code using the Joomla API; JDocument::addScriptDeclaration, JDocument::addScript and script. These methods should be called either in your component's View class (<yourcomponent>/views/<yourview>/view.html.php) or template script (<yourcomponent>/views/<yourview>/tmpl/<yourtemplate>.php or in the case of a module, in its template script (<yourmodule>/tmpl/<yourtemplate>.php).

Inline JavaScript

Blocks of JavaScript code can be declared directly within a component or module's display template using the JDocument class' addScriptDeclaration method:

<?php
$document = JFactory::getDocument();
$document->addScriptDeclaration('
    window.event("domready", function() {
        alert("An inline JavaScript Declaration");
    });
');
?>

External JavaScript

Alternatively, you may wish to separate your JavaScript into a separate file. Separating your JavaScript into an external file can make your template code easier to read especially if the JavaScript is lengthy or complex.

There are two ways to include a JavaScript file using the Joomla API. The first involves using the JDocument class' addScript method:

<?php
$document = JFactory::getDocument();
$document->addScript('/media/system/js/sample.js');
?>

The second uses the JHTML class' script method:

<?php
// Add the path parameter if the path is different than 'media/system/js/'
JHTML::script('sample.js', 'templates/custom/js/');
?>

API has changed in 3.x, so the second parameter cannot be a string. If you really need to use this method, you must include the absolute link to your javacript file:

<?php
JHtml::script(Juri::base() . 'templates/custom/js/sample.js');
?>

Description

The Joomla API's JDocument::addScriptDeclaration, JDocument::addScript and script methods embed JavaScript into Joomla's index.php via the jdoc head tag:

<jdoc:include type="head"/>

Using the JDocument::addScript or script methods to embed JavaScript includes would result in the index.php rendering the following HTML:

<head>
...
<script type="text/javaScript" src="/media/system/js/sample.js"></script>
...
</head>

Calling the class method JDocument::addScriptDeclaration would render the following HTML:

<head>
...
<script type="text/javaScript">
window.addEvent("domready", function() {
    alert("Embedded block of JS here");
});
</script>
...
</head>

Using these methods is highly recommended as it clearly differentiates another scripting language (JavaScript) from the main PHP code, ensures all JavaScript is correctly embedded between the <head></head> tags and, in the case of JDocument::addScript and JHTML::script ensures that a JavaScript file is included only once (I.e. there is no .js file duplication).

Using a JavaScript Framework

A Javascript framework provides developers with generic functionality for handling various coding tasks in a familiar, consistent and platform-independent way. A framework enables the developer to forget about the intricacies of implementing a certain function in different web browsers and focus on the requirements of the software.

Two Javascript Frameworks are provided as part of Joomla 3.x; jQuery and Mootools. jQuery is a newly introduced framework which integrates with Joomla's new Bootstrap HTML framework; Mootools is Joomla's legacy Javascript library which is now superseded by jQuery and is included for backwards compatibility with 3rd party extensions.

In nearly all cases you should use a framework when developing Javascript in your extensions or templates and including one is very simple with Joomla's API.

Joomla 3.x jQuery

Please see the guide on Javascript Frameworks in Joomla 3.x for information about including a framework in Joomla 3.x

Joomla 1.5/2.5 Mootools

Unless you are maintaining Javascript code which leverages Mootools or you are developing an extension for Joomla 2.5 or earlier it is recommended you use jQuery instead.

Firstly, you will need to include the Mootools code in your extension. To include the Mootools framework in your extension, you add the following code to your view.html.php or tmpl file:

FOR JOOMLA 1.5

JHTML::_('behavior.mootools');

FOR JOOMLA 2.5

JHtml::_('behavior.framework');

The above code results in the same outcome as the similar jQuery framework statement; that is it ensures Mootools is included correctly and only once.

Then using Mootools is almost identical to jQuery:

JFactory::getDocument()->addScriptDeclaration('
window.addEvent("domready", function() {
    alert($("list").getElements("li").length);
});
');

More information about Mootools is available at http://mootools.net/. For API documentation, visit http://mootools.net/docs/core.

See Also

JHtmlBehaviour::framework method from the Joomla! Framework 11.1 documentation

Ajax using MooTools

Adding Javascript moo.fx to your component

External Links

http://api.joomla.org/Joomla-Platform/HTML/JHtmlBehavior.html#methodframework

http://en.wikipedia.org/wiki/JavaScript

http://www.w3schools.com/js/default.asp

http://mootools.net/

http://jquery.com/

How to determine browser capabilities

Different web browsers sometimes show differences in the way that they render a page. For this reason you may wish to find out which particular browser a visitor is using, in order to use some browser-specific CSS.

The following JavaScript defines a simple browser detection object which determines the browser's name and version by decoding the navigator.userAgent string.

function browserDetect()
{
  var browserNames=new Array("Opera", "MSIE","Netscape","Firefox");
  this.name="NK";
  this.mainVersion="NK";
  this.minorVersion="NK";
 
  for (var i=0; i< browserNames.length; i++)
  {
   var pattern='('+browserNames[i]+')'+'.([0-9]+)\.([0-9]+)';    
   var myRegExp=new RegExp(pattern);
   if (myRegExp.test(navigator.userAgent))
    {
      var results=myRegExp.exec(navigator.userAgent);
      this.name=results[1];
      this.mainVersion=results[2];
      this.minorVersion=results[3];
      break;
    }
  }
}

In order to use this in a script, you then create an instance of this object:

var browser = new browserDetect();

The property browser.name will then give you then name of the browser (MSIE, Opera, Netscape or Firefox), browser.mainVersion will give you the main version number and browser.minorVersion will give you the minor version number.

However you should be aware that this is not foolproof, and it is generally better (in this writer's opinion) to avoid writing browser-specific code as far as possible.


Adding stylesheets for other output devices

Using CSS style sheets, it is possible to use a set of directives(styles) depending upon the device being used to browse web pages.

Media Types

The recognised media types are:

  • all - Suitable for all devices.
  • aural - For speech synthesizers.
  • braille - Intended for braille tactile feedback devices.
  • embossed -Intended for paged braille printers.
  • handheld - Intended for handheld devices.
  • print - Used for formatting printed pages.
  • projection - Intended for projected presentations, for example projectors or print to transparencies.
  • screen - Intended primarily for color computer screens.
  • tty - Intended for media using a fixed-pitch character grid, such as teletypes, terminals, or portable devices with limited display capabilities. Authors should not use pixel units with the "tty" media type.
  • tv - Intended for television-type devices (low resolution, color, limited-scrollability screens, sound available).

Examples

You can assign a media type to a CSS declaration with the following syntax

@media print {
  body { 
    font-size: 12pt;
    font-color: #000000; 
  }
}

To assign more than one declaration style to more than one media type:

@media print, handheld{
  body { 
    font-size: 12pt;
    font-color: #000000;
  }
  img {
    max-width: 100%;
    height: auto;
  }
}

The directives can be used in the main CSS file or in a separate style sheet for a given media type. There must be an include to the CSS file in the templates <head> section (the following is taken from the Joomla! Beez template):

<link rel="stylesheet" href="<?php echo $this->baseurl ?>/templates/beez/css/print.css" type="text/css" media="Print" />

Enhancing template performance

Enhancing template performance

Administrator (back-end) templates

Administrator (back-end) templates