Adding a Compile LESS Button to a Joomla 3.2 Template

There was no big announcement, but you may have noticed that the Joomla 3.2.2 templates area now has a compile LESS button when viewing a less file.

I had a look at how to bring this into a custom template without having to use a plugin, giving you the possibility to compile a templates less files from within the template style administration area.

The new integrated compiler in the com_templates component has a function which calls the framework on framework LESS compiler.

The problem is that a template is not a component and you cannot add a custom button to the toolbar which calls a function without the aid of a plugin to run the code when a user clicks on the button.

The first thoughts were to look in to using the new com_ajax component which should make it easy to interact with components that were developed by other people. This would give the possibility to compile without refreshing the page and keep unsaved parameters.

Unfortunatly, the template components function uses the current encrypted url to find the file that needs to be compiled and there doesn't seem to be an easy way to pass it the correct information of what should be compiled and to where.

Fortunatly, the templates component is using the FoF library, so there is nothing to stop us from using that too. It makes it impossible (as far as I know) to compile with ajax, but the template component doesn't do that either.

So, without further ado, the code.

Adding A field Path

In the templates templateDetails.xml file we need to specify a location that holds our custom fields. This goes on the fields tag.

 <fields name="params" addfieldpath="/templates/templatename/fields">

Then we can add a field of the type we are about to create called compile.

<field name="compile" type="compile" label="compile LESS files" />

Now as our template is called 'templatename' and we specified the folder 'fields' to look for new fields, we can add the file compile.php to that folder for it to be used in our new compile field.

Adding the New Compiler Field

So here is the contents of the compile.php file:

<?php
/**
* @package Joomla.Site
* @subpackage Templates.dna
*
* @copyright Copyright (C) 2014 Robert Went. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('_JEXEC') or die('caught by _JEXEC');
class JFormFieldCompile extends JFormField
{
protected function getInput()
{

$app = JFactory::getApplication();
$jinput = $app->input;
$compile = 0;
$compile = $jinput->get('compileless');
$currentpath = realpath(__DIR__ ) ;
$pageurl = str_replace('&compileless=1', '', JURI::getInstance ());
if ($compile) {
// Load the RAD layer to use its LESS compiler
if (!defined('FOF_INCLUDED'))
{
require_once JPATH_LIBRARIES . '/fof/include.php';
}
$less = new FOFLess;
$less->setFormatter(new FOFLessFormatterJoomla);
try
{
$less->compileFile($currentpath. '/../less/template.less', $currentpath.'/../css/template.less'); }
catch (Exception $e)
{
$app->enqueueMessage($e->getMessage(), 'error');
}
}
return '<button onclick="window.location.href=\''.$pageurl.'\'+\'&compileless=1\'" class="btn btn-primary" type="button">Compile Less</button>';
}
}
?>

You can find out about the general custom field code from the Joomla docs site here: Creating custom fields in Joomla

So first of all we are setting some variables to store the current page url so we can check if the less files should be compiled or not and setting the path to the current directory so we can point the compiler to the correct files.

Next, we check the current url to see if the post value 'compileless' is defined, and if so, start the machine....

We first check if FOF is included and if not, import the library so we can use the LESS compiler. Start a new instance of FOFLess and then feed it the file to compile and let it know where the outputted file should be placed. It then compiles the filess, catching any errors and sending them to Joomla's message area if needed.

After the check is made to see if compilation should take place we then create the actual button to start the process by returning a html string. The field outputs a standard bootstrapped button that has an onclick event to refresh the page adding the query string '&compileless=1' which we just checked for when loading the page.

Hmm... that's about it. We now either have a compiled less file or an error message.

As the button refreshes the page, any unsaved changes will be lost, but you could easilly expand the field to check for clicks to prompt the user to save first.

 In this example, the paths to the LESS and CSS directories are assumed to be one level below the location of the field file, as if it were in a folder called 'fields' as specified in the fieldpath attribute.