最近在开发的过程中,遇到了一很奇怪的问题,就是模块的语言文件不能正确的加载。为此需要分析一下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中可得到

 

 

作者: 樱木花道

Joomla程序员,从J1.5到J4.x始终都在做Joomla相关开发定制工作,有超过10年行业经验,国内Joomla扩展开发商ZMAX团队的核心成员

作者网站:ZMAX程序人

评论 (0)

  • 最新在前
  • 最佳在前