0

I am building a custom module for Joomla. Let's call the module "mod_mygallery". Inside the module I have a the files mod_mygallery.php, helper.php and mod_mygallery.xml. And off course I also have the tmpl/default.php file.

Since I am still pretty new at building my own components and modules, I would like some input on how to deal with JavaScript and jQuery inside the template php file.

I am trying to keep my tmpl file as clean as possible. Adding stylesheets, scripts and declaring php vars is all done inside the main mod_mygallery.php file, with some help from my helper class in helper.php.

The module works fine as it is. But I wonder what is best practice to add some jQuery on document ready. Currently, I have declare a JS variable that gets an object from php. On document ready the object is used to initialize my gallery (using light gallery). This is my tmpl/default.php:

<?php
defined('_JEXEC') or die;
?>

<div id="gallery" class="gallery">
    <?php echo $images; ?>
</div>

<script type="text/javascript">
const gallerySettings = <?php echo json_encode($gallerySettings, JSON_PRETTY_PRINT); ?>;
jQuery(document).ready(function() {
    jQuery("#gallery").lightGallery(
        gallerySettings
    );
});
</script>

Is this good practice? How would you do it? I would prefer to also keep my JS outside of the template file, but I'm not sure how. Or am I overthinking it?

Thanks for any insights on this.

6
  • 1
    Generally speaking, it should always be encouraged to put js and css in separate/external files. If you are going to add the js in your php, I see no reason to declare the gallerySettings constant. just echo the json directly into lightGallery(). Essentially, I'm advising to avoid declaring "single-use" variables/constants. Commented Jun 14, 2020 at 22:36
  • Hi @mickmackusa. Yes, for that reason I would prefer to not have it inside my template php file. But it would mean I have to pass the php var to an external JS file and I'm not sure how to do it... About the single-use var: I tried declaring the gallerySettings json directly into lightgallery(). But the json did not render, and as a result the gallery did not work. I assumed this is because php parsed before the document is ready. By asigning it to a var before using it in document ready, it works.
    – TVBZ
    Commented Jun 14, 2020 at 23:02
  • 1
    Surely this will work: <script type="text/javascript"> jQuery(document).ready(function() { jQuery("#gallery").lightGallery(<?php echo json_encode($gallerySettings, JSON_PRETTY_PRINT); ?>); }); </script> ...it does the same thing without the constant needing to be declared. Commented Jun 14, 2020 at 23:19
  • Yes. Just tried it again just to be sure and it works. I guess I had a type somewhere before. :) Thanks @mickmackusa. Still not sure how to get the JS out of the template file. Any ideas?
    – TVBZ
    Commented Jun 14, 2020 at 23:23
  • 1
    docs.joomla.org/J3.x:Adding_JavaScript_and_CSS_to_the_page see the section about passing options. Commented Jun 15, 2020 at 0:09

2 Answers 2

2

Adding stylesheets, scripts and declaring php vars is all done inside the main mod_mygallery.php file

This is bad. Styles and scripts should be added in layout files to allow overriding with ease. This way unneeded assets can even be removed.

Adding JavaScript manually is bad also. You should use Document API instead.

You could avoid JS code cluttering your layout file by using Joomla\CMS\Document\Document::addScriptOptions() instead. Though this would require adding another JS file or modifying existing one to handle initialization of your script.

5
  • The scripts and stylesheets I am adding outside the layout files are added using document api, using conditional logic based on module settings. There are no unused recourses loaded. Removing these resources would break the module configuration options. In this case, you would still recommend to put all that conditional logic inside the layout files?
    – TVBZ
    Commented Jun 15, 2020 at 23:28
  • I am building the json for initialization of the gallery inside a helper function. Just because there is also lots of conditional logic used there. I could make use of addScriptDeclaration inside the layout file, but it would still result in inline JS. Would it not be better to use external file for script initialization?
    – TVBZ
    Commented Jun 15, 2020 at 23:37
  • 1
    "There are no unused recourses loaded." - don't trust that. It's up to end users to decide what's used and what's not. Imagine a simple case: user has your extension installed, as well as a different extension also using lightGallery. Two instances of the same library are loaded, causing both extensions to break, as well as bringing down client side performance.
    – Sharky
    Commented Jun 17, 2020 at 8:31
  • I see. Yes. I will rewrite that. Thanks :)
    – TVBZ
    Commented Jun 17, 2020 at 17:51
  • Thanks for the hint to addScriptOptions. That works great! :)
    – TVBZ
    Commented Jun 17, 2020 at 17:56
0

Here is the standard way of adding JavaScript code any extension in Joomla:

function getToolTipJS($toolTipVarName, $toolTipClassName){
    $javascript = 'window.addEvent(\"domready\", function(){' ."\n";
    $javascript .= "\t"  .'var $toolTipVarName = new Tips($$("' . $toolTipVarName .'"), {' ."\n";
    $javascript .= "\t\t"   .'className: "' .$toolTipClassName .'",' ."\n";
    $javascript .= "\t\t"   .'initialize: function(){' ."\n";
    $javascript .= "\t\t\t"    .'this.fx = new Fx.Style(this.toolTip, "opacity", {duration: 500, wait: false}).set(0);' ."\n";
    $javascript .= "\t\t"   .'},' ."\n";
    $javascript .= "\t\t"   .'onShow: function(toolTip){' ."\n";
    $javascript .= "\t\t\t"    .'this.fx.start(1);' ."\n";
    $javascript .= "\t\t"   .'},' ."\n";
    $javascript .= "\t\t"   .'onHide: function(toolTip) {' ."\n";
    $javascript .= "\t\t\t"    .'this.fx.start(0);' ."\n";
    $javascript .= "\t\t"   .'}' ."\n";
    $javascript .= "\t"  .'});' ."\n";
    $javascript .= '});' ."\n\n";
    return $javascript;
}

    $document = JFactory::getDocument();
    $document->addStyleSheet("/joomla/components/com_mycustomcomponent/css/mytooltip.css",'text/css',"screen");
    $document->addScriptDeclaration(getToolTipJS("mytool","MyToolTip"));

Reference: https://docs.joomla.org/J3.x:Adding_JavaScript_and_CSS_to_the_page

2
  • I know that this code snippet is from official Joomla documents but I would never use this. It looks like an extremely bad style of coding.
    – Zollie
    Commented Jun 15, 2020 at 7:44
  • Just another case of the Joomla Docs needing some Tender Loving Care. Commented Jun 17, 2020 at 22:36

Your Answer

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

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