1

I've created a custom form field for templates, which is meant to handle SCSS compile. In short, I've opened an issue on Github where I had a little chat with one of the Joomla devs about wasm compile.

Here is a basic structure of my custom field:

namespace Joomla\Template\Cassiopeia\Site\Field;

\defined('JPATH_PLATFORM') or die;

class ScssCompileField extends FormField
{
    protected $type = 'ScssCompile';
    protected $template;
    protected $scssContent = '';

    public function setup(\SimpleXMLElement $element, $value, $group = null)
    {
        if (!parent::setup($element, $value, $group))
        {
            return false;
        }

        // this is the template
        $this->template = $this->form->getValue('template');

        // here are the inputFile and outputFile
        $this->inputFile = 'template.scss'; // the path is handled by the resolve
        $this->outputFile = JPATH_SITE . '/templates/' . $this->template . '/css/template.css';

        // here's adding the scripts and such
        HTMLHelper::_('script', 'templates/' . $this->template . '/js/system/sass.js');
        HTMLHelper::_('script', 'templates/' . $this->template . '/js/system/sass.worker.js');
        HTMLHelper::_('script', 'templates/' . $this->template . '/js/system/scss-compile.js', array(), array("type" => "module"));
        return true;
    }  

    public static function scssResponseAjax(){
        $this->concatContent($this->inputFile);
        return json_encode($this->scssContent);
    }  

    public static function scssWriteAjax($response){
        if (file_exists($this->outputFile) && is_writable($this->outputFile)) {
            file_put_contents($this->outputFile, $response);
        }
    }  

    // this is the button the user will interact with
    protected function getInput(){
        return '<button id="compileButton" class="btn btn-success">Compile</button>';
    }

    // this method will fill the SCSS content
    protected function concatContent(){}

    // other methods that handle paths resolve and such
}

Now, as the author of the wasm script instructed, I've create a JS module scss-compile.js:

'use strict';

function compileSCSS(){ 
  const compileOps = {
    style: Sass.style.expanded,
    precision: -1,
    comments: false,
    indent: '  ',
    linefeed: '\n',
  };

  // const response = await fetch('com_ajax...', {'GET' ... });

  // compile given SCSS content
  Sass.compile(response, compileOps, function callback(result) {
    return result.text
  });
}

document.getElementById('compileButton').addEventListener('click', compileSCSS);

Now I don't know what the await fetch function looks like and what com_ajax expects me to pass in to connect to the ScssCompileField class, nor do I know if my methods which this script is supposed to interact with are correct.

After some research, I noticed people mention about the Joomla Input class with its set, get and other methods within com_ajax context, I wonder if that would be useful for my custom field methods.

Please advise.

1 Answer 1

1

com_ajax looks for a helper.php file in your root template directory and then searches for the method inside there, so you firstly need to create a helper.php with the following code:

class TplCassiopeiaHelper
{
    public static function scssResponseAjax()
    {
        return file_get_contents(JPATH_SITE . '/templates/cassiopeia/scss/template.scss');
    }
}

Then, remove the following line:

HTMLHelper::_('script', 'templates/' . $this->template . '/js/system/sass.worker.js');

Then in your scss-compile.js:

'use strict';

async function compileSCSS() {
  const sass = new Sass()

  const compileOps = {
    style: sass.style.expanded,
    precision: -1,
    comments: false,
    indent: '  ',
    linefeed: '\n',
  }

  const response = await fetch('index.php?option=com_ajax&template=cassiopeia&method=scssResponse&format=raw', {
    method: 'GET',
    headers: {
      'Content-Type': 'plan/text',
    }
  })
  const content = await response.text()

  // Log the SCSS
  console.log(content)

  // Compile
  sass.compile(content, compileOps, function callback(result) {
    // Log the CSS
    console.log(result.text)

    // Now fire another fetch request to send the CSS and save the file in PHP
  })
}

document.addEventListener('DOMContentLoaded', () => {
  document.getElementById('compileButton').addEventListener('click', compileSCSS)
})
11
  • Thanks man. I'm finishing some commit to Joomla and will get back to this. I will provide feeedback asap. Cheers!
    – thednp
    Commented Mar 5, 2021 at 16:31
  • For some reason, on click it throws me out of the template style panel after "thinking" a bit, for sure that sass.compile you got there won't work with sass.js, it needs the data pre-loaded, which is what is missing from my above PHP and added here github.com/thednp/scss-wasm-compile/blob/master/templates/…. Basically I've added all those class functions to TplCassiopeiaHelper and setup() is now init(). I'm executing init() then concatContent then return it. But can't get any response anywhere for now. Researching...
    – thednp
    Commented Mar 5, 2021 at 18:43
  • I think this has to be related to github.com/joomla/joomla-cms/pull/32291 and my commit github.com/joomla/joomla-cms/pull/30816
    – thednp
    Commented Mar 5, 2021 at 18:57
  • Hmm well it was working perfect fine for me. I got the CSS output. It doesn't need anything preloaded, but yeah the namespace thing is probably your issue at the moment. I haven't namespaced my template
    – Lodder
    Commented Mar 5, 2021 at 19:15
  • 1
    Thanks man, much appreciated. I would suggest we wait and let them handle all those nasty inter-dependent PRs. I think it's a waste of time to deal with this at this point, but we MUST contribute to the Joomla GIT with testing and PRs. I've heard you like my color-picker ;)
    – thednp
    Commented Mar 5, 2021 at 19:54

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.