Python Flask Frontend workflow setup
Tags: javascript, python, tailwindcss, flask
Published: 2022-08-09 07:19:00

Hello.! I hope you are doing great. In the last post we setup our application backend structure and in this one we are setting the frontend workflow for our application.

Run the <code>yarn init -y</code> in your root folder structure to setup yarn or npm whatever you like.

```shell
yarn init -y
```

we will get a file <code>package.json</code> something like this

```js
{
  "name": "flask_blog",
  "version": "1.0.0",
  "repository": "git@github.com:MuhammadSaim/flask_tutorial_blog.git",
  "author": "Muhammad Saim",
  "license": "MIT"
}
```

Now install the all Dev dependencies for our project with this command. We will use [Laravel Mix](https://laravel-mix.com/) as our build tool.

```shell 
yarn add autoprefixer laravel-mix postcss tailwindcss -D
```

after running this your <code>package.json</code> will look like this.

```js
{
  "name": "flask_blog",
  "version": "1.0.0",
  "repository": "git@github.com:MuhammadSaim/flask_tutorial_blog.git",
  "author": "Muhammad Saim",
  "license": "MIT",
  "devDependencies": {
    "autoprefixer": "^10.4.8",
    "laravel-mix": "^6.0.49",
    "postcss": "^8.4.16",
    "tailwindcss": "^3.1.8"
  }
}
```

Now install the dependencies of the project which we will need in our project. We will be use Tailwind's UI Kit [Daisy UI](https://daisyui.com/) for our UI.

```shell
yarn add @tailwindcss/typography daisyui jquery
```

after installing these dependencies our <code>package.json</code> will look like this.

```js
{
  "name": "flask_blog",
  "version": "1.0.0",
  "repository": "git@github.com:MuhammadSaim/flask_tutorial_blog.git",
  "author": "Muhammad Saim",
  "license": "MIT",
  "devDependencies": {
    "autoprefixer": "^10.4.8",
    "laravel-mix": "^6.0.49",
    "postcss": "^8.4.16",
    "tailwindcss": "^3.1.8"
  },
  "dependencies": {
    "@tailwindcss/typography": "^0.5.4",
    "daisyui": "^2.22.0",
    "jquery": "^3.6.0"
  }
}
```

Now generate tailwindcss config file for our project.

```shell
npx tailwindcss init
```

this will generate <code>tailwind.confg.js</code> which something looks like this.

```js
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [],
  theme: {
    extend: {},
  },
  plugins: [],
}
```

Now create a <code>src</code> folder in the root directory and make two more folders in the <code>src</code> folder <code>css</code> and <code>js</code> and create <code>app.css</code> file in your <code>css</code> folder and <code>app.js</code> file in your <code>js</code> folder. Your folder structure will look like this.

![Src directory structure](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e61qgcncy3vhgp3wp80d.png)
 
Open <code>src/css/app.css</code> file and place tailwind directives there.

```css
@tailwind base;
@tailwind components;
@tailwind utilities;
```

Open <code>src/js/app.js</code> file and setup the jquery in that file.

```js
window.$ = window.jQuery = require('jquery');
```

Now its time to configure [Daisy UI](https://daisyui.com/) and twailwind's typography helper in our project. Open <code>tailwind.config.js</code> file and add these two enteries in the plugins array.

```js
{
  ...,
  plugins: [
    require('@tailwindcss/typography'),
    require('daisyui')
  ]
}
```

After that <code>tailwind.config.js</code> will looks like this. Also add templates and js files in the contents so tailwindcss will generate those classes which are using in the project and remove those from the build file which project is not using for minimize the css file.

```js
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
      './application/views/**/*.jinja2',
      './application/assets/js/**/*.js',
  ],
  theme: {
    extend: {},
  },
  plugins: [
      require('@tailwindcss/typography'),
      require('daisyui')
  ],
}
```

Now its time to build these assets using our build tool [Laravel Mix](https://laravel-mix.com/). Create <code>webpack.mix.js</code> file in our root diretcory and place all these configurations in that file.

```js
const mix = require('laravel-mix');


mix.options({
  fileLoaderDirs: {
    fonts: "assets/fonts",
    images: "assets/images",
  },
});



mix.js("src/js/app.js", "application/assets/js")
  .postCss("src/css/app.css", "application/assets/css", [
    require("tailwindcss"),
  ]);
```

We need scripts to build our assets for development and production so add those lines in <code>package.json</code> file after adding those lines package.json will look like this.

```js
{
  "name": "flask_blog",
  "version": "1.0.0",
  "repository": "git@github.com:MuhammadSaim/flask_tutorial_blog.git",
  "author": "Muhammad Saim",
  "license": "MIT",
  "scripts": {
    "dev": "npm run development",
    "development": "mix",
    "watch": "mix watch",
    "watch-poll": "mix watch -- --watch-options-poll=1000",
    "hot": "mix watch --hot",
    "prod": "npm run production",
    "production": "mix --production"
  },
  "devDependencies": {
    "autoprefixer": "^10.4.8",
    "laravel-mix": "^6.0.49",
    "postcss": "^8.4.16",
    "tailwindcss": "^3.1.8"
  },
  "dependencies": {
    "@tailwindcss/typography": "^0.5.4",
    "daisyui": "^2.22.0",
    "jquery": "^3.6.0"
  }
}
```

After adding these configurations you can run command to build these assets.

*Development*
```shell
yarn dev
```

*Production*
```shell
yarn prod
```

*Watch server*
```shell
yarn watch
```

these will build your assets into <code>assets</code> diretcory in <code>application/assets</code> you can also ignore this directory in <code>.gitignore</code> file in <code>application</code> directory.

![Build assets](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5nupwl1qpwkuk4ylwquo.png)

Now in <code>views</code> create 3 folders <code>includes</code>, <code>layouts</code> and <code>pages</code> create one file in layouts with the name of <code>app.jinja2</code> and 2nd one in <code>pages</code> directory with the name of <code>home.jinja2</code> the content of these two files are here.

**app.jinja2**
```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="{{ url_for('static', filename='css/app.css') }}">
    <title>{% block title %}{% endblock %}</title>
</head>
<body class="prose">

    {% block content %}{% endblock %}

    <script src="{{ url_for('static', filename='css/app.css') }}"></script>
</body>
</html>
``` 

**home.jinja2**
```html
{% extends 'layouts/app.jinja2' %}


{% block title %} Home {% endblock %}


{% block content %}
    <h1 class="text-3xl">Home</h1>
    <button class="btn btn-primary">Home</button>
{% endblock %}
```

after setting all our templates so we can change a bit in our controller <code>home.py</code>.

```python
from flask import Blueprint, render_template

controller = Blueprint('home', __name__)


@controller.route('/', methods=['GET'])
def index():
    return render_template('pages/home.jinja2')
```

Now run you applictaion

```shell
python run.py
```

Open the url <code>https://127.0.0.1:5000</code>

![Applictaion](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mgv05u0gv5s7brjv8xe2.png)

You can get the updated code on [GitHub Repo](https://github.com/MuhammadSaim/flask_tutorial_blog)
 
Thanks for being with me.

See you guys in next post if you have any issue while going with this post feel free to comment.