JModuleHelper::getModule('mod_modulename')->id only gets the first one loaded on a page Topic is solved

Be informed that this forum is not an official support forum for Joomla! 4.0. Any issues regarding Joomla! 4.0 must be reported at https://issues.joomla.org/.

Joomla 4.0 is still in Beta stage. This forum should be used for sharing information about Joomla! 4.0.

Moderator: ooffick

Forum rules
Locked
sozzled
I've been banned!
Posts: 13639
Joined: Sun Jul 05, 2009 3:30 am
Location: Canberra, Australia

JModuleHelper::getModule('mod_modulename')->id only gets the first one loaded on a page

Post by sozzled » Sat Sep 04, 2021 9:13 pm

This is a bit of a tricky problem and it's been around since the days when J! was wearing short pants. For the purposes of discussion, however, the problem persists today in J! 4.

The scenario:
  1. You've written a module (and, even better, it's compatible with J! 4 :D ) and you've installed it on your brand new J! website.
  2. You've decided to publish two instances of the module on a web page. (This doesn't happen often that you need the same module to be displayed "twice" but each instance of the module may have different parameters.)
  3. You want to do something different depending on the instance of the module (without having to create another parameter to differentiate one instance from another). The normal way to identify a module is to get its id.
The method:

The usual way to get a module's id is to write the following PHP:

Code: Select all

// no direct access
defined('_JEXEC') or die('Restricted access');
use Joomla\CMS\Factory;

jimport('joomla.application.module.helper');
$module = JModuleHelper::getModule('mod_mymodule');

$id = $module->id
Nothing terribly difficult there. You can display the value of $id with an echo instruction.

OK, now run the page with two instances of the module and display the value of $id. Interesting, isn't it, that the value is the same in both cases! This was situation was discussed years ago on this forum: viewtopic.php?t=254805. It's also been discussed more recently on GitHub and at StackExchange but I'm really not interested in running AJAX to identify the specific instance.

It would be really nice if there was a method or property that identified the specific instance of the module that's being used at the time. I don't want to have to feed the call to getModule() like this:

getModule(string $name, string $title = null)

because I won't always know the title of the module when I'm using it. I just want to know the "id" of the module's instance and, if there are multiple instances, which particular instance of the module the PHP needs to "work" on. In other words, the module should be agnostic about the title of the module or what template position it uses or may use.

Ideally, it be great if there was a property like this:

Code: Select all

JModuleHelper::getModule('mod_mymodule')->getInstance
... but there ain't AFAICT.
Last edited by imanickam on Sun Sep 05, 2021 6:54 am, edited 1 time in total.
Reason: Moved topic » from General Questions/New to Joomla! 4.x to Joomla! 4 Related

SharkyKZ
Joomla! Hero
Joomla! Hero
Posts: 2906
Joined: Fri Jul 05, 2013 10:35 am
Location: Parts Unknown

Re: JModuleHelper::getModule('mod_modulename')->id only gets the first one loaded on a page

Post by SharkyKZ » Sat Sep 04, 2021 11:38 pm

Where are you placing this code?

sozzled
I've been banned!
Posts: 13639
Joined: Sun Jul 05, 2009 3:30 am
Location: Canberra, Australia

Re: JModuleHelper::getModule('mod_modulename')->id only gets the first one loaded on a page

Post by sozzled » Sun Sep 05, 2021 1:35 am

Thanks for getting back to me, @SharkyKZ.

I've built this module the same way as I've build other modules in the past. The file structure looks like this:

Code: Select all


/modules/mod_mymodule
|---- mod_mymodule.php
|---- mod_mymodule.xml
.
.	(other files, e.g. a "README" and an image)
.
|---- /tmpl
|---- |---- default.php
.
.      (other files and folders, e.g. CSS, images)
.
The call to set the object

Code: Select all

$module = JModuleHelper::getModule('mod_mymodule')
is made in the file mod_mymodule.php. The last line of that file is

Code: Select all

require(JModuleHelper::getLayoutPath('mod_mrwdownload'));
which then invokes the file tmpl/default.php. The $module object is accessible in both PHP files.

The language files used by the module are, of course, placed in the /languages folder. The module is parceled as a .ZIP and installed in the normal way. The module works fine (if there's only one instance of it on a page). If there are two instances of it, $module->id returns the same ID value for both. If you disable one or the other instance, $module->id returns the correct ID.

For example, let's say you have used Extensions » Modules » New to create one instance (and it gets the ID of 162) and then you do the same again (and the new instance gets the ID of 163). If you publish both instances for any number of menu items and echo the result of $module->id, you will get the ID of the first-loaded instance of that module that appears on the page generated by the menu item; that's the problem. If you had more than two instances of the module all published on the same menu item, again you will only get the ID of the first-loaded instance of them. The point is that you can't identify which instance is which from looking at $module->id.

Does that help and does it answer your question? Does that make a difference?

User avatar
ceford
Joomla! Hero
Joomla! Hero
Posts: 2677
Joined: Mon Feb 24, 2014 10:38 pm
Location: Edinburgh, Scotland
Contact:

Re: JModuleHelper::getModule('mod_modulename')->id only gets the first one loaded on a page

Post by ceford » Sun Sep 05, 2021 2:00 am

This question is too vague and in the wrong forum - something more for Developers than Newcomers.

Inside the module I think you can use $module->id to get the instance id [var_dump($module->id);]

Elsewhere you might be able to use ModuleHelper::getModuleList(); to get a list to work on.

sozzled
I've been banned!
Posts: 13639
Joined: Sun Jul 05, 2009 3:30 am
Location: Canberra, Australia

Re: JModuleHelper::getModule('mod_modulename')->id only gets the first one loaded on a page

Post by sozzled » Sun Sep 05, 2021 2:12 am

@ceford: I am asking a question (a question that has been asked before on this forum several times before) about how the Joomla API is used. If The Joomla Forum™ is the "wrong forum" to ask questions about Joomla then I don't know what you're suggesting. :eek: I am not involved in "developing" the J! CMS (that's what GitHub is for). I'm just trying to use Joomla, to build an extension, that's all.

UPDATE: Nah ... var_dump just told me that there was no "instance" property. There are a lot of properties (e.g. id, position, title, params, etc.), even though these are not listed in the J! documentation site, but there isn't a property that corresponds to the instance when you have multiple instances of the module appearing on the same page. I didn't learn anything new from doing that but thanks for your suggestion.

It's not a major deal for me. Knowing that having multiple instances of a module on the same page can make your source code behave unpredictably is something we can live with; we just don't load multiple instance of those kinds of modules on the same page, do we? :laugh: I'm just saying that it would be something nice to have—a relatively uncomplicated way of obtaining some information that could be used to control a process within a piece of software.

User avatar
Per Yngve Berg
Joomla! Master
Joomla! Master
Posts: 30929
Joined: Mon Oct 27, 2008 9:27 pm
Location: Romerike, Norway

Re: JModuleHelper::getModule('mod_modulename')->id only gets the first one loaded on a page

Post by Per Yngve Berg » Sun Sep 05, 2021 8:18 am

You are using deprecated 3.x code.

From the J4 mod_menu

Code: Select all

use Joomla\CMS\Helper\ModuleHelper;
use Joomla\Module\Menu\Site\Helper\MenuHelper;

$class_sfx  = htmlspecialchars($params->get('class_sfx'), ENT_COMPAT, 'UTF-8');[(code]

In the J4 mod_custom. $params and $module is used:

[code]$params->get('backgroundimage');
$module->content;
api.joomla.org/cms-4/classes/Joomla.CMS ... elper.html

sozzled
I've been banned!
Posts: 13639
Joined: Sun Jul 05, 2009 3:30 am
Location: Canberra, Australia

Re: JModuleHelper::getModule('mod_modulename')->id only gets the first one loaded on a page

Post by sozzled » Sun Sep 05, 2021 8:47 am

Thanks, Per, you're right. I rewrote the module using the correct syntax like this:

Code: Select all

// no direct access
defined('_JEXEC') or die('Restricted access');
use Joomla\CMS\Factory;
use Joomla\CMS\Helper\ModuleHelper;

$module = JModuleHelper::getModule('mod_mymodule');

$id = $module->id

echo "<p>Module ID=". $id . "</p>"
... ran two instances of it again and it still says that two instances of the same module have the same ID. So, even with fixing the deprecated [J3.x] code, it still isn't detecting the difference between the two instances of the same module. Thanks for trying, Per. :)

I also ran the package through the JED checker component and it didn't detect any problems.

SharkyKZ
Joomla! Hero
Joomla! Hero
Posts: 2906
Joined: Fri Jul 05, 2013 10:35 am
Location: Parts Unknown

Re: JModuleHelper::getModule('mod_modulename')->id only gets the first one loaded on a page

Post by SharkyKZ » Sun Sep 05, 2021 9:35 am

Inside the module entry file you don't need to call JModuleHelper::getModule(). There is already $module variable populated with correct module data. The same is true for J3.

User avatar
Per Yngve Berg
Joomla! Master
Joomla! Master
Posts: 30929
Joined: Mon Oct 27, 2008 9:27 pm
Location: Romerike, Norway

Re: JModuleHelper::getModule('mod_modulename')->id only gets the first one loaded on a page

Post by Per Yngve Berg » Sun Sep 05, 2021 10:54 am

You should be fine when you omit this line:

$module = JModuleHelper::getModule('mod_mymodule');

You are overwriting the already populated variable with generic data.

sozzled
I've been banned!
Posts: 13639
Joined: Sun Jul 05, 2009 3:30 am
Location: Canberra, Australia

Re: JModuleHelper::getModule('mod_modulename')->id only gets the first one loaded on a page

Post by sozzled » Sun Sep 05, 2021 7:50 pm

Thanks, guys. You've helped restore my faith in the usefulness of this forum!

The next step in my plan is to build a very small module for testing purposes consisting only of the two files that are needed to install it (viz., the XML manifest and the PHP "executable"). It shouldn't take me more than a couple of hours to assemble the basics, package it into a ZIP, install it, run it, take a screen capture, and reply to this topic with the results of that test.

I'll return to this discussion in a few hours from now. ;) Thanks again. 8)

sozzled
I've been banned!
Posts: 13639
Joined: Sun Jul 05, 2009 3:30 am
Location: Canberra, Australia

Re: JModuleHelper::getModule('mod_modulename')->id only gets the first one loaded on a page

Post by sozzled » Mon Sep 06, 2021 2:34 am

I've written a brand-new module that simply displays the module's ID/instance.

This is all that is in it:

Code: Select all

// no direct access
defined('_JEXEC') or die('Restricted access');
use Joomla\CMS\Helper\ModuleHelper;

echo "<p>The instance of this module is " . ModuleHelper::getModule('mod_testinstance')->id . "</p>";
The entire package is here:
mod_testinstance.zip
Install the module, create two instances of it and place them on the same page. Here's a screenshot of the result:
modInstance.jpg
Any ideas?
You do not have the required permissions to view the files attached to this post.

User avatar
ceford
Joomla! Hero
Joomla! Hero
Posts: 2677
Joined: Mon Feb 24, 2014 10:38 pm
Location: Edinburgh, Scotland
Contact:

Re: JModuleHelper::getModule('mod_modulename')->id only gets the first one loaded on a page

Post by ceford » Mon Sep 06, 2021 3:38 am

Replace ModuleHelper::getModule('mod_testinstance') with $modiule

So $module->id will show you the id of the module it is in and var_dump($module) will show you all the module properties.

And give us a clue: what are you going to do with the id when you get it?

sozzled
I've been banned!
Posts: 13639
Joined: Sun Jul 05, 2009 3:30 am
Location: Canberra, Australia

Re: JModuleHelper::getModule('mod_modulename')->id only gets the first one loaded on a page

Post by sozzled » Mon Sep 06, 2021 5:10 am

Thanks, for replying, @ceford. Well, well, well!

This is the [entire] module's source code (with the change that you recommended):

Code: Select all

// no direct access
defined('_JEXEC') or die('Restricted access');
use Joomla\CMS\Helper\ModuleHelper;

echo "<p>The instance of this module is " . $module->id . "</p>";
When you do that, it all works! Fantastic-flat-plastic!

What wizardry is that?!?!

Thanks a million for that tip, mate. As I wrote earlier, I spent days trawling all over the internet to discover this piece of information and I couldn't find it. Now I have (and it will probably help other website developers).

I [kind of] have a question about it: where is this documented? After digging around the same question was asked on this forum years ago!

Back in the dark ages of PHP 5 the developers defined these global variables (and you used jimport) in a "helper file". Now that J! uses PHP 7 namespaces, use namespace does things simpler. Thanks to Per's earlier suggestion about deprecated code, I tidied up my code. I should probably tidy up my code in a few other places too! :laugh:

As for practical uses, here's one example (although it's not the application that I have in mind): viewtopic.php?t=535332.

In my case, I need the information to insert a row in a database table, if it doesn't exist, populated with the module's ID and other data and, when the module is executed, update the record (or records) with new data.

So, thanks to this forum, I found the information. Thanks to everyone who was involved. :)

And, BTW, if anyone wants a carte-blanche version of the module to play with, I'm attaching it here:
You do not have the required permissions to view the files attached to this post.

SharkyKZ
Joomla! Hero
Joomla! Hero
Posts: 2906
Joined: Fri Jul 05, 2013 10:35 am
Location: Parts Unknown

Re: JModuleHelper::getModule('mod_modulename')->id only gets the first one loaded on a page

Post by SharkyKZ » Mon Sep 06, 2021 5:31 am

For what it's worth, this is the old way of writing modules. You might want to try the new J4 way now :D.

sozzled
I've been banned!
Posts: 13639
Joined: Sun Jul 05, 2009 3:30 am
Location: Canberra, Australia

Re: JModuleHelper::getModule('mod_modulename')->id only gets the first one loaded on a page

Post by sozzled » Mon Sep 06, 2021 5:41 am

I certainly will be using the improved method of writing modules this way, thanks, @SharkyKZ. :D

User avatar
ceford
Joomla! Hero
Joomla! Hero
Posts: 2677
Joined: Mon Feb 24, 2014 10:38 pm
Location: Edinburgh, Scotland
Contact:

Re: JModuleHelper::getModule('mod_modulename')->id only gets the first one loaded on a page

Post by ceford » Mon Sep 06, 2021 7:13 am

For anyone developing a J4 Module:

Go to the Joomla 4 Tutorials page:

https://docs.joomla.org/JDOC:Joomla_4_Tutorials_Project

And follow the link to the Creating a Simple Module item:

https://docs.joomla.org/J4.x:Creating_a_Simple_Module

There is another example too:

https://docs.joomla.org/J4_Module_example_-_Mydownmsg

SharkyKZ
Joomla! Hero
Joomla! Hero
Posts: 2906
Joined: Fri Jul 05, 2013 10:35 am
Location: Parts Unknown

Re: JModuleHelper::getModule('mod_modulename')->id only gets the first one loaded on a page

Post by SharkyKZ » Mon Sep 06, 2021 7:33 am

All those tutorials are using old conventions with single entry file.

User avatar
ceford
Joomla! Hero
Joomla! Hero
Posts: 2677
Joined: Mon Feb 24, 2014 10:38 pm
Location: Edinburgh, Scotland
Contact:

Re: JModuleHelper::getModule('mod_modulename')->id only gets the first one loaded on a page

Post by ceford » Mon Sep 06, 2021 7:55 am

SharkyKZ wrote:
Mon Sep 06, 2021 7:33 am
All those tutorials are using old conventions with single entry file.
I am not clear what you mean by single entry file. Can you point me to where can I find information on the new conventions? Or can you point me to a good example in the core modules. I could revise the tutorials.

SharkyKZ
Joomla! Hero
Joomla! Hero
Posts: 2906
Joined: Fri Jul 05, 2013 10:35 am
Location: Parts Unknown

Re: JModuleHelper::getModule('mod_modulename')->id only gets the first one loaded on a page

Post by SharkyKZ » Mon Sep 06, 2021 8:11 am

mod_quickicon is so far the only core module to use new conventions.


Locked

Return to “Joomla! 4 Related”