Extend the core Joomla\CMS\Document\Document class with own class to add scripts to footer

by thednp   Last Updated October 08, 2019 12:10 PM - source

I've been looking for a way to add scripts in footer in Joomla and the only thing I found is this github repository, but it requires changes to the Joomla core libraries/src/Document/Document.php file and we don't like that. So I made a footer.php inside my templateNAME\helpers folder with the following content:

<?php // footer.php

namespace Joomla\CMS\Document;

// No direct access
defined('JPATH_BASE') or die;

use Joomla\CMS\Factory;
use Joomla\CMS\Document\Document;

class FooterDocument extends Document
{
  public $_footer_scripts = array();

  public function __construct($options = array())
  {
    parent::__construct($options);

    // I wish I could link these to the parent somehow, but extend should do that anyway
    parent['addFooterScript'] = $this->addFooterScript($url = null);  
    parent['_footer_scripts'] = $this->_footer_scripts;  
  }

  // Method to addScriptsToFooter
  public function addFooterScript($url, $type = "text/javascript", $defer = false, $async = false) {
    $this->_footer_scripts[$url]['mime'] = $type;
    $this->_footer_scripts[$url]['defer'] = $defer;
    $this->_footer_scripts[$url]['async'] = $async;
    return $this;
  }

  public function render($cache = false, $params = array())
  {
    ob_start();
    echo $this->fetchFooter($this->_doc);
    $buffer = ob_get_contents();
    ob_end_clean();
    return $buffer;
  }
  public function fetchFooter(&$document)
  {
    $app = Factory::getApplication();
    $app->triggerEvent('onBeforeCompileFooter');
    $lnEnd   = $document->_getLineEnd();
    $tab   = $document->_getTab();
    $buffer   = '';
    foreach ($document->_footer_scripts as $strSrc => $strType) {
      $buffer .= $tab.'<script type="'.$strType['mime'].'" src="'.$strSrc.'"></script>'.$lnEnd;
    }

    return $buffer;
  }
}

In my index.php file of my template I'm registering the new class like so

JLoader::register('Joomla\\CMS\\Document\\FooterDocument', __DIR__ . '\helpers\footer.php');

then call the new method to use it

$doc->addFooterScript( __DIR__ . '/javascript/template.js');

This throws the following error:

0 Call to undefined method Joomla\CMS\Document\HtmlDocument::addFooterScript()
............\templates\templateNAME\index.php:90

Alternatively there is this ScriptsDown plugin that uses $app->getBody() and $app->setBody() to move one and/or more scripts to footer.

I need a way to be able to include JavaScript files in template footer, via $doc->addFooterScript('JavaScript_File_Path.js'); or something like MyTemplateHelper::addFooterScript('path_to_file.js'); either using the first method via the footer.php -> FooterDocument class or the alternate ScriptsDown method inside MyTemplateHelper class.



Related Questions


How to set html5 property within template.php

Updated April 04, 2015 17:04 PM



Load javascript script before </body> closing tag

Updated August 05, 2015 13:04 PM

Control order of loaded scripts

Updated January 11, 2018 17:10 PM