Flask-Assets
Published: 2021-12-21 21:54:21

This week, I had a task to implement the SCSS with the Python Flask application. The project uses Jinja as a template engine and Flask for web Framework. This is the first time I have used SCSS, so I would love to take some introductory notes.
## Why SCSS
We all know that CSS is Cascading style language using to style webpage. SCSS stands for `Sassy CSS`, which is CSS pre-processor that give developer ability to use variables, nested syntax, imports, etc. In the pre-processing stage, SCSS files will be converted to CSS to be ready for the browser. 
The biggest advantages of SCSS over CSS is removing code redundant and utilizing code reuse. For example:
CSS Code
```css
.container {
  background-color: white;
  padding: 20px;
}
.container h1{
  color: red;
  text-align: center;
  margin-top: 20px;
}
.container p{
  color: red;
  text-align: center;
  margin-top: 10px;
}
```
SCSS Code
```scss
$color-container: white;
$color-text: red;
.container {
  background-color: white;
  padding: 20px;
  h1 {     // Notice here we don't need to repeat .container class
  color: $color-text;
  text-align: center;
  margin-top: 20px; 
  }
  p {
  color: $color-text;
  text-align: center;
  margin-top: 10px;
  }
}
```
## Install Flask-assets and pyscss
To compile SCSS to CSS, I need [Flask-Assets](https://flask-assets.readthedocs.io/en/latest/) to manage the assets/static files of my Flask application and Pyscss as CSS compiler to convert SCSS markup to real CSS. 

```bash
pip install Flask-Assets
pip install pyscss
```
My application structure:
```bash
Folder    
├───App
│   ├───Config
│   │   └───__pycache__
│   ├───Constants
│   │   └───__pycache__
│   ├───flask_session
│   ├───Models
│   │   └───__pycache__
│   ├───static 
│   │   ├───Gen
│   │   ├───SCSS
│   ├───templates
│   │   ├───example.html
|   ├───__init__.py
├───Setup
│   ├───PIP
│   └───QRIOUS
├───application.py
```
According to the documentation, Environment object is used to hold a collection of bundles and configuration.
A bundle object contains source files, filters _ pyscss in my case, and the output file. It is important to note that all paths in the bundle are relative to my flask application's `static` folder. For example: ` output='Gen/example.css'` , the output CSS file will be in static\Gen folder. 
My code:
```python
from flask import Flask
from flask_assets import Environment, Bundle
app = Flask(__name__)
assets = Environment(app) # create an Environment instance
bundles = {  # define nested Bundle
  'example_style': Bundle(
            'SCSS/example.scss',
            filters='pyscss',
            output='Gen/example.css',
  )
} 
assets.register(bundles) # register name for every bundle in bundles object
```
And lately, I can insert my bundle by using its name in the block `assets` of jinja template. Flask-Assets will help merge and compress my bundle source files the first time when the template is rendered. Moreover, it also watches the change of the source files and will update the compressed file when necessary. 

```html
<head>
	{% assets "example_style" %}
	<link rel="stylesheet" type="text/css" href="{{ ASSET_URL }}">
	{% endassets %}
</head>
```

I found that Flask-assets is easy to use, and it becomes convenient for pre-processing files such as SCSS files or JS files.