JModuleHelper类分析 原
最近在开发的过程中,遇到了一很奇怪的问题,就是模块的语言文件不能正确的加载。为此需要分析一下joomla的源代码。JModulehelper
JModuleHelper是一个虚类。他的实现文件在joomla.application.module.helper.php文件中。他的声明如下:
/**
* Module helper class
*
* @package Joomla.Platform
* @subpackage Application
* @since 11.1
*/
abstract class JModuleHelper
{
......
这个类提供了几个静态方法。getModule($name,$title)这个方法通过模块的名称和标题来获取一个模块。这个模块的标题默认为空。这个函数的实现比较简单。如果要查找的模块不存在,那么就创建一个空的模块出来,并返回。创建的模块的名称和你要查找的模块的名称一致。
整个的实现代码如下:
/**
* Get module by name (real, eg 'Breadcrumbs' or folder, eg 'mod_breadcrumbs')
*
* @param string $name The name of the module
* @param string $title The title of the module, optional
*
* @return object The Module object
*
* @since 11.1
*/
public static function &getModule($name, $title = null)
{
$result = null;
$modules =& JModuleHelper::_load();
$total = count($modules);
for ($i = 0; $i < $total; $i++)
{
// Match the name of the module
if ($modules[$i]->name == $name || $modules[$i]->module == $name)
{
// Match the title if we're looking for a specific instance of the module
if (!$title || $modules[$i]->title == $title)
{
// Found it
$result = &$modules[$i];
break; // Found it
}
}
}
// If we didn't find it, and the name is mod_something, create a dummy object
if (is_null($result) && substr($name, 0, 4) == 'mod_')
{
$result = new stdClass;
$result->id = 0;
$result->title = '';
$result->module = $name;
$result->position = '';
$result->content = '';
$result->showtitle = 0;
$result->control = '';
$result->params = '';
$result->user = 0;
}
return $result;
}
不复杂,只是我不清楚,为什么函数的前面要加一个&符号。难道要引用返回。
同样还有一个函数getModules($position)这个函数可以返回指定位置的模块。以数组的形式返回。如果没有找到也会创建一个模块。这个就不贴代码,实现思路和上一个基本一致。
/**
* Checks if a module is enabled
*
* @param string $module The module name
*
* @return boolean
*
* @since 11.1
*/
public static function isEnabled($module)
{
$result = JModuleHelper::getModule($module);
return !is_null($result);
}
这个函数,没什么说的了。检查一个模块是否启用了。
这里有一个函数,需要说一下。getLayoutPath($module ,$layout = 'default')。之所以要说这个函数,是因为它和joomla的一个重要特性有关,那就是对核心的输出重载。
/**
* Get the path to a layout for a module
*
* @param string $module The name of the module
* @param string $layout The name of the module layout. If alternative layout, in the form template:filename.
*
* @return string The path to the module layout
*
* @since 11.1
*/
public static function getLayoutPath($module, $layout = 'default')
{
$template = JFactory::getApplication()->getTemplate();
$defaultLayout = $layout;
if (strpos($layout, ':') !== false)
{
// Get the template and file name from the string
$temp = explode(':', $layout);
$template = ($temp[0] == '_') ? $template : $temp[0];
$layout = $temp[1];
$defaultLayout = ($temp[1]) ? $temp[1] : 'default';
}
// Build the template and base path for the layout
$tPath = JPATH_THEMES . '/' . $template . '/html/' . $module . '/' . $layout . '.php';
$bPath = JPATH_BASE . '/modules/' . $module . '/tmpl/' . $defaultLayout . '.php';
$dPath = JPATH_BASE . '/modules/' . $module . '/tmpl/default.php';
// If the template has a layout override use it
if (file_exists($tPath))
{
return $tPath;
}
elseif (file_exists($bPath))
{
return $bPath;
}
else
{
return $dPath;
}
}
重点看下面的代码:
// Build the template and base path for the layout
$tPath = JPATH_THEMES . '/' . $template . '/html/' . $module . '/' . $layout . '.php';
$bPath = JPATH_BASE . '/modules/' . $module . '/tmpl/' . $defaultLayout . '.php';
$dPath = JPATH_BASE . '/modules/' . $module . '/tmpl/default.php';
这里有3个路径,其中第一个是模版的html目录下的重载路径。这个是第一个的返回值。
在这个类里面还有一个很强大的方法。renderModule。这个方法可以在任何的地方输出指定的模块。
/**
* Render the module.
*
* @param object $module A module object.
* @param array $attribs An array of attributes for the module (probably from the XML).
*
* @return string The HTML content of the module output.
*
* @since 11.1
*/
public static function renderModule($module, $attribs = array())
另外在renderModule函数的实现文件中还解释了joomla语言文件的加载原理,下面是相关的代码:
// Load the module
// $module->user is a check for 1.0 custom modules and is deprecated refactoring
if (empty($module->user) && file_exists($path))
{
$lang = JFactory::getLanguage();
// 1.5 or Core then 1.6 3PD
$lang->load($module->module, JPATH_BASE, null, false, false) ||
$lang->load($module->module, dirname($path), null, false, false) ||
$lang->load($module->module, JPATH_BASE, $lang->getDefault(), false, false) ||
$lang->load($module->module, dirname($path), $lang->getDefault(), false, false);
$content = '';
ob_start();
include $path;
$module->content = ob_get_contents() . $content;
ob_end_clean();
}
$lang->load会加载执行扩展的语言文件。JPATH_BASE如果在前台就代表JPATH_SITE.在后台就代表JPATH_ADMINISTRATOR.这段话的意思是,首先在系统的language文件夹下找语言文件,如果没有找到,那么再去模块的安装目录下的language目录找。如果依旧找不到,那么就加载默认语言的语言文件。
这个就不补贴出代码了。
下面是针对这个类的方法的常见用法
输出模块到任意位置:
$module = JModuleHelper::getModule('custom',$title);//此针对 定制html module,其中$title是定制的HTML模块标题
echo JModuleHelper::renderModule($module);
//针对多个
$modules = JModuleHelper::getModules('right'); //参数是position
foreach($modules as $module)
{
echo JModuleHelper::renderModule($module);
}
$module = JModuleHelper::getModule('mod_breadcrumbs');//参数是module名
echo JModuleHelper::renderModule($module);
一下内容为相关的引用:
总结,有时在component所在的view中输出所需的module,会带来更大灵活性。另外,灵活运用定制HTML模块
custom module: http://docs.joomla.org/Applying_custom_module_chrome
简要步聚:1.模板所在目录中的html目录中创建modules.php
2.定义function modChrome_STYLE($module, &$params, &$attribs)
3.模板中调用<jdoc:include type="modules" name="user1" style="STYLE" />这个中可带任意参数,在$attribs中可得到