3

In Joomla 3.x we can use the JLayout class to override the files located in ROOT/layouts folder

According to this doc http://docs.joomla.org/J3.x:JLayout_Improvements_for_Joomla!

all we need to do is add something like this;

        $layout = new JLayoutFile('joomla.edit.frontediting_modules'); 
        $layout->addIncludePaths(YJSGPATH .'includes/html/layouts');

        print_r($layout);

This snippet is added in my system plugin in onAfterRoute function.

Now the array looks fine and points to the right direction

JLayoutFile Object
(
    [layoutId:protected] => joomla.edit.frontediting_modules
    [basePath:protected] => 
    [fullPath:protected] => 
    [includePaths:protected] => Array
        (
            [0] => D:\wamp\www\Development\Yjsgv2-DEV\3x\plugins\system\yjsg\includes/html/layouts
            [1] => D:\wamp\www\Development\Yjsgv2-DEV\3x/templates/creatus/html/layouts
            [2] => D:\wamp\www\Development\Yjsgv2-DEV\3x/layouts
        )

    [options:protected] => Joomla\Registry\Registry Object
        (
            [data:protected] => stdClass Object
                (
                    [component] => 
                    [client] => 0
                )

        )

    [debugMessages:protected] => Array
        (
        )

)

and file frontediting_modules.php is located in my folder http://prntscr.com/4lijlf

but the override is not happening.

I removed the call for bootstrap popover and tooltips http://prntscr.com/4lijz3 just to test it but it does not work

if I move the override folder to my template html folder the override works.

Can someone please advise.

Thank you!

3 Answers 3

5

The addIncludePaths call only affects that particular instance of the $layout variable. Unless you are also rendering the layout in the plugin, your code will have no effect on the actual rendering.

It looks like you are trying to affect this line from the document renderer:

JLayoutHelper::render('joomla.edit.frontediting_modules', $displayData);

This uses the JLayoutHelper's render method which will instantiate a new instance of JLayoutFile:

public static function render($layoutFile, $displayData = null, $basePath = '', $options = null)
{
    $basePath = empty($basePath) ? self::$defaultBasePath : $basePath;

    // Make sure we send null to JLayoutFile if no path set
    $basePath = empty($basePath) ? null : $basePath;
    $layout = new JLayoutFile($layoutFile, $basePath, $options);
    $renderedLayout = $layout->render($displayData);

    return $renderedLayout;
}

To do what you are trying to do, you would have to get your line ($layout->addIncludePaths(YJSGPATH .'includes/html/layouts');) in between the $layout setting and the render call within this method.

Since that would involve editing the core code, you will likely want to avoid it. However, there does not appear to be a way to do what you are trying to do in the CMS (yet!).

This is a very new piece of the CMS, so this will likely be an option in the future, but it just isn't there yet.

2
  • Thnx for explaining and yes that is what I am trying to do , tell Jlayout class to include my layout folder to look for overrides. So basic "where" to look for override does not work unless you are also rendering the layout variable.
    – Dan
    Sep 10, 2014 at 17:43
  • 1
    Correct. Otherwise it falls back to the two defaults, which is why putting it in your template was still working. Sep 10, 2014 at 17:44
2

OK , found a workaround since we are already extending few classes I managed to extend the JLayoutFile class and add my path in between layout and template/html/layout

via this method How to override core classes?

http://prntscr.com/4ln5dt

so the array now reads

JLayoutFile Object
(
    [layoutId:protected] => joomla.edit.frontediting_modules
    [basePath:protected] => 
    [fullPath:protected] => 
    [includePaths:protected] => Array
        (
            [0] => D:\wamp\www\Development\Yjsgv2-DEV\3x/templates/creatus/html/layouts
            [1] => D:\wamp\www\Development\Yjsgv2-DEV\3x\plugins\system\yjsg\includes/html/layouts
            [2] => D:\wamp\www\Development\Yjsgv2-DEV\3x/layouts
        )

    [options:protected] => Joomla\Registry\Registry Object
        (
            [data:protected] => stdClass Object
                (
                    [component] => 
                    [client] => 0
                )

        )

    [debugMessages:protected] => Array
        (
        )

)

And checks

  • layouts
  • my_plugin/layouts
  • template/html/layouts

it would be great if we can just do

jimport('cms.layout.file');
JLayoutFile::addIncludePath(YJSGPATH .'includes/html/layouts');

in the future since the addIncludePath method already exists.

1
  • 1
    The best part is that you could be the one to make it happen! Editing the core files is great if you then make a pull request on github! ;) Sep 11, 2014 at 1:46
2

Just stumbled upon this; the top answer is not correct, and the workaround offered is not needed. As they were posted a long time ago, information was probably not well known at the time.

It is the main purpose of JLayout to be overridable, so it was the case from day 1 (in Joomla 3.0.0).

All you have to do to override, say joomla.edit.frontediting_modules is to coy the original layout file to your template override folder. In that example, you would copy:

/layouts/joomla/edit/frontediting_modules.php

to

/templates/{your_templates}/html/layouts/joomla/edit/frontediting_modules.php

and just make your changes as usual for other types of overrides.

Here is the corresponding Joomla documentation page (Look at the "Template overrides" paragraph.

Rgds

1
  • This answer should be paste as an EDIT in the one that is checked as correct answer, which is outdated. Dec 7, 2017 at 22:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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