2

I know in a template you can add

<jdoc:include type="modules" name="newposition"   />

and then within the positions tags you add your new position.

<positions>
     <position>newposition</position>
</positions>

But I also know you can just create a position out of nowhere by typing it in the module back end in the position slot.

Adding a new module position in the Joomla! module backend

And then you can do module loadposition.

{loadposition some_position}

But if I echo this text in my module it's just text (a string). If I echo the XML that's also a string, but I never expected that to work as it's not in the XML file.

Is it possible to add a module position within a module?

I'd rather do this the built in Joomla! way than using any extensions.

I have tried it with a content prepare plugin but I would rather try Sharky's method but I cannot get it working. Here is what I have tried.

<?php 
use Joomla\CMS\Factory;
?>

<div class="ui-nav ui-nav-mobile">
    <div class="g-content">
    <a class="ui-btn ui-menu-close">Close <i class="fa fa-close" aria-label="Close dialog"></i></a>        
    <?php
        foreach ($subform_items as $item) {
            $position_name = "{loadposition " . $item->position_name_x . "}";
         $modulePositions = JHtml::_('content.prepare', $position_name, '', 'mod_koy_sticky_contact.content');
            //$modulePositions = Factory::getApplication()->getDocument()->loadRenderer('modules')->render($position_name);
            echo "<div class='" . $item->position_name_x . "'>" . $modulePositions . "</div>";
        }
    ?>
    </div>
</div>

The commented out part shows a blank, but the other version works.

2

Although using content plugin works, there is no need for it in PHP code. Instead you can use the document renderer directly:

use Joomla\CMS\Factory;

echo Factory::getApplication()->getDocument()->loadRenderer('modules')->render($position);
  • Nice. Is getDocument still being used in J4? I should update my instance to use HTMLHelper instead of JHtml – Eoin Jun 26 at 19:51
  • 1
    \Joomla\CMS\Factory::getDocument() works in J4 but is deprecated. Instead could use \Joomla\CMS\Factory::getApplication()->getDocument(). It works in J3 too. – Sharky Jun 26 at 20:13
  • 1
    My method doesn't run unneeded code. – Sharky Jun 27 at 5:58
  • 1
    No. mod_custom intends to trigger content plugins. – Sharky Jun 27 at 13:11
  • 1
    You are passing a shortcode ($position_name), not the position ($item->position_name_x) to render() call. Also, you can move Factory::getApplication()->getDocument()->loadRenderer('modules') out of the loop. – Sharky Jul 19 at 22:13
1

It probably depends on specific circumstances. I have custom modules that contain several 'secondary' modules. I accomplish this using the Modules Anywhere extension and add {example module} to the code for the module I'm putting it in. You don't need to include a module position in the module settings to use Modules Anywhere.

https://extensions.joomla.org/extensions/extension/core-enhancements/coding-a-scripts-integration/modules-anywhere/

  • Hmm, yes, I'm aware of that extension and it is useful. – Eoin Dec 29 '18 at 0:09
0

I AM LEAVING THIS HERE IN CASE SOMEONE NEEDS TO KNOW HOW TO DO THIS. BUT THE ANSWER ABOVE IS BETTER.

You need to switch on the content plugin

Trigger the onContentPrepare plugin event

https://docs.joomla.org/Triggering_content_plugins_in_your_extension

I ended up creating a Joomla! subform so I could add multiple positions. Here is my code.

        foreach ($subform_items as $item) {
            $position_name = "{loadposition " . $item->position_name_x . "}";
            $modulePositions = JHtml::_('content.prepare', $position_name, '', 'mod_my_module.content');
            echo $modulePositions;
        }

What this is doing is:

  1. A foreach on my XML to gain each position.
  2. Use the usual {loadposition yourPositionName} code that can be seen here: https://docs.joomla.org/How_do_you_put_a_module_inside_an_article%3F
  3. Usually you would manually type it or use the Editor Module Plugin, in my example I used yourPositionName, but in real life I wanted these positions to come from my module where there is a repeatable field. So I called $position_name_x which is part of the params of my $item.
  4. I then echo my position name. Without content prepare it will echo a literal string {yourPositionName} and not the modules in that position, but with content prepare it will send you the modules. This is using the system plugin onContentPrepare I believe.

I hope that helps someone

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.