Joomla源代码解析(二十一) 模块是如何被调用执行并渲染?

以前的文章中,关于/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); 

阅读更多

没有更多推荐了,返回首页