一个 Joomla 模块是否能够“知道”它所处的位置?

3
我对Joomla还比较新(我更喜欢WordPress),关于模块位置,我有一个问题。
模块能否知道它所在的位置。例如,我能否像这样做:
如果(modulePosition =='left'){
    做这个...
}否则{
    做那个...
}
看起来很容易,但我已经搜索了几个小时,找不到任何可以帮助我的东西。我知道有一个countModules函数,但从我所了解的情况来看,它只是检查模块是否处于活动状态。
谢谢你的帮助!
5个回答

9
我找到了答案!大部分要感谢@Hanny。他使用模块id的想法让我开始搜索,然后我找到了答案。对于任何其他正在寻找类似功能的人,这里是解决方案。
您可以使用全局变量$module(谁能想到呢?)
所以我的代码现在看起来像这样:
$class = '';
if($module->position == 'position1'){
     $class = 'class1';
}
and so on...

很简单,对吧?

想要了解全局变量$module还能做什么,只需在代码中加入以下内容即可查看可用信息:

echo(print_r($module));

感谢您的所有帮助!(这句话已经是中文了,无需翻译)

不错!我曾尝试通过在模块内检查 $this 来实现这一点。但是模块是函数式调用的,所以那样行不通。没想到会尝试像全局变量这样老派的方法 ;o。 - KingJackaL
没有人会想到(除了Joomla开发人员),特别是如果全局变量没有在任何地方提到。还有另一个隐藏的变量,你可以设置它来选择自己的模块HTML包装器或完全删除它,但我不记得它叫什么了。 - Timo Huovinen

1

我尝试在John的解决方案下进行评论,但是我的声望点数不够--我想补充一点,无论您在模板中如何命名模块位置,$module->position返回的位置名称始终是小写,与您在模板中命名的方式无关...例如,在您的模板XML文件中,可能会将顶部栏位置命名为“topBar”,但在尝试使用时,其名称将变为“topbar”,而不是“topBar”。

if($module->position == 'topBar') //always false... use instead
if($module->position == 'topbar') //what you need to use

1
简短的回答是“是的”,你可以基于你的模板为一个模块分配一个位置。当它出现时,你可以有像这样关于该位置的条件语句(不同的模板对于位置有不同的命名约定,所以在编码之前确保你知道它们)。
例如,有些人使用“Position12”,其他人可能使用“leftcol”等。你只需要检查模板文件即可(您可以查看模板目录中的.xml文件以查看模板中列出的位置,或者在jdoc包含项的index.php文件中查看)。
在我的一些经验中,你真正需要像这样的代码的唯一时间是在模板的核心布局文件中(例如,如果你有不同的列宽取决于模块存在与否),否则不会真正有可能出现“可能或可能不”有模块出现的情况-因为你将明确地告诉它们后端何时在哪里。

谢谢您的回答!我应该更清楚地说明我需要什么。我基本上需要模块本身确定它所在的位置,然后适当地设置一个变量。在我正在处理的网站上,有三个使用相同模块类型(我正在为其构建的模块)的模块位置,根据它所在的位置,我需要设置一个变量(用于CSS类),以便正确显示。因此,代码看起来会像这样:if(modulePosition == '1'){$class = 'class1'}elseif(modulePosition == '2'){$class = 'class2'}等等。有什么想法吗?谢谢! - john
啊,我相信你可以做到像你所要求的那样...如果不行,你可以使用模块ID作为模块ID,并检查它的位置-它将知道它在哪个位置(或者应该知道)。我大约99%确定它实际上会知道它的位置。只要确保你知道模板中位置的名称,你就应该能够通过这种方式进行检查。 - Hanny
此外,我发现添加 PHP(和其他语言)到模块的最佳解决方案是一个名为 Sourceror 的插件 - 如果您还没有安装该解决方案,请查看一下!祝你好运,希望这个答案能够稍微澄清一些问题! - Hanny

0

我不同意Hanny的观点。我认为答案是否定的,不是你描述的那样。

模板知道它何时到达了一个模块位置,并获取分配给该位置的模块列表,然后调用它们进行渲染。但是它不会传递那些信息。它也不存储在JApplication或JDocument中(就像没有任何东西存储渲染模板的位置或其他任何内容)。

尽管如此,有一些hacky方法可以实现类似于您想要的功能。如果您知道需要搜索的模板位置(遗憾的是,没有从模板获取这个的简单方法-否则您可以解析模板的.XML文件以获取<position>元素...),然后您可以做类似以下的操作:

<?php

$positions = array('left', 'right', 'top', 'bottom')

$found_in = false;

foreach ($positions as $cur_position)
{
    $module_positions = JModuleHelper::getModules($cur_position);
    foreach ($module_positions as $cur_module_in_pos)
    {
        if ($cur_module_in_pos->module == 'mod_MYMODULE')
        {
            $found_in = $cur_position;
        }
    }
}

if ($found_in)
...

当然,如果您的模块在页面上被多次包含,那么这种方法可能不太有效,但也许这是您可以做出的一种假设?
否则,您需要修改核心代码 - 您可以在模板调用模块之前使用JDispatcher :: trigger()调用,设置某些变量等。不幸的是,在核心中没有此类事件(例如pre_module_render)。

0

一个模块实例只能被分配到一个位置,并且存储在数据库中,通常您会在模板中为该位置设置样式。因此,虽然这是一个有趣的问题,但实际上并不实用。

以下是一些例外情况: loadposition ... 您可能想知道是否使用插件加载了模块,因为这可能会将其放置在位置的样式区域之外。尽管如此,我建议始终创建一个新实例,以便您拥有更多控制权。

loadmodule ... 使用插件按名称加载的模块。在这种情况下,您最好再创建一个模块实例并进行样式设置。此外,无论是 span 还是 div,我都会将其放置在其中,具体取决于它是什么。

jdocinclude:module ... 直接在模板中加载模块。同样,如果您这样做,我会将其包装在 span 或 div 中。在这种情况下,您还可以包含一串内联样式字符串,如果您喜欢这种方式的话。

将模块渲染为字符串并回显它,这基本上是一个非常定制化的解决方案,您需要设置样式和选项。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接