以前的文章中,關於/index.php我們已經分析完了 $mainframe->dispatch()是引入了組件,並被執行。我們知道對於Joomla,一個頁面只能有一個或者0個組件,而上,下左右的碎片都是module,module是頁面豐富的有效補充。比如我們知道菜單是 mod_mainmenu,而footer是mod_footer等等,那麼這些module是怎麼被引入的,並最後執行的?
祕密都在$mainframe->render()這個函數上,我們看看這個函數都做了什麼工作。
以下是JSite 的render 函數的內容
$document =& JFactory::getDocument();
$user =& JFactory::getUser();
// get the format to render
$format = $document->getType();
switch($format)
{
case 'feed' :
{
$params = array();
} break;
case 'html' :
default :
{
$template = $this->getTemplate();
$file = JRequest::getCmd('tmpl', 'index');
if ($this->getCfg('offline') && $user->get('gid') < '23' ) {
$file = 'offline';
}
if (!is_dir( JPATH_THEMES.DS.$template ) && !$this->getCfg('offline')) {
$file = 'component';
}
$params = array(
'template' => $template,
'file' => $file.'.php',
'directory' => JPATH_THEMES
);
} break;
}
$data = $document->render( $this->getCfg('caching'), $params);
JResponse::setBody($data);
其實重要的部分是引入了相應的模板文件(template/***/index.php),並調用了 JDocumentHtml的 render 函數。
看到這裏,我們終於明白了,模板的index.php原來是這個時候被引入的。
我們再看看 JDocumentHtml 的render函數。
這個函數中最重要的兩句程序是
$data = $this->_loadTemplate($directory.DS.$template, $file); 載入模板文件
$data = $this->_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;
}
對了,就是這部分,對模板中 JDOC標籤進行了解析,獲得了相應的module名稱和參數,並調用getBuffer函數執行。
至此 調用 $renderer->render($name, $attribs, $result);