Joomla!1.6 的元件 render 過程

Written by Simon Asika on

Joomla!1.6 中,元件render是在Dispatch時進行的。當 JApplication::dispatch() 被執行時,其中一行就會看見: 

$contents = JComponentHelper::renderComponent($component);
$document->setBuffer($contents, 'component');

呼叫元件helper在輸出緩衝之中渲染元件頁面的html,然後存在 $contents 中放進緩衝區,等待之後的全站 Render 過程再拿來用。

 

讓我們先看看 JComponentHelper::renderComponent() 中的原始碼:

public static function renderComponent($option, $params = array())
{
// Initialise variables.
$app = JFactory::getApplication();

// 模板語系檔就是在此時載入的
$template = $app->getTemplate(true)->template;
$lang = JFactory::getLanguage();
$lang->load('tpl_'.$template, JPATH_BASE, null, false, false)
|| $lang->load('tpl_'.$template, JPATH_THEMES."/$template", null, false, false)
|| $lang->load('tpl_'.$template, JPATH_BASE, $lang->getDefault(), false, false)
|| $lang->load('tpl_'.$template, JPATH_THEMES."/$template", $lang->getDefault(), false, false);

if (empty($option)) {
// Throw 404 if no component
JError::raiseError(404, JText::_('JLIB_APPLICATION_ERROR_COMPONENT_NOT_FOUND'));
return;
} //沒有元件參數(OPTION)的話就丟出錯誤訊息

$scope = $app->scope; //record the scope
$app->scope = $option; //set scope to component name

// 從 option 參數建立元件路徑。
// 例如 com_content 就以 componants/com_content/content.php 為元件入口頁面
$option = preg_replace('/[^A-Z0-9_\.-]/i', '', $option);
$file = substr($option, 4);

// 建立元件路徑常數 (之前都自己Define,想不到原來這裡有阿= =)
define('JPATH_COMPONENT', JPATH_BASE.DS.'components'.DS.$option);
define('JPATH_COMPONENT_SITE', JPATH_SITE.DS.'components'.DS.$option);
define('JPATH_COMPONENT_ADMINISTRATOR', JPATH_ADMINISTRATOR.DS.'components'.DS.$option);

// 入口頁面
if ($app->isAdmin() && file_exists(JPATH_COMPONENT.DS.'admin.'.$file.'.php')) {
$path = JPATH_COMPONENT.DS.'admin.'.$file.'.php';
} else {
$path = JPATH_COMPONENT.DS.$file.'.php';
}

// 若元件處於關閉狀態,丟錯
if (!self::isEnabled($option) || !file_exists($path)) {
JError::raiseError(404, JText::_('JLIB_APPLICATION_ERROR_COMPONENT_NOT_FOUND'));
}

$task = JRequest::getString('task');

// 讀取元件的語系檔.
$lang->load($option, JPATH_BASE, null, false, false)
|| $lang->load($option, JPATH_COMPONENT, null, false, false)
|| $lang->load($option, JPATH_BASE, $lang->getDefault(), false, false)
|| $lang->load($option, JPATH_COMPONENT, $lang->getDefault(), false, false);

// Handle template preview outlining.
$contents = null;

// 啟動輸出緩衝區,require元件入口頁面。此時就進入整個元件的執行過程了,詳細可看元件部分的教學。
ob_start();
require_once $path;
$contents = ob_get_contents();
ob_end_clean();

// 後台專用,當元件在後台運作時,管理頁面需要載入toolbar來執行操作
jimport('joomla.application.helper');

if (($path = JApplicationHelper::getPath('toolbar')) && $app->isAdmin()) {
// Get the task again, in case it has changed
$task = JRequest::getString('task');

// Make the toolbar
include_once $path;
}

$app->scope = $scope; //revert the scope

return $contents; //回傳輸出的元件html
}

 

Control Tools

WS-logo