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中可得到