Skip to content

Commit f476a02

Browse files
committed
Adds JIT; Adds Hot-Reloading
1 parent ea24959 commit f476a02

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+5554
-114
lines changed

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,4 @@ repos:
1616
entry: isort
1717
language: system
1818
types: [python]
19-
exclude: tailwind/app_template_v(1|2)/apps.py
19+
exclude: tailwind/app_template_v2/{{cookiecutter.app_name}}/apps.py

README.md

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# The integration of Tailwind CSS framework with Django a.k.a. Django + Tailwind = ❤
22

3+
## Features
4+
* An opinionated Tailwind setup that makes your life easier;
5+
* Hot reloading of CSS, configuration files and Django templates. No more manual page refreshes!
6+
* Out of the box support for CSS imports, SASS-like variables and nesting;
7+
* Includes official Tailwind plugins like typography, form, line-clamp and aspect-ratio;
8+
39
## Quick start
410

511
1. Install the `django-tailwind` package via Pip:
@@ -14,7 +20,9 @@
1420

1521
3. Create a tailwind-compatible Django-app, I like to call it `theme`:
1622

17-
`python manage.py tailwind init theme`
23+
`python manage.py tailwind init`
24+
25+
> During the initialization step, you'll be prompted to choose between `jit` and `default` modes. Whereas `jit` mode is new and somewhat experimental in Tailwind, I suggest choosing it for the best development experience.
1826
1927
4. Add your newly created `theme` app to INSTALLED_APPS in **settings.py**
2028

@@ -34,14 +42,16 @@
3442
`your_tailwind_app_name/templates/base.html`. You can always extend it or delete it if you
3543
have own layout.
3644

37-
9. If you're not using `base.html` template provided with Django Tailwind, add `styles.css` to your own `base.html` template file:
45+
9. If don't use `base.html` template provided with Django Tailwind, add `{% tailwind_css %}` to your `base.html` template file:
3846

3947
```html
40-
<link
41-
rel="stylesheet"
42-
href="{% static 'css/styles.css' %}"
43-
type="text/css"
44-
/>
48+
{% load tailwind_tags %}
49+
...
50+
<head>
51+
...
52+
{% tailwind_css %}
53+
...
54+
</head>
4555
```
4656

4757
10) You should now be able to use Tailwind CSS classes in your html.
@@ -73,8 +83,11 @@ Note that you may need to adjust those paths to suit your specific project layou
7383

7484
For more information on this, check out the "Controlling File Size" page of the Tailwind docs: [https://tailwindcss.com/docs/controlling-file-size/#removing-unused-css](https://tailwindcss.com/docs/controlling-file-size/#removing-unused-css) - particularly the "Removing Unused CSS" section, although the entire page is a useful reference.
7585

86+
*The following applies to the `default` mode only.*
7687
To help speed up development builds, PurgeCSS is only run when you use the `tailwind build` management command (to create a production build of your CSS).
7788

89+
If you run in `jit` mode, you get an optimized build even in dev mode, and it happens at the lightning speed.
90+
7891
## NPM executable path configuration
7992

8093
Sometimes (especially on Windows), Python executable can't find `NPM` installed in the system.
@@ -128,4 +141,4 @@ If you have found a bug, please use the issue tracker on GitHub.
128141

129142
[https://github.com/timonweb/django-tailwind/issues](https://github.com/timonweb/django-tailwind/issues)
130143

131-
2020 (c) [Tim Kamanin - A Full Stack Django Developer](https://timonweb.com)
144+
2019 - 2021 (c) [Tim Kamanin - A Full Stack Django Developer](https://timonweb.com)

example/example_project/asgi.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
"""
2+
ASGI config for example_project project.
3+
4+
It exposes the ASGI callable as a module-level variable named ``application``.
5+
6+
For more information on this file, see
7+
https://docs.djangoproject.com/en/3.1/howto/deployment/asgi/
8+
"""
9+
10+
import os
11+
12+
from django.core.asgi import get_asgi_application
13+
14+
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "example_project.settings")
15+
16+
application = get_asgi_application()

example/example_project/settings.py

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
"""
2+
Django settings for example_project project.
3+
4+
Generated by 'django-admin startproject' using Django 3.1.3.
5+
6+
For more information on this file, see
7+
https://docs.djangoproject.com/en/3.1/topics/settings/
8+
9+
For the full list of settings and their values, see
10+
https://docs.djangoproject.com/en/3.1/ref/settings/
11+
"""
12+
13+
from pathlib import Path
14+
15+
# Build paths inside the project like this: BASE_DIR / 'subdir'.
16+
BASE_DIR = Path(__file__).resolve().parent.parent
17+
18+
19+
# Quick-start development settings - unsuitable for production
20+
# See https://docs.djangoproject.com/en/3.1/howto/deployment/checklist/
21+
22+
# SECURITY WARNING: keep the secret key used in production secret!
23+
SECRET_KEY = "7c@h1io9=5@8m%fqlyvnx&!x0zm556-g@+dpvu4ab+tsjkm@vm"
24+
25+
# SECURITY WARNING: don't run with debug turned on in production!
26+
DEBUG = True
27+
28+
ALLOWED_HOSTS = []
29+
30+
INTERNAL_IPS = [
31+
"127.0.0.1",
32+
]
33+
34+
35+
# Application definition
36+
37+
INSTALLED_APPS = ["django.contrib.staticfiles", "tailwind", "theme"]
38+
39+
TAILWIND_APP_NAME = "theme"
40+
41+
MIDDLEWARE = [
42+
"django.middleware.security.SecurityMiddleware",
43+
"django.middleware.common.CommonMiddleware",
44+
"django.middleware.csrf.CsrfViewMiddleware",
45+
"django.middleware.clickjacking.XFrameOptionsMiddleware",
46+
]
47+
48+
ROOT_URLCONF = "example_project.urls"
49+
50+
TEMPLATES = [
51+
{
52+
"BACKEND": "django.template.backends.django.DjangoTemplates",
53+
"DIRS": [],
54+
"APP_DIRS": True,
55+
"OPTIONS": {
56+
"context_processors": [
57+
"django.template.context_processors.debug",
58+
"django.template.context_processors.request",
59+
],
60+
},
61+
},
62+
]
63+
64+
WSGI_APPLICATION = "example_project.wsgi.application"
65+
66+
67+
# Database
68+
# https://docs.djangoproject.com/en/3.1/ref/settings/#databases
69+
70+
DATABASES = {}
71+
72+
73+
# Password validation
74+
# https://docs.djangoproject.com/en/3.1/ref/settings/#auth-password-validators
75+
76+
AUTH_PASSWORD_VALIDATORS = [
77+
{
78+
"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator",
79+
},
80+
{
81+
"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator",
82+
},
83+
{
84+
"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator",
85+
},
86+
{
87+
"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator",
88+
},
89+
]
90+
91+
92+
# Internationalization
93+
# https://docs.djangoproject.com/en/3.1/topics/i18n/
94+
95+
LANGUAGE_CODE = "en-us"
96+
97+
TIME_ZONE = "UTC"
98+
99+
USE_I18N = True
100+
101+
USE_L10N = True
102+
103+
USE_TZ = True
104+
105+
106+
# Static files (CSS, JavaScript, Images)
107+
# https://docs.djangoproject.com/en/3.1/howto/static-files/
108+
109+
STATIC_URL = "/static/"

example/example_project/urls.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
"""example_project URL Configuration
2+
3+
The `urlpatterns` list routes URLs to views. For more information please see:
4+
https://docs.djangoproject.com/en/3.1/topics/http/urls/
5+
Examples:
6+
Function views
7+
1. Add an import: from my_app import views
8+
2. Add a URL to urlpatterns: path('', views.home, name='home')
9+
Class-based views
10+
1. Add an import: from other_app.views import Home
11+
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
12+
Including another URLconf
13+
1. Import the include() function: from django.urls import include, path
14+
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
15+
"""
16+
from django.urls import path
17+
from django.views.generic import TemplateView
18+
19+
urlpatterns = [path("", TemplateView.as_view(template_name="base.html"))]

example/example_project/wsgi.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
"""
2+
WSGI config for example_project project.
3+
4+
It exposes the WSGI callable as a module-level variable named ``application``.
5+
6+
For more information on this file, see
7+
https://docs.djangoproject.com/en/3.1/howto/deployment/wsgi/
8+
"""
9+
10+
import os
11+
12+
from django.core.wsgi import get_wsgi_application
13+
14+
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "example_project.settings")
15+
16+
application = get_wsgi_application()

example/manage.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#!/usr/bin/env python
2+
"""Django's command-line utility for administrative tasks."""
3+
import os
4+
import sys
5+
6+
7+
def main():
8+
"""Run administrative tasks."""
9+
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "example_project.settings")
10+
try:
11+
from django.core.management import execute_from_command_line
12+
except ImportError as exc:
13+
raise ImportError(
14+
"Couldn't import Django. Are you sure it's installed and "
15+
"available on your PYTHONPATH environment variable? Did you "
16+
"forget to activate a virtual environment?"
17+
) from exc
18+
execute_from_command_line(sys.argv)
19+
20+
21+
if __name__ == "__main__":
22+
main()
File renamed without changes.

example/theme/apps.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
from django.apps import AppConfig
2+
3+
4+
class ThemeConfig(AppConfig):
5+
name = "theme"

0 commit comments

Comments
 (0)