Symfony assetic sass filter via node-sass? Symfony assetic sass filter via node-sass? symfony symfony

Symfony assetic sass filter via node-sass?


I'd like to share my solution to this issue for anybody out there who might be experiencing it as well.

It appears that the BaseSassFilter is suited to work only with the ruby version. So I decided to create my own filter. Here is my class:

<?phpnamespace App\YourBundle\Assetic\Filter;use Assetic\Asset\AssetInterface;use Assetic\Exception\FilterException;use Assetic\Filter\Sass\BaseSassFilter;use Assetic\Filter\Sass\SassFilter;/** * This class is based on Assetic\Filter\Sass\SassFilter and is slightly modified to work with node-sass instead of Ruby. */class NodeSassFilter extends BaseSassFilter{    const STYLE_NESTED     = 'nested';    const STYLE_EXPANDED   = 'expanded';    const STYLE_COMPACT    = 'compact';    const STYLE_COMPRESSED = 'compressed';    private $sassPath;    private $scss;    private $style;    private $quiet;    private $cacheLocation;    public function __construct($sassPath = '/usr/bin/node-sass')    {        $this->sassPath = $sassPath;        $this->cacheLocation = realpath(sys_get_temp_dir());    }    public function setScss($scss)    {        $this->scss = $scss;    }    public function setStyle($style)    {        $this->style = $style;    }    public function setQuiet($quiet)    {        $this->quiet = $quiet;    }    public function filterLoad(AssetInterface $asset)    {        $sassProcessArgs = array($this->sassPath);        $pb = $this->createProcessBuilder($sassProcessArgs);        if ($dir = $asset->getSourceDirectory()) {            $pb->add('--include-path')->add($dir);        }        if ($this->style) {            $pb->add('--output-style')->add($this->style);        }        if ($this->quiet) {            $pb->add('--quiet');        }        // input        $pb->add($input = tempnam(sys_get_temp_dir(), 'assetic_sass'));        file_put_contents($input, $asset->getContent());        $proc = $pb->getProcess();        $code = $proc->run();        unlink($input);        if (0 !== $code) {            throw FilterException::fromProcess($proc)->setInput($asset->getContent());        }        $asset->setContent($proc->getOutput());    }    public function filterDump(AssetInterface $asset)    {    }}

Then, in your config.yml you add the following:

assetic:    filters:        nodesass:            bin: "%sass.bin%"            resource: '%kernel.root_dir%/config/filters/nodesass.xml'            style: compressed            apply_to: "\.scss%"

In app/config/filters/nodesass.xml you add the following xml:

<?xml version="1.0" ?><container xmlns="http://symfony.com/schema/dic/services"           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"           xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">    <parameters>        <parameter key="assetic.filter.nodesass.class">App\YourBundle\Assetic\Filter\NodeSassFilter</parameter>        <parameter key="assetic.filter.nodesass.bin">%assetic.sass.bin%</parameter>        <parameter key="assetic.filter.nodesass.timeout">240</parameter>        <parameter key="assetic.filter.nodesass.style">null</parameter>        <parameter key="assetic.filter.nodesass.load_paths" type="collection" />    </parameters>    <services>        <service id="assetic.filter.nodesass" class="%assetic.filter.nodesass.class%">            <tag name="assetic.filter" alias="nodesass" />            <argument>%assetic.filter.nodesass.bin%</argument>            <call method="setTimeout"><argument>%assetic.filter.nodesass.timeout%</argument></call>            <call method="setStyle"><argument>%assetic.filter.nodesass.style%</argument></call>            <call method="setLoadPaths"><argument>%assetic.filter.nodesass.load_paths%</argument></call>        </service>    </services></container>

This should get things working for now.