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); 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章