Profile

Layout

Menu Style

Cpanel

Articoli

Processo di Rendering del template Joomla 1.5 - jdoc:include

In questo articolo vedremo passo dopo passo come avviene il processo di Rendering del Template di Joomla 1.5.

In particolare cercheremo di capire come vengono sostituiti i tag jdoc:include inseriti nel nostro template.

Quando richiamiamo la homepage di un sito in Joomla 1.5, la prima pagina caricata è la index.php che si trova sotto la root.

All'inizio della pagina index.php viene inizializzata la variabile $mainframe:

{xtypo_code}
/**
* CREATE THE APPLICATION
*
* NOTE :
**/

mainframe =& JFactory::getApplication('site');
{/xtypo_code}


Il processo di Rendering inizia a riga 79.

· index.php.{main} : lineno 79

{xtypo_code}
/**
* RENDER THE APPLICATION
*
* NOTE :
*/

$mainframe->render();
{/xtypo_code}


Viene richiamato il metodo render() ,

includes/application.php.JSite->render : lineno 135

{xtypo_code}
/**
* Display the application.
*
* @access public
*/

function render()
{
$document =& JFactory::getDocument();
$user =& JFactory::getUser();

// get the format to render
$format = $document->getType();
{/xtypo_code}

In base alla variabile $format che in questo caso è ‘html’ verrà eseguita la parte di codice: case ‘html’ che corrisponde al default:

{xtypo_code}
switch($format)
{
case 'feed' :
{
$params = array();

} break;
case 'html' :
default :
{
$template = $this->getTemplate();
$file = JRequest::getCmd('tmpl', 'index');
{/xtypo_code}

Viene quindi impostata la variabile $template al template predefinito. Richiamiamo il metodo render della classe $document

{xtypo_code}
$params = array(
'template' => $template,
'file' => $file.'.php',
'directory' => JPATH_THEMES
);
} break;
}

$data = $document->render( $this->getCfg('caching'), $params);
JResponse::setBody($data);
}
{/xtypo_code}

Nel metodo render (libraries/joomla/document/html/html.php.JDocumentHTML->render : lineno 220) toviamo due metodi fondamentali del processo di Rendering del template.

{xtypo_code}
// Assign the variables
$this->template = $template;
$this->baseurl = JURI::base(true);
$this->params = $params;


// load
1) $data = $this->_loadTemplate($directory.DS.$template, $file);

// parse
2) $data = $this->_parseTemplate($data);

//output
parent::render();
return $data;
}
{/xtypo_code}



Function _loadTemplate(..)

Il primo metodo 1) carica il template senza eseguire il pasing.

{xtypo_code}
/**
* Load a template file
*
* @param string $template The name of the template
* @param string $filename The actual filename
* @return string The contents of the template
*/

function _loadTemplate($directory, $filename)
{
global $mainframe, $option;

if ($mainframe->getCfg('legacy'))
{
global $task, $_VERSION, $my, $cur_template, $database, $acl, $Itemid;
//For backwards compatibility extract the config vars as globals
$registry =& JFactory::getConfig();

foreach (get_object_vars($registry->toObject()) as $k => $v) {
$name = 'mosConfig_'.$k;
$$name = $v;
}
}

$contents = '';

//Check to see if we have a valid template file
if ( file_exists( $directory.DS.$filename ) )
{
//store the file path
$this->_file = $directory.DS.$filename;

//get the file content
ob_start();
require_once $directory.DS.$filename;
$contents = ob_get_contents();
ob_end_clean();
}

{/xtypo_code}



Verrà, quindi, caricato il template che abbiamo creato per il nostro sito. In questo esempio il template risulta semplificato in quanto il nostro scopo è quello di vedere come avviene il processo di rendering dei singoli oggetti inseriti con i tag <jdoc:include.

Nel nostro template che abbiamo definito alcuni type: head, modules, component e message .


{xtypo_code}


<?php echo '<?xml version="1.0" encoding="utf-8"?'.'>'; ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="" lang=""
 dir="" >
<head>
<jdoc:include type="head" />
</head>

<body>
<jdoc:include type="modules" name="left" />
<hr>
<jdoc:include type="component" />
<hr>
<jdoc:include type="message" />
<hr>
</body>
</html>
{/xtypo_code}


Entriamo nella parte di parsing del template, dove per intenderci avvengono le trasformazioni dei tag jdoc.

function parse_template(..)

Come abbiamo visto precedentemente con il metodo _loadTemplate si carica il template così come lo abbiamo definito senza operazioni di parsing.

Il metodo parse_template si occupa invece del parsing. Questa è la fase più interessante del processo.



{xtypo_code}
// Assign the variables
$this->template = $template;
$this->baseurl = JURI::base(true);
$this->params = $params;

// load
$data = $this->_loadTemplate($directory.DS.$template, $file);

// parse
$data = $this->_parseTemplate($data);

//output
parent::render();
return $data;
}
{/xtypo_code}

La funzione _parseTemplate() cerca tutte le occorenze: jdoc all’interno del nostro template.

{xtypo_code}
/**
* Parse a document template
*
* @access public
* @param string $data The data too parse
* @return The parsed contents of the template
*/

function _parseTemplate($data)
{
$replace = array();
$matches = array();
if(preg_match_all('#<jdoc:include\ type="([^"]+)" (.*)\/>#iU', $data, $matches))
{
$matches[0] = array_reverse($matches[0]);
$matches[1] = array_reverse($matches[1]);
$matches[2] = array_reverse($matches[2]);

$count = count($matches[1]);

for($i = 0; $i < $count; $i++)
{
$attribs = JUtility::parseAttributes( $matches[2][$i] );
$type = $matches[1][$i];
$name = isset($attribs['name']) ? $attribs['name'] : null;
$replace[$i] = $this->getBuffer($type, $name, $attribs);
}
$data = str_replace($matches[0], $replace, $data);
}
return $data;
}
}
{/xtypo_code}

Nel nostro caso, abbiamo definito questi jdoc:

{xtypo_code}
<jdoc:include type="head" />
<jdoc:include type="modules" name="left" />
<jdoc:include type="component" />
<jdoc:include type="message" />
{/xtypo_code}

Nel metodo _parseTemplate viene eseguito un loop su tutte le occorenze jdoc.

{xtypo_code}
for($i = 0; $i < $count; $i++)
{
$attribs = JUtility::parseAttributes( $matches[2][$i] );
$type = $matches[1][$i];
$name = isset($attribs['name']) ? $attribs['name'] : null;
$replace[$i] = $this->getBuffer($type, $name, $attribs);
}
{/xtypo_code}

Per ogni occorrenza jdoc, viene richiamata la funzione: getBuffer (libraries/joomla/document/html/html.php.JDocumentHTML->getBuffer : lineno 173)

{xtypo_code}
/**
* Get the contents of a document include
*
* @access public
* @param string $type The type of renderer
* @param string $name The name of the element to render
* @param array $attribs Associative array of remaining attributes.
* @return The output of the renderer
*/

function getBuffer($type = null, $name = null, $attribs = array())
{
$result = null;

// If no type is specified, return the whole buffer
if ($type === null) {
return $this->_buffer;
}

if(isset($this->_buffer[$type][$name])) {
$result = $this->_buffer[$type][$name];
}

// If the buffer has been explicitly turned off don't display or attempt to render
if ($result === false) {
return null;
}

if( $renderer =& $this->loadRenderer( $type )) {
$result = $renderer->render($name, $attribs, $result);
}

return $result;
}
{/xtypo_code}

In base al parametro type (component.php, head.php, message.php, module.php, modules.php) il metodo loadRender ritorna la classe specifica per il render.

{xtypo_code}
if( $renderer =& $this->loadRenderer( $type )) {
$result = $renderer->render($name, $attribs, $result);
}
{/xtypo_code}

Le classi sono definite nei file inseriti in: libraries/joomla/document/html/

Vediamo come avviene il Rendering di<jdoc:include type ="modules" name="left" />

In questo caso i parametri sono: $type = ‘modules’ e $attribs=’left’
{xtypo_code}
/**
* Get the contents of a document include
*
* @access public
* @param string $type The type of renderer
* @param string $name The name of the element to render
* @param array $attribs Associative array of remaining attributes.
* @return The output of the renderer
*/

function getBuffer($type = null, $name = null, $attribs = array())
{/xtypo_code}

Quindi la nostra funzione: getBuffer, in base al $type, in questo caso ‘modules’,

{xtypo_code}
// If the buffer has been explicitly turned off don't display or attempt to render
if ($result === false) {
return null;
}


if( $renderer =& $this->loadRenderer( $type )) {
$result = $renderer->render($name, $attribs, $result);
}

return $result;
}
{/xtypo_code}

richiama il metodo loadRender(‘modules’)

{xtypo_code}
/**
* Load a renderer
*
* @access public
* @param string The renderer type
* @return object
* @since 1.5
*/

function &loadRenderer( $type )
{
$null = null;
$class = 'JDocumentRenderer'.$type;

if( !class_exists( $class ) )
{
$path = dirname(__FILE__).DS.$this->_type.DS.'renderer'.DS.$type.'.php';
if(file_exists($path)) {
require_once($path);
} else {
JError::raiseError(500,JText::_('Unable to load renderer class'));
}
}

if ( !class_exists( $class ) ) {
return $null;
}

$instance = new $class($this);
return $instance;

}
{/xtypo_code}

il quale restituisce un’istanza della classe specifica per il render: JDocumentRendermodules.

Viene cosi richiamato il metodo render della classe JDocumentRenderModules (libraries/joomla/document/html/renderer/modules.php.JDocumentRendererModules->render : lineno 37)

{xtypo_code}
// Check to ensure this file is within the rest of the framework
defined('JPATH_BASE') or die();
/**
* JDocument Modules renderer
*
* @package Joomla.Framework
* @subpackage Document
* @since 1.5
*/

class JDocumentRendererModules extends JDocumentRenderer
{
/**
* Renders multiple modules script and returns the results as a string
*
* @access public
* @param string $name The position of the modules to render
* @param array $params Associative array of values
* @return string The output of the script
*/

function render( $position, $params = array(), $content = null )
{
$renderer =& $this->_doc->loadRenderer('module');
$contents = '';
foreach (JModuleHelper::getModules($position) as $mod) {
$contents .= $renderer->render($mod, $params, $content);
}
return $contents;
}
}
{/xtypo_code}

Il metodo loadRenderer ottiene un istanza della classe JDocumentRenderModule che verrà utilizzata nell’loop:

{xtypo_code}
function render( $position, $params = array(), $content = null )
{
$renderer =& $this->_doc->loadRenderer('module');
$contents = '';
foreach (JModuleHelper::getModules($position) as $mod) {
$contents .= $renderer->render($mod, $params, $content);
}
return $contents;
}
}
{/xtypo_code}

Il metodo render della classe JDocumentRenderModule (libraries/joomla/document/html/renderer/module.php.JDocumentRendererModule->render : lineno 37)

Ritorna il codice html del singolo modulo.

{xtypo_code}
class JDocumentRendererModule extends JDocumentRenderer
{
/**
* Renders a module script and returns the results as a string
*
* @access public
* @param string $name The name of the module to render
* @param array $params Associative array of values
* @return string The output of the script
*/

function render( $module, $params = array(), $content = null )
{
if (!is_object($module))
{/xtypo_code}

La chiamata JModuleHelper::renderModule() restituisci il codice html del modulo.

{xtypo_code}
$cache->setCacheValidation(true);
$contents = $cache->get( array('JModuleHelper', 'renderModule'), array( $module, $params ), $module->id. $user->get('aid', 0) );
} else {
$contents = JModuleHelper::renderModule($module, $params);
}
return $contents;
}

}
{/xtypo_code}

libraries/joomla/application/module/helper.php.JModuleHelper->renderModule : lineno 123

{xtypo_code}
function renderModule($module, $attribs = array())
{
{/xtypo_code}

Nel nostro esempio abbiamo pubblicato un modulo di tipo mainmenu nella posizione left. In questo caso viene caricata la pagina mod_mainmenu.php.

Conclusioni

Abbiamo visto come avviene la trasformazione dei tag jdoc:include in codice html nella pagina finale.

In particolare abbiamo analizzato il comportamento di un modulo. Il processo è simile anche per le altre tipologie di oggetti.

Ricordiamo, infine, che questo articolo aveva lo scopo di introdurci alla fase di Rendering.


 
 

Dati fiscali

Pironti Eleonora - V. Sandro Pertini 19 - Settimo Milanese (MI) 20019 Cell: 3774322098- tel 0292807768 - P.IVA 13201480152