Django Tailwind CSS, Alpine.js Tutorial Series:
- Introduction
- How to Setup Tailwind CSS with Django (Part 1)
- How to Setup Tailwind CSS with Django (Part 2)
- Optimize Tailwind CSS in Django
- Render Django Form with Tailwind CSS Style
- Integrate Alpine.js with Django (Part 1) (coming soon)
- Integrate Alpine.js with Django (Part 2) (coming soon)
- Build Task List with Tailwind CSS, Alpine.js and Django (coming soon)
- Django Form Validation in Tailwind Modal (Alpine.js) (coming soon)
- Django Form Validation in Tailwind Modal (Alpine.js + HTMX) (coming soon)
- How to deploy Django Tailwind CSS project with Docker (coming soon)
The source code is on Github/django-tailwind-alpine-htmx
Recommended Posts:
Objectives
By the end of this chapter, you should be able to:
- Use
python-webpack-boilerplate
to jump start frontend project bundled by Webpack - Setup
Tailwind CSS
to the frontend project.
python-webpack-boilerplate
python-webpack-boilerplate can help you Jump start frontend project bundled by Webpack
Create Django project
$ mkdir django_tailwind_project && cd django_tailwind_project
$ python3 -m venv env
$ source env/bin/activate
You can also use other tools such as Poetry or Pipenv
Create requirements.txt
django==3.2
(env)$ pip install -r requirements.txt
(env)$ django-admin.py startproject django_tailwind_app .
You will see structure like this
.
├── django_tailwind_app
├── env
├── manage.py
└── requirements.txt
Now, let's get the project running on local env.
# create db tables
(env)$ python manage.py migrate
(env)$ python manage.py runserver
Check on http://127.0.0.1:8000/
, and you should be able to see the Django welcome page
Import python-webpack-boilerplate
Add python-webpack-boilerplate
to the requirements.txt
django==3.2
python-webpack-boilerplate==0.0.5
(env)$ pip install -r requirements.txt
Update django_tailwind_app/settings.py to add 'webpack_boilerplate' to INSTALLED_APPS
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'webpack_boilerplate', # new
]
Let's run Django command to create frontend project from the python-webpack-boilerplate
$ python manage.py webpack_init
# here we use the default frontend slug
project_slug [frontend]:
Now a new frontend
directory is created which contains pre-defined files for our frontend project.
├── django_tailwind_app
├── env
├── frontend # new
│ ├── README.md
│ ├── package-lock.json
│ ├── package.json
│ ├── postcss.config.js
│ ├── src
│ ├── vendors
│ └── webpack
├── manage.py
└── requirements.txt
Run frontend project
If you have no nodejs installed, please install it first by using below links
- On nodejs homepage
- Using nvm I recommend this way.
$ node -v
v14.18.0
$ npm -v
6.14.15
$ cd frontend
# install dependency packages
$ npm install
# launch webpack dev server
$ npm run start
If the command run without error, that means the setup works, let's terminate the npm run start
by pressing Ctrl + C
Add Tailwind
By default Python Webpack Boilerplate
does not contains Tailwind CSS
, let's add it.
$ cd frontend
# install packages
$ npm install -D tailwindcss@latest postcss-import
You should see something like this in the frontend/package.json
"postcss-import": "^14.0.2",
"tailwindcss": "^3.0.12",
Next, let's edit postcss.config.js
// https://tailwindcss.com/docs/using-with-preprocessors
module.exports = {
plugins: [
require('postcss-import'),
require('tailwindcss/nesting')(require('postcss-nesting')),
require('tailwindcss'),
require('postcss-preset-env')({
features: { 'nesting-rules': false }
}),
]
};
Next, generate a config file for your frontend project using the Tailwind CLI utility included when you install the tailwindcss
npm package
$ cd frontend
$ npx tailwindcss init
Now tailwind.config.js is generated
module.exports = {
content: [],
theme: {
extend: {},
},
plugins: [],
}
We will update this file after a while.
Write Tailwind CSS
Update src/application/app.js
// This is the scss entry file
import "../styles/index.scss";
window.document.addEventListener("DOMContentLoaded", function () {
window.console.log("dom ready 1");
});
Update src/styles/index.scss
@import "tailwindcss/base";
@import "tailwindcss/components";
@import "tailwindcss/utilities";
.jumbotron {
// should be relative path of the entry scss file
background-image: url("../../vendors/images/sample.jpg");
background-size: cover;
}
.btn-blue {
@apply inline-flex items-center px-4 py-2 bg-blue-500 text-white font-semibold rounded-lg shadow-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-400 focus:ring-opacity-75;
}
Let's test again.
$ cd frontend
$ npm run start
Now the tailwindcss can be compiled successfully, let's test in Django template.
Test in Django Template
Add code below to django_tailwind_app/settings.py
import os
STATICFILES_DIRS = [
os.path.join(BASE_DIR, "frontend/build"),
]
WEBPACK_LOADER = {
'MANIFEST_FILE': os.path.join(BASE_DIR, "frontend/build/manifest.json"),
}
- We add the above
frontend/build
toSTATICFILES_DIRS
so Django can find the static assets (img, font and others) - We add
MANIFEST_FILE
location to theWEBPACK_LOADER
so our custom loader can help us load JS and CSS.
Update django_tailwind_app/urls.py
from django.contrib import admin
from django.urls import path
from django.views.generic import TemplateView
urlpatterns = [
path('', TemplateView.as_view(template_name="index.html")), # new
path('admin/', admin.site.urls),
]
Create directory for templates
$ mkdir django_tailwind_app/templates
├── django_tailwind_app
│ ├── __init__.py
│ ├── asgi.py
│ ├── settings.py
│ ├── templates # new
│ ├── urls.py
│ └── wsgi.py
Update TEMPLATES
in django_tailwind_app/settings.py
, so Django can know where to find the templates
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': ['django_tailwind_app/templates'], # new
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
Add index.html
to the above django_tailwind_app/templates
{% load webpack_loader static %}
<!DOCTYPE html>
<html>
<head>
<title>Index</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
{% stylesheet_pack 'app' %}
</head>
<body>
<div class="jumbotron py-5">
<div class="w-full max-w-7xl mx-auto px-4">
<h1 class="text-4xl mb-4">Hello, world!</h1>
<p class="mb-4">This is a template for a simple marketing or informational website. It includes a large callout called a
jumbotron and three supporting pieces of content. Use it as a starting point to create something more unique.</p>
<p><a class="btn-blue mb-4" href="#" role="button">Learn more »</a></p>
<div class="flex justify-center">
<img src="{% static 'vendors/images/webpack.png' %}" class="img-fluid"/>
</div>
</div>
</div>
{% javascript_pack 'app' %}
</body>
</html>
- We
load webpack_loader
at the top of the template, which come frompython-webpack-boilerplate
- We can still use
static
to import image from the frontend project. - We use
stylesheet_pack
andjavascript_pack
to load CSS and JS bundle files to Django
(env)$ python manage.py migrate
(env)$ python manage.py runserver
Now check on http://127.0.0.1:8000/
and you should be able to see a welcome page.
Here we can see:
- The button style is working.
- Some styles in the Django templates such as
w-full max-w-7xl mx-auto px-4
is not working.
JIT
From Tailwind V3, it enabled JIT
(Just-in-Time) all the time.
Tailwind CSS works by scanning all of your HTML, JavaScript components, and any other template files for class names, then generating all of the corresponding CSS for those styles.
In order for Tailwind to generate all of the CSS you need, it needs to know about every single file in your project that contains any Tailwind class names.
So we should config content
section of the tailwind.config.js
, then Tailwind will know which css classes are used.
Let's update frontend/tailwind.config.js
const Path = require("path");
const pwd = process.env.PWD;
// We can add current project paths here
const projectPaths = [
Path.join(pwd, "../django_tailwind_app/templates/**/*.html"),
// add js file paths if you need
];
const contentPaths = [...projectPaths];
console.log(`tailwindcss will scan ${contentPaths}`);
module.exports = {
content: contentPaths,
theme: {
extend: {},
},
plugins: [],
}
Notes:
- Here we add Django templates path to the
projectPaths
- And then we pass the
contentPaths
to thecontent
- The final built css file will contain css classes used in the Django templates
$ cd frontend
$ npm run start
tailwindcss will scan django_tailwind_project/django_tailwind_app/templates/**/*.html
Workflow
- We use python-webpack-boilerplate to jump start frontend project.
- And then, we install
Tailwind CSS
to the frontend project to make it work.
Notes
python-webpack-boilerplate
is easy to extend and customize, and we can benefit from the rich Webpack ecosystem.- It supports
code linting
on the JS and SCSS code. - It supports ES6+ syntax and has great JS bundle solution.
Django Tailwind CSS, Alpine.js Tutorial Series:
- Introduction
- How to Setup Tailwind CSS with Django (Part 1)
- How to Setup Tailwind CSS with Django (Part 2)
- Optimize Tailwind CSS in Django
- Render Django Form with Tailwind CSS Style
- Integrate Alpine.js with Django (Part 1) (coming soon)
- Integrate Alpine.js with Django (Part 2) (coming soon)
- Build Task List with Tailwind CSS, Alpine.js and Django (coming soon)
- Django Form Validation in Tailwind Modal (Alpine.js) (coming soon)
- Django Form Validation in Tailwind Modal (Alpine.js + HTMX) (coming soon)
- How to deploy Django Tailwind CSS project with Docker (coming soon)
The source code is on Github/django-tailwind-alpine-htmx
Recommended Posts: