How to compile SASS (scss) using plain PHP in Symfony 3

How to compile SASS (scss) using plain PHP in Symfony 3

The way in which developers work on Web applications changes everyday, many application nowadays integrate JavaScript and CSS manipulation on the fly, which means that the production source code is created automatically by some PHP scripts. SASS, the extension of CSS that enables you to use variables, nested rules, inline imports and also helps to keep your CSS things organised and allows you to create style sheets faster is one of those technologies that everybody is using as well today. If you are looking to integrate a SCSS compiler in your Symfony project, today is your lucky day as scssphp does this for you.

scssphp is a compiler library for SCSS written in pure PHP, scssphp is ready for inclusion in any project. It includes a command line tool for running the compiler from a terminal/shell or script. In this article you will learn how to use it in your Symfony 3 project.

1. Install scssphp

The preferred way to install the library to compile sass in PHP is via composer, so switch to the directory of your project and install it with the following command:

composer require leafo/scssphp

After the installation you will be able use the Compiler class of the package in your controllers or symfony services. For more information about this library, please visit the official documentation or the official repository at Github here.

2. Using the Compiler

As mentioned, the library is pretty easy to use and is pretty well document. Offers a lot of features, like the declaration of variables with PHP (preset variables), customization of import paths etc. We'll show you how to achieve the most typical tasks with the compiler in Symfony controllers:

A. Compiling a SCSS string and returning a CSS response

Create a compiler instance and run the compile method with the SCSS string as first argument. This will return the CSS result as a string that you can use to send as response in the controller:

<?php

namespace AppBundle\Controller;

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\HttpException;

// Use the Sass compiler
use Leafo\ScssPhp\Compiler;

class DefaultController extends Controller
{
    /**
     * @Route("/", name="homepage")
     */
    public function indexAction(Request $request)
    {
        // Create an instance of the Sass Compiler class
        $scss = new Compiler();

        // Sass String
        $sassString = '$color: #abc; div { color: lighten($color, 20%); }';

        // Compile the sass string and store the CSS result in another variable
        $css = $scss->compile($sassString);
        
        // Return a response of CSS Type
        $response = new Response();
        $response->setContent($css);
        $response->setStatusCode(Response::HTTP_OK);
        $response->headers->set('Content-Type', 'text/css');
        return $response;
    }
}

B. Compiling a SCSS file and writing into a css file

The compiler library doesn't offer a way to write from a file to another, so you will have to get the output of the compiler and write it into a new file. The following example shows how to compile the all.scss file to the all.css file:

Note

If you don't like to use plain methods of PHP to read and write files (file_put_contents and file_get_contents), you may want to use instead the Filesystem package of Symfony.

<?php

namespace AppBundle\Controller;

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\HttpException;

// Use the Sass compiler
use Leafo\ScssPhp\Compiler;

class DefaultController extends Controller
{
    /**
     * @Route("/", name="homepage")
     */
    public function indexAction(Request $request)
    {
        // Create an instance of the Sass Compiler class
        $scss = new Compiler();

        // Path to the folder of the sass files
        $sassFilesPath = $this->get('kernel')->getRootDir() . '/../web/assets/sass/';
    
        // Path to the folder of css files
        $cssFilesPath = $this->get('kernel')->getRootDir() . '/../web/assets/css/';

        // Write output css file
        file_put_contents(
            $cssFilesPath. "all.css",
            // Set the content of all.css the output of the
            // sass compiler from the file all.scss
            $scss->compile(
                // Read content of all.scss
                file_get_contents(
                    $sassFilesPath. "all.scss"
                )
            )
        );

        return new Response("Sass File Succesfully compiled");
    }
}

C. Changing CSS Output Format

The compiler by default uses the Nested output formatter that outputs CSS of the following type:

.navigation ul {
  line-height: 20px;
  color: blue; }
  .navigation ul a {
    color: red; }

.footer .copyright {
  color: silver; }

In some cases, you may want readable versions of the code or even minified versions. The compiler allows you to change the style of the output using one of its custom formatters using the setFormatter method:

<?php

namespace AppBundle\Controller;

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\HttpException;

// Use the Sass compiler
use Leafo\ScssPhp\Compiler;

class DefaultController extends Controller
{
    /**
     * @Route("/", name="homepage")
     */
    public function indexAction(Request $request)
    {
        // Create an instance of the Sass Compiler class
        $scss = new Compiler();

        // Add the expanded formatter to produce a readable format of CSS
        $scss->setFormatter(new \Leafo\ScssPhp\Formatter\Expanded());
        // Other possible formatters:
        //Leafo\ScssPhp\Formatter\Expanded
        //Leafo\ScssPhp\Formatter\Nested (default)
        //Leafo\ScssPhp\Formatter\Compressed
        //Leafo\ScssPhp\Formatter\Compact
        //Leafo\ScssPhp\Formatter\Crunched

        // Path to the folder of the sass files
        $sassFilesPath = $this->get('kernel')->getRootDir() . '/../web/assets/sass/';
    
        // Path to the folder of css files
        $cssFilesPath = $this->get('kernel')->getRootDir() . '/../web/assets/css/';

        // Write output css file
        file_put_contents(
            $cssFilesPath. "all.css",
            // Set the content of all.css the output of the
            // sass compiler from the file all.scss
            $scss->compile(
                // Read content of all.scss
                file_get_contents(
                    $sassFilesPath. "all.scss"
                )
            )
        );

        return new Response("Sass File Succesfully compiled");
    }
}

Which should produce the following CSS instead:

.navigation ul {
  line-height: 20px;
  color: blue;
}
.navigation ul a {
  color: red;
}
.footer .copyright {
  color: silver;
}

D. Catching compiler exceptions

In some cases, its possible that your CSS is invalid so the compiler will throw an exception that you can simply catch:

<?php

namespace AppBundle\Controller;

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\HttpException;

// Use the Sass compiler
use Leafo\ScssPhp\Compiler;

class DefaultController extends Controller
{
    /**
     * @Route("/", name="homepage")
     */
    public function indexAction(Request $request)
    {
        try{
            // Create an instance of the Sass Compiler class
            $scss = new Compiler();
    
            // Sass String
            $sassString = 'div { color: lighten($color, 20%); }';
    
            // Compile the sass string and store the CSS result in another variable
            $css = $scss->compile($sassString);

            // Return a response of CSS Type
            $response = new Response();
            $response->setContent($css);
            $response->setStatusCode(Response::HTTP_OK);
            $response->headers->set('Content-Type', 'text/css');
            return $response;
        }catch(\Exception $e){
            return new Response("SCSS Compiler Error: " . $e->getMessage());
        }
    }
}

For example the previous code would throw the exception: SCSS Compiler Error: Undefined variable $color: line: 1

Happy coding !

This could interest you

Become a more social person