django-tailwind-cli 4.0.1__tar.gz → 4.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/.pre-commit-config.yaml +8 -3
- {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/CHANGELOG.md +40 -0
- {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/PKG-INFO +11 -3
- {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/README.md +9 -2
- {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/docs/installation.md +0 -9
- django_tailwind_cli-4.2.0/docs/requirements.txt +2 -0
- django_tailwind_cli-4.2.0/docs/settings.md +101 -0
- {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/docs/usage.md +32 -4
- {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/justfile +1 -1
- {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/mkdocs.yml +1 -0
- {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/pyproject.toml +4 -5
- django_tailwind_cli-4.2.0/src/django_tailwind_cli/config.py +174 -0
- {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/src/django_tailwind_cli/management/commands/tailwind.py +18 -53
- {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/src/django_tailwind_cli/templatetags/tailwind_cli.py +2 -4
- {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/tests/test_config.py +95 -75
- {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/tests/test_management_commands.py +15 -31
- {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/tox.ini +1 -1
- {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/uv.lock +156 -280
- django_tailwind_cli-4.0.1/docs/requirements.txt +0 -1
- django_tailwind_cli-4.0.1/docs/settings.md +0 -123
- django_tailwind_cli-4.0.1/src/django_tailwind_cli/config.py +0 -131
- {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/.github/dependabot.yml +0 -0
- {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/.github/workflows/release.yml +0 -0
- {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/.github/workflows/test.yml +0 -0
- {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/.gitignore +0 -0
- {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/.readthedocs.yml +0 -0
- {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/CODE_OF_CONDUCT.md +0 -0
- {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/LICENSE +0 -0
- {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/docs/base_template.md +0 -0
- {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/docs/changelog.md +0 -0
- {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/docs/index.md +0 -0
- {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/docs/template_tags.md +0 -0
- {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/src/django_tailwind_cli/__init__.py +0 -0
- {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/src/django_tailwind_cli/apps.py +0 -0
- {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/src/django_tailwind_cli/management/__init__.py +0 -0
- {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/src/django_tailwind_cli/management/commands/__init__.py +0 -0
- {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/src/django_tailwind_cli/py.typed +0 -0
- {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/src/django_tailwind_cli/templates/tailwind_cli/base.html +0 -0
- {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/src/django_tailwind_cli/templates/tailwind_cli/tailwind_css.html +0 -0
- {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/src/django_tailwind_cli/templatetags/__init__.py +0 -0
- {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/tests/.gitignore +0 -0
- {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/tests/__init__.py +0 -0
- {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/tests/assets/css/.gitkeep +0 -0
- {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/tests/assets/css/tailwind.css +0 -0
- {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/tests/conftest.py +0 -0
- {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/tests/settings.py +0 -0
- {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/tests/templates/tests/base.html +0 -0
- {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/tests/templates/tests/dummy.email +0 -0
- {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/tests/test_get_runserver_options.py +0 -0
- {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/tests/test_tailwind_css_tag.py +0 -0
|
@@ -16,19 +16,19 @@ repos:
|
|
|
16
16
|
- id: check-json
|
|
17
17
|
|
|
18
18
|
- repo: https://github.com/charliermarsh/ruff-pre-commit
|
|
19
|
-
rev: "v0.
|
|
19
|
+
rev: "v0.11.2"
|
|
20
20
|
hooks:
|
|
21
21
|
- id: ruff
|
|
22
22
|
- id: ruff-format
|
|
23
23
|
|
|
24
24
|
- repo: https://github.com/asottile/pyupgrade
|
|
25
|
-
rev: v3.19.
|
|
25
|
+
rev: v3.19.1
|
|
26
26
|
hooks:
|
|
27
27
|
- id: pyupgrade
|
|
28
28
|
args: [--py39-plus]
|
|
29
29
|
|
|
30
30
|
- repo: https://github.com/adamchainz/django-upgrade
|
|
31
|
-
rev: "1.
|
|
31
|
+
rev: "1.23.1"
|
|
32
32
|
hooks:
|
|
33
33
|
- id: django-upgrade
|
|
34
34
|
args: [--target-version, "4.2"]
|
|
@@ -38,3 +38,8 @@ repos:
|
|
|
38
38
|
hooks:
|
|
39
39
|
- id: djade
|
|
40
40
|
args: [--target-version, "4.2"]
|
|
41
|
+
|
|
42
|
+
- repo: https://github.com/owenlamont/uv-secure
|
|
43
|
+
rev: 0.9.0
|
|
44
|
+
hooks:
|
|
45
|
+
- id: uv-secure
|
|
@@ -1,5 +1,45 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 4.2.0 (Unreleased)
|
|
4
|
+
|
|
5
|
+
> [!CAUTION]
|
|
6
|
+
> Version 4.2.x and onward only support Tailwind CSS 4.x. If you are using Tailwind CSS 3.x,
|
|
7
|
+
> please use version 2.21.1 of this library. Version 4.0.x or 4.1.x still support Tailwind CSS 3.x, but
|
|
8
|
+
> these versions are not recommended to use for new projects.
|
|
9
|
+
|
|
10
|
+
> [!CAUTION]
|
|
11
|
+
> This version includes changes to the handling of `TAILWIND_CLI_PATH` and `TAILWIND_CLI_SRC_CSS`.
|
|
12
|
+
|
|
13
|
+
- Default fallback version is now 4.1.3.
|
|
14
|
+
- Removed support for Tailwind CSS 3.x. The main reason is that this makes the library easier to maintain and also add better support for custom CLI builds which support DaisyUI and other plugins.
|
|
15
|
+
- django-tailwind-cli now uses proper platform directories to store the CLI binary.
|
|
16
|
+
|
|
17
|
+
* The proper directories are powered by [platformdirs](https://pypi.org/project/platformdirs/).
|
|
18
|
+
* `TAILWIND_CLI_PATH` is now optional by default.
|
|
19
|
+
* If `TAILWIND_CLI_PATH` is None, the binary is stored in `user_data_dir("django-tailwind-cli", "django-commons")`.
|
|
20
|
+
* The library doesn't rely anylonger on a properly set `settings.BASE_DIR`.
|
|
21
|
+
|
|
22
|
+
- `TAILWIND_CLI_ASSET_NAME` is also used for the downloaded CLI to distinguish between `tailwindcss` and `tailwindcss-extra`.
|
|
23
|
+
- The behaviour of `TAILWIND_CLI_SRC_CSS` has been changed. The reasoning behind this change was, less default code inside the project and whitenoise had issues with a CSS file inside an asset folder referencing non-existing imports.
|
|
24
|
+
|
|
25
|
+
* It defaults to `None`.
|
|
26
|
+
* If it is `None` the default input file is created in the user cache directory.
|
|
27
|
+
* If it is a relative path, this path is considered relative to `settings.BASE_DIR`.
|
|
28
|
+
* The last option is an absolute path.
|
|
29
|
+
|
|
30
|
+
- Proper daisyUI support using [tailwind-cli-extra](https://github.com/dobicinaitis/tailwind-cli-extra).
|
|
31
|
+
|
|
32
|
+
## 4.1.0
|
|
33
|
+
|
|
34
|
+
- TAILWIND_CLI_VERSION defaults to "latest" now. In case it is set to this value,
|
|
35
|
+
django-tailwind-cli tries to determine which version is the latest version of Tailwind CSS. If it is not able to access the internet, it uses a fallback version defined in django_tailwind_cli.config.FALLBACK_VERSION. Currently,
|
|
36
|
+
it is set to 4.0.6.
|
|
37
|
+
|
|
38
|
+
## 4.0.1
|
|
39
|
+
|
|
40
|
+
- Various fixes for the documentation.
|
|
41
|
+
- Added Django 5.2 to the testing matrix.
|
|
42
|
+
|
|
3
43
|
## 4.0.0
|
|
4
44
|
|
|
5
45
|
- Added support for Tailwind CSS 4.0.0.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: django-tailwind-cli
|
|
3
|
-
Version: 4.0
|
|
3
|
+
Version: 4.2.0
|
|
4
4
|
Summary: Django and Tailwind integration based on the prebuilt Tailwind CSS CLI.
|
|
5
5
|
Project-URL: Home, https://django-tailwind-cli.rtfd.io/
|
|
6
6
|
Project-URL: Documentation, https://django-tailwind-cli.rtfd.io/
|
|
@@ -47,6 +47,7 @@ Classifier: Topic :: Utilities
|
|
|
47
47
|
Requires-Python: >=3.9
|
|
48
48
|
Requires-Dist: django-typer>=2.1.2
|
|
49
49
|
Requires-Dist: django>=4.0
|
|
50
|
+
Requires-Dist: platformdirs>=4.3.7
|
|
50
51
|
Requires-Dist: requests>=2.32.3
|
|
51
52
|
Requires-Dist: semver>=3.0.4
|
|
52
53
|
Provides-Extra: django-extensions
|
|
@@ -66,6 +67,11 @@ Description-Content-Type: text/markdown
|
|
|
66
67
|
[](https://pepy.tech/project/django-tailwind-cli)
|
|
67
68
|
[](<https://pepy.tech/project/django-tailwind-cli>)
|
|
68
69
|
|
|
70
|
+
> [!WARNING]
|
|
71
|
+
> Version 4.2.x and onward only support Tailwind CSS 4.x. If you are using Tailwind CSS 3.x,
|
|
72
|
+
> please use version 2.21.1 of this library. Version 4.0.x or 4.1.x still support Tailwind CSS 3.x, but
|
|
73
|
+
> these versions are not recommended to use for new projects.
|
|
74
|
+
|
|
69
75
|
This library provides an integration of [Tailwind CSS](https://tailwindcss.com) for Django that is using on the precompiled versions of the [Tailwind CSS CLI](https://tailwindcss.com/blog/standalone-cli).
|
|
70
76
|
|
|
71
77
|
The goal of this library is to provided the simplest possible Tailwind integration for your Django project. It took its inspiration from the [Tailwind integration for Phoenix](https://github.com/phoenixframework/tailwind) which completely skips the neccesity of a node installation.
|
|
@@ -120,7 +126,9 @@ if you want to activate browser reload or the `runserver_plus` management comman
|
|
|
120
126
|
## Features
|
|
121
127
|
|
|
122
128
|
- Simplest possible integration.
|
|
123
|
-
- Support Tailwind CSS
|
|
129
|
+
- Support Tailwind CSS 4.x.
|
|
130
|
+
- Proper support for DaisyUI via [tailwindcss-cli-extra](https://github.com/dobicinaitis/tailwind-cli-extra). Settings are described in the [usage guide](https://django-tailwind-cli.readthedocs.io/latest/usage/#use-with-daisyui).
|
|
131
|
+
- Or bring your own version of Tailwind CSS CLI.
|
|
124
132
|
- Management commands:
|
|
125
133
|
|
|
126
134
|
* To start the Tailwind CLI in watch mode during development.
|
|
@@ -130,7 +138,7 @@ if you want to activate browser reload or the `runserver_plus` management comman
|
|
|
130
138
|
- Configuration options to adapt the library to your project, when the defaults don't fit you.
|
|
131
139
|
- A template tag to include the Tailwind CSS file in your project.
|
|
132
140
|
- A base template for your project.
|
|
133
|
-
- Sane default configurations for
|
|
141
|
+
- Sane default configurations for Tailwinc 4.x.
|
|
134
142
|
|
|
135
143
|
## Requirements
|
|
136
144
|
|
|
@@ -10,6 +10,11 @@
|
|
|
10
10
|
[](https://pepy.tech/project/django-tailwind-cli)
|
|
11
11
|
[](<https://pepy.tech/project/django-tailwind-cli>)
|
|
12
12
|
|
|
13
|
+
> [!WARNING]
|
|
14
|
+
> Version 4.2.x and onward only support Tailwind CSS 4.x. If you are using Tailwind CSS 3.x,
|
|
15
|
+
> please use version 2.21.1 of this library. Version 4.0.x or 4.1.x still support Tailwind CSS 3.x, but
|
|
16
|
+
> these versions are not recommended to use for new projects.
|
|
17
|
+
|
|
13
18
|
This library provides an integration of [Tailwind CSS](https://tailwindcss.com) for Django that is using on the precompiled versions of the [Tailwind CSS CLI](https://tailwindcss.com/blog/standalone-cli).
|
|
14
19
|
|
|
15
20
|
The goal of this library is to provided the simplest possible Tailwind integration for your Django project. It took its inspiration from the [Tailwind integration for Phoenix](https://github.com/phoenixframework/tailwind) which completely skips the neccesity of a node installation.
|
|
@@ -64,7 +69,9 @@ if you want to activate browser reload or the `runserver_plus` management comman
|
|
|
64
69
|
## Features
|
|
65
70
|
|
|
66
71
|
- Simplest possible integration.
|
|
67
|
-
- Support Tailwind CSS
|
|
72
|
+
- Support Tailwind CSS 4.x.
|
|
73
|
+
- Proper support for DaisyUI via [tailwindcss-cli-extra](https://github.com/dobicinaitis/tailwind-cli-extra). Settings are described in the [usage guide](https://django-tailwind-cli.readthedocs.io/latest/usage/#use-with-daisyui).
|
|
74
|
+
- Or bring your own version of Tailwind CSS CLI.
|
|
68
75
|
- Management commands:
|
|
69
76
|
|
|
70
77
|
* To start the Tailwind CLI in watch mode during development.
|
|
@@ -74,7 +81,7 @@ if you want to activate browser reload or the `runserver_plus` management comman
|
|
|
74
81
|
- Configuration options to adapt the library to your project, when the defaults don't fit you.
|
|
75
82
|
- A template tag to include the Tailwind CSS file in your project.
|
|
76
83
|
- A base template for your project.
|
|
77
|
-
- Sane default configurations for
|
|
84
|
+
- Sane default configurations for Tailwinc 4.x.
|
|
78
85
|
|
|
79
86
|
## Requirements
|
|
80
87
|
|
|
@@ -120,12 +120,3 @@ If you enjoy automatic reloading during development. Install the [django-browser
|
|
|
120
120
|
The middleware should be listed after any that encodes the response, such as Django’s GZipMiddleware.
|
|
121
121
|
|
|
122
122
|
The middleware automatically inserts the required script tag on HTML responses before </body> when DEBUG is True. It does so to every HTML response, meaning it will be included on Django’s debug pages, admin pages, etc. If you want more control, you can instead insert the script tag in your templates—see below.
|
|
123
|
-
|
|
124
|
-
## Upgrade from Tailwind CSS 3.x to 4.x
|
|
125
|
-
|
|
126
|
-
In order to upgrade this package from using Tailwind CSS 3.x to 4.x, you have to follow some simple
|
|
127
|
-
steps.
|
|
128
|
-
|
|
129
|
-
- Remove or change the setting `TAILWIND_CLI_VERSION` if it is set.
|
|
130
|
-
- Remove the setting `TAILWIND_CLI_CONFIG_FILE` if it is set.
|
|
131
|
-
- Remove the `tailwind.config.js` from your project.
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
---
|
|
2
|
+
hide:
|
|
3
|
+
- navigation
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Settings & Configuration
|
|
7
|
+
|
|
8
|
+
## Settings
|
|
9
|
+
|
|
10
|
+
The package can be configured by a few settings, which can be overwritten in the `settings.py` of
|
|
11
|
+
your project.
|
|
12
|
+
|
|
13
|
+
`TAILWIND_CLI_VERSION`
|
|
14
|
+
: **Default**: `"latest"`
|
|
15
|
+
|
|
16
|
+
This defines the version of the CLI and of Tailwind CSS you want to use in your project.
|
|
17
|
+
|
|
18
|
+
If it is set to `latest`, the management commands try to determine the most recent version of Tailwind CSS by placing a request to GitHub and parse the location header of the redirect. If this is not possible a fallback version is used. This version is defined in the module `django_tailwind_cli.config`.
|
|
19
|
+
|
|
20
|
+
If you want to pinpoint your setup to certain version of Tailwind CSS, then you can set `TAILWIND_CLI_VERSION`to a fixed version number.
|
|
21
|
+
|
|
22
|
+
For example:
|
|
23
|
+
```python
|
|
24
|
+
TAILWIND_CLI_VERSION = "4.1.0"
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
`TAILWIND_CLI_PATH`
|
|
28
|
+
: **Default**: `None`
|
|
29
|
+
|
|
30
|
+
This allows you to override the default of the library where to store the CLI binary.
|
|
31
|
+
|
|
32
|
+
The default behaviour is to store the CLI binary in the directory returned by this call `platformdirs.user_data_dir("django-tailwind-cli", "django-commons")`. Checkout [platformdirs](https://pypi.org/project/platformdirs/) for details.
|
|
33
|
+
|
|
34
|
+
But if you want to store it elsewhere or plan to use a custom build binary stored locally, change this setting either to a path to a directory or the full path to the binary. If it points to a directory, this is the download destination otherwise it directly tries to use the referenced binary.
|
|
35
|
+
|
|
36
|
+
> [!Warning]
|
|
37
|
+
> If you use the new option from **2.7.0** but haven't installed a binary before running any of the management commands, these commands will treat the configured path as a directory and create it, if it is missing. Afterwards the official CLI will be downloaded to this path.
|
|
38
|
+
>
|
|
39
|
+
> In case you want to use the new behaviour, it is highly recommended to also set the new setting `TAILWIND_CLI_AUTOMATIC_DOWNLOAD` to `False`.
|
|
40
|
+
|
|
41
|
+
`TAILWIND_CLI_AUTOMATIC_DOWNLOAD`
|
|
42
|
+
: **Default**: `True`
|
|
43
|
+
|
|
44
|
+
Enable or disable the automatic downloading of the official CLI to your machine.
|
|
45
|
+
|
|
46
|
+
`TAILWIND_CLI_SRC_REPO`
|
|
47
|
+
: **Default**: `"tailwindlabs/tailwindcss"`
|
|
48
|
+
|
|
49
|
+
Specifies the repository from which the CLI is downloaded. This is useful if you are using a customized version of the CLI, such as [tailwind-cli-extra](https://github.com/dobicinaitis/tailwind-cli-extra).
|
|
50
|
+
|
|
51
|
+
> [!Warning]
|
|
52
|
+
> If you use this option, ensure that you update the `TAILWIND_CLI_VERSION` to match the version of the customized CLI you are using. Additionally, you may need to update the `TAILWIND_CLI_ASSET_NAME` if the asset name is different. See the example below.
|
|
53
|
+
|
|
54
|
+
`TAILWIND_CLI_ASSET_NAME`:
|
|
55
|
+
: **Default**: `"tailwindcss"`
|
|
56
|
+
|
|
57
|
+
Specifies the name of the asset to download from the repository.
|
|
58
|
+
|
|
59
|
+
This option is particularly useful if the customized repository you are using has a different name for the Tailwind CLI asset. For example, the asset name for [tailwind-cli-extra](https://github.com/dobicinaitis/tailwind-cli-extra/releases/latest/) is `tailwindcss-extra`.
|
|
60
|
+
|
|
61
|
+
> [!Note]
|
|
62
|
+
> Here is a full example of using a custom repository and asset name:
|
|
63
|
+
> ```python
|
|
64
|
+
> TAILWIND_CLI_SRC_REPO = "dobicinaitis/tailwind-cli-extra"
|
|
65
|
+
> TAILWIND_CLI_ASSET_NAME = "tailwindcss-extra"
|
|
66
|
+
> ```
|
|
67
|
+
|
|
68
|
+
`TAILWIND_CLI_SRC_CSS`
|
|
69
|
+
**Default**: `None`
|
|
70
|
+
|
|
71
|
+
This variable can be set to `None`, a relative path and an absolute path.
|
|
72
|
+
|
|
73
|
+
If it is set to `None`, the library creates file with the name `source.css` in the directory returned by this call `platformdirs.user_cache_dir("django-tailwind-cli", "django-commons")`. Checkout [platformdirs](https://pypi.org/project/platformdirs/) for details.
|
|
74
|
+
|
|
75
|
+
If it is a relative path it is assumed to be relative to `settings.BASE_DIR`. If `settings.BASE_DIR` is not defined or the file doesn't exist a `ValueError` is raised.
|
|
76
|
+
|
|
77
|
+
If it is an absolute path, this path is used as the input file for Tailwind CSS CLI. If the path doesn't exist, a `ValueError`is raised.
|
|
78
|
+
|
|
79
|
+
`TAILWIND_CLI_DIST_CSS`
|
|
80
|
+
: **Default**: `"css/tailwind.css"`
|
|
81
|
+
|
|
82
|
+
The name of the output file. This file is stored relative to the first element of the
|
|
83
|
+
`STATICFILES_DIRS` array.
|
|
84
|
+
|
|
85
|
+
`TAILWIND_CLI_USE_DAISY_UI`:
|
|
86
|
+
: **Default**: `False`
|
|
87
|
+
|
|
88
|
+
This switch determines what content is written to `TAILWIND_CLI_SRC_CSS` if it is automatically created by the library.
|
|
89
|
+
|
|
90
|
+
The default is:
|
|
91
|
+
```css
|
|
92
|
+
@import "tailwindcss";
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
If `TAILWIND_CLI_USE_DAISY_UI = True` is put into the `settings.py` of your project, this is the output:
|
|
96
|
+
```css
|
|
97
|
+
@import "tailwindcss";
|
|
98
|
+
@plugin "daisyui";
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
This switch can also be used as a shortcut to activate daisyUI and change `TAILWIND_CLI_SRC_REPO` and `TAILWIND_CLI_ASSET_NAME` as described above to fetch [tailwind-cli-extra](https://github.com/dobicinaitis/tailwind-cli-extra/releases/latest/).
|
|
@@ -9,10 +9,6 @@ hide:
|
|
|
9
9
|
|
|
10
10
|
**No.** The management commands of this library handle the download and installation of the Tailwind CLI. You don't have to deal with this. But you can configure the installation location and the version of the CLI you want to use. Take a look at the [settings](settings.md) section.
|
|
11
11
|
|
|
12
|
-
!!! question "Do I have to create my own `tailwind.config.js` for Tailwind 3.x?"
|
|
13
|
-
|
|
14
|
-
**No.** The management commands also take care of this step. If no `tailwind.config.js` is present in your project, a new one with sane defaults will be created. Afterwards this file will be used and be customized by you. The default location for the file is the `BASE_DIR` of your project, but you can change this. Take a look at the [settings](settings.md) section.
|
|
15
|
-
|
|
16
12
|
!!! question "Do I have to create my own `css/source.css` for Tailwind 4.x?"
|
|
17
13
|
|
|
18
14
|
**No.** The management commands also take care of this step. If no `css/source.css` is present in your project, a new one with sane defaults will be created. Afterwards this file will be used and be customized by you. The default location for the file is first folder from the `STATICFILES_DIRS` of your project, but you can change this. Take a look at the [settings](settings.md) section.
|
|
@@ -106,3 +102,35 @@ tailwind-sidecar:
|
|
|
106
102
|
command: python manage.py tailwind watch
|
|
107
103
|
tty: true
|
|
108
104
|
```
|
|
105
|
+
|
|
106
|
+
## Use with daisyUI
|
|
107
|
+
|
|
108
|
+
If you plan to use [daisyUI](https://daisyui.com), there is an easy way to solve this with this library.
|
|
109
|
+
|
|
110
|
+
```python
|
|
111
|
+
TAILWIND_CLI_USE_DAISY_UI = True
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Setting this, the library switches from using the default TailwindCSS CLI to the one provided by [Andris Dobičinaitis](https://github.com/dobicinaitis) and his [tailwind-cli-extra](https://github.com/dobicinaitis/tailwind-cli-extra) project. It also causes the library to create a proper default config that activates the daisyUI plugin.
|
|
115
|
+
|
|
116
|
+
But of course you can do it manually, too. Just configure a repository where the library should pull the CLI from and activate the daisyUI support.
|
|
117
|
+
|
|
118
|
+
```python
|
|
119
|
+
TAILWIND_CLI_SRC_REPO = "dobicinaitis/tailwind-cli-extra"
|
|
120
|
+
TAILWIND_CLI_ASSET_NAME = "tailwindcss-extra"
|
|
121
|
+
TAILWIND_CLI_USE_DAISY_UI = True
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Or provide your custom configuration, too.
|
|
125
|
+
|
|
126
|
+
```python
|
|
127
|
+
TAILWIND_CLI_SRC_REPO = "dobicinaitis/tailwind-cli-extra"
|
|
128
|
+
TAILWIND_CLI_ASSET_NAME = "tailwindcss-extra"
|
|
129
|
+
TAILWIND_CLI_SRC_CSS = "etc/source.css"
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
## Use with WhiteNoise
|
|
133
|
+
|
|
134
|
+
If you are using [WhiteNoise](https://whitenoise.readthedocs.io/en/latest/) to serve your static assets, you must not put your custom Tailwind configuration file inside any of the directories for static files. WhiteNoise stumbles across the `@import "tailwindcss";` statement, because it can't resolve it.
|
|
135
|
+
|
|
136
|
+
If you want to use a custom configuration for Tailwind CSS, put it somewhere else in the project.
|
|
@@ -30,6 +30,7 @@ requires-python = ">=3.9"
|
|
|
30
30
|
dependencies = [
|
|
31
31
|
"django>=4.0",
|
|
32
32
|
"django-typer>=2.1.2",
|
|
33
|
+
"platformdirs>=4.3.7",
|
|
33
34
|
"requests>=2.32.3",
|
|
34
35
|
"semver>=3.0.4",
|
|
35
36
|
]
|
|
@@ -50,8 +51,6 @@ dev = [
|
|
|
50
51
|
"pytest-randomly>=3.15.0",
|
|
51
52
|
"pytest>=8.3.3",
|
|
52
53
|
"django-stubs[compatible-mypy]>=5.1.1",
|
|
53
|
-
"tox>=4.23.2",
|
|
54
|
-
"tox-uv>=1.16.0",
|
|
55
54
|
]
|
|
56
55
|
|
|
57
56
|
[build-system]
|
|
@@ -79,7 +78,7 @@ strict_settings = false
|
|
|
79
78
|
|
|
80
79
|
# Ruff
|
|
81
80
|
[tool.ruff]
|
|
82
|
-
target-version = "
|
|
81
|
+
target-version = "py39"
|
|
83
82
|
line-length = 120
|
|
84
83
|
|
|
85
84
|
[tool.ruff.format]
|
|
@@ -117,13 +116,13 @@ unfixable = [
|
|
|
117
116
|
]
|
|
118
117
|
|
|
119
118
|
[tool.ruff.lint.isort]
|
|
120
|
-
known-first-party = ["
|
|
119
|
+
known-first-party = ["django_tailwind_cli"]
|
|
121
120
|
|
|
122
121
|
[tool.ruff.lint.flake8-tidy-imports]
|
|
123
122
|
ban-relative-imports = "all"
|
|
124
123
|
|
|
125
124
|
[tool.ruff.lint.per-file-ignores]
|
|
126
|
-
"tests/**/*" = ["PLR2004", "S101", "TID252", "ARG001"]
|
|
125
|
+
"tests/**/*" = ["PLR2004", "S101", "TID252", "ARG001", "FBT001"]
|
|
127
126
|
"tests/snapshots/*" = ["ALL"]
|
|
128
127
|
"**/migrations/*" = ["ALL"]
|
|
129
128
|
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import platform
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
from typing import Optional
|
|
6
|
+
|
|
7
|
+
import platformdirs
|
|
8
|
+
import requests
|
|
9
|
+
from django.conf import settings
|
|
10
|
+
from semver import Version
|
|
11
|
+
|
|
12
|
+
FALLBACK_VERSION = "4.1.3"
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@dataclass
|
|
16
|
+
class Config:
|
|
17
|
+
version_str: str
|
|
18
|
+
version: Version
|
|
19
|
+
cli_path: Path
|
|
20
|
+
download_url: str
|
|
21
|
+
dist_css: Path
|
|
22
|
+
dist_css_base: str
|
|
23
|
+
src_css: Optional[Path]
|
|
24
|
+
automatic_download: bool = True
|
|
25
|
+
use_daisy_ui: bool = False
|
|
26
|
+
|
|
27
|
+
@property
|
|
28
|
+
def watch_cmd(self) -> list[str]:
|
|
29
|
+
result = [
|
|
30
|
+
str(self.cli_path),
|
|
31
|
+
"--input",
|
|
32
|
+
str(self.src_css),
|
|
33
|
+
"--output",
|
|
34
|
+
str(self.dist_css),
|
|
35
|
+
"--watch",
|
|
36
|
+
]
|
|
37
|
+
|
|
38
|
+
return result
|
|
39
|
+
|
|
40
|
+
@property
|
|
41
|
+
def build_cmd(self) -> list[str]:
|
|
42
|
+
result = [
|
|
43
|
+
str(self.cli_path),
|
|
44
|
+
"--input",
|
|
45
|
+
str(self.src_css),
|
|
46
|
+
"--output",
|
|
47
|
+
str(self.dist_css),
|
|
48
|
+
"--minify",
|
|
49
|
+
]
|
|
50
|
+
|
|
51
|
+
return result
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def get_version() -> tuple[str, Version]:
|
|
55
|
+
"""
|
|
56
|
+
Retrieves the version of Tailwind CSS specified in the Django settings or fetches the latest
|
|
57
|
+
version from the Tailwind CSS GitHub repository.
|
|
58
|
+
|
|
59
|
+
Returns:
|
|
60
|
+
tuple[str, Version]: A tuple containing the version string and the parsed Version object.
|
|
61
|
+
|
|
62
|
+
Raises:
|
|
63
|
+
ValueError: If the TAILWIND_CLI_SRC_REPO setting is None when the version is set to
|
|
64
|
+
"latest".
|
|
65
|
+
"""
|
|
66
|
+
use_daisy_ui = getattr(settings, "TAILWIND_CLI_USE_DAISY_UI", False)
|
|
67
|
+
version_str = getattr(settings, "TAILWIND_CLI_VERSION", "latest")
|
|
68
|
+
repo_url = getattr(
|
|
69
|
+
settings,
|
|
70
|
+
"TAILWIND_CLI_SRC_REPO",
|
|
71
|
+
"tailwindlabs/tailwindcss" if not use_daisy_ui else "dobicinaitis/tailwind-cli-extra",
|
|
72
|
+
)
|
|
73
|
+
if not repo_url:
|
|
74
|
+
raise ValueError("TAILWIND_CLI_SRC_REPO must not be None.")
|
|
75
|
+
|
|
76
|
+
if version_str == "latest":
|
|
77
|
+
r = requests.get(f"https://github.com/{repo_url}/releases/latest/", timeout=2)
|
|
78
|
+
if r.ok and "location" in r.headers:
|
|
79
|
+
version_str = r.headers["location"].rstrip("/").split("/")[-1].replace("v", "")
|
|
80
|
+
return version_str, Version.parse(version_str)
|
|
81
|
+
else:
|
|
82
|
+
return FALLBACK_VERSION, Version.parse(FALLBACK_VERSION)
|
|
83
|
+
elif repo_url == "tailwindlabs/tailwindcss":
|
|
84
|
+
version = Version.parse(version_str)
|
|
85
|
+
if version.major < 4:
|
|
86
|
+
raise ValueError(
|
|
87
|
+
"Tailwind CSS 3.x is not supported by this version. Use version 2.21.1 if you want to use Tailwind 3."
|
|
88
|
+
)
|
|
89
|
+
return version_str, version
|
|
90
|
+
else:
|
|
91
|
+
return version_str, Version.parse(version_str)
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def get_config() -> Config:
|
|
95
|
+
if settings.STATICFILES_DIRS is None or len(settings.STATICFILES_DIRS) == 0:
|
|
96
|
+
raise ValueError("STATICFILES_DIRS is empty. Please add a path to your static files.")
|
|
97
|
+
|
|
98
|
+
# daisyUI support
|
|
99
|
+
use_daisy_ui = getattr(settings, "TAILWIND_CLI_USE_DAISY_UI", False)
|
|
100
|
+
|
|
101
|
+
# Determine the system and machine we are running on
|
|
102
|
+
system = platform.system().lower()
|
|
103
|
+
system = "macos" if system == "darwin" else system
|
|
104
|
+
|
|
105
|
+
machine = platform.machine().lower()
|
|
106
|
+
if machine in ["x86_64", "amd64"]:
|
|
107
|
+
machine = "x64"
|
|
108
|
+
elif machine == "aarch64":
|
|
109
|
+
machine = "arm64"
|
|
110
|
+
|
|
111
|
+
# Yeah, windows has this exe thingy..
|
|
112
|
+
extension = ".exe" if system == "windows" else ""
|
|
113
|
+
|
|
114
|
+
# Read version from settings
|
|
115
|
+
version_str, version = get_version()
|
|
116
|
+
|
|
117
|
+
# Determine the asset name
|
|
118
|
+
if not (
|
|
119
|
+
asset_name := getattr(
|
|
120
|
+
settings, "TAILWIND_CLI_ASSET_NAME", "tailwindcss" if not use_daisy_ui else "tailwindcss-extra"
|
|
121
|
+
)
|
|
122
|
+
):
|
|
123
|
+
raise ValueError("TAILWIND_CLI_ASSET_NAME must not be None.")
|
|
124
|
+
|
|
125
|
+
# Determine the full path to the CLI
|
|
126
|
+
cli_path = Path(
|
|
127
|
+
getattr(settings, "TAILWIND_CLI_PATH", None)
|
|
128
|
+
or platformdirs.user_data_dir("django-tailwind-cli", "django-commons")
|
|
129
|
+
)
|
|
130
|
+
if cli_path.exists() and cli_path.is_file() and os.access(cli_path, os.X_OK):
|
|
131
|
+
cli_path = cli_path.expanduser().resolve()
|
|
132
|
+
else:
|
|
133
|
+
cli_path = cli_path.expanduser() / f"{asset_name}-{system}-{machine}-{version_str}{extension}"
|
|
134
|
+
|
|
135
|
+
# Determine the download url for the cli
|
|
136
|
+
repo_url = getattr(
|
|
137
|
+
settings,
|
|
138
|
+
"TAILWIND_CLI_SRC_REPO",
|
|
139
|
+
"tailwindlabs/tailwindcss" if not use_daisy_ui else "dobicinaitis/tailwind-cli-extra",
|
|
140
|
+
)
|
|
141
|
+
download_url = (
|
|
142
|
+
f"https://github.com/{repo_url}/releases/download/v{version_str}/{asset_name}-{system}-{machine}{extension}"
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
# Determine the full path to the dist css file
|
|
146
|
+
if not (dist_css_base := getattr(settings, "TAILWIND_CLI_DIST_CSS", "css/tailwind.css")):
|
|
147
|
+
raise ValueError("TAILWIND_CLI_DIST_CSS must not be None.")
|
|
148
|
+
dist_css = Path(settings.STATICFILES_DIRS[0]) / dist_css_base
|
|
149
|
+
|
|
150
|
+
# Determine the full path to the source css file.
|
|
151
|
+
src_css = getattr(settings, "TAILWIND_CLI_SRC_CSS", None)
|
|
152
|
+
if not src_css:
|
|
153
|
+
user_cache_dir = platformdirs.user_cache_dir("django-tailwind-cli", "django-commons")
|
|
154
|
+
src_css = Path(user_cache_dir) / "source.css"
|
|
155
|
+
else:
|
|
156
|
+
src_css = Path(src_css)
|
|
157
|
+
if not src_css.is_absolute():
|
|
158
|
+
src_css = Path(settings.BASE_DIR) / src_css
|
|
159
|
+
|
|
160
|
+
# Determine if the CLI should be downloaded automatically
|
|
161
|
+
automatic_download = getattr(settings, "TAILWIND_CLI_AUTOMATIC_DOWNLOAD", True)
|
|
162
|
+
|
|
163
|
+
# return configuration
|
|
164
|
+
return Config(
|
|
165
|
+
version_str=version_str,
|
|
166
|
+
version=version,
|
|
167
|
+
cli_path=cli_path,
|
|
168
|
+
download_url=download_url,
|
|
169
|
+
dist_css=dist_css,
|
|
170
|
+
dist_css_base=dist_css_base,
|
|
171
|
+
src_css=src_css,
|
|
172
|
+
automatic_download=automatic_download,
|
|
173
|
+
use_daisy_ui=use_daisy_ui,
|
|
174
|
+
)
|
|
@@ -23,24 +23,19 @@ app = Typer(name="tailwind", help="Create and manage a Tailwind CSS theme.") #
|
|
|
23
23
|
@app.command()
|
|
24
24
|
def build() -> None:
|
|
25
25
|
"""Build a minified production ready CSS file."""
|
|
26
|
-
|
|
26
|
+
config = get_config()
|
|
27
27
|
_download_cli()
|
|
28
28
|
_create_standard_config()
|
|
29
29
|
|
|
30
30
|
try:
|
|
31
|
-
subprocess.run(
|
|
31
|
+
subprocess.run(config.build_cmd, cwd=settings.BASE_DIR, check=True, capture_output=True, text=True)
|
|
32
|
+
typer.secho(f"Built production stylesheet '{config.dist_css}'.", fg=typer.colors.GREEN)
|
|
32
33
|
except KeyboardInterrupt:
|
|
33
34
|
typer.secho("Canceled building production stylesheet.", fg=typer.colors.RED)
|
|
34
35
|
except subprocess.CalledProcessError as e: # pragma: no cover
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
)
|
|
39
|
-
else:
|
|
40
|
-
typer.secho(
|
|
41
|
-
f"Built production stylesheet '{c.dist_css}'.",
|
|
42
|
-
fg=typer.colors.GREEN,
|
|
43
|
-
)
|
|
36
|
+
error_message = e.stderr if e.stderr else "An unknown error occurred."
|
|
37
|
+
typer.secho(f"Failed to build production stylesheet: {error_message}", fg=typer.colors.RED)
|
|
38
|
+
sys.exit(1)
|
|
44
39
|
|
|
45
40
|
|
|
46
41
|
@app.command()
|
|
@@ -55,10 +50,8 @@ def watch():
|
|
|
55
50
|
except KeyboardInterrupt:
|
|
56
51
|
typer.secho("Stopped watching for changes.", fg=typer.colors.RED)
|
|
57
52
|
except subprocess.CalledProcessError as e: # pragma: no cover
|
|
58
|
-
typer.secho(
|
|
59
|
-
|
|
60
|
-
fg=typer.colors.RED,
|
|
61
|
-
)
|
|
53
|
+
typer.secho(f"Failed to start in watch mode: {e.stderr.decode()}", fg=typer.colors.RED)
|
|
54
|
+
sys.exit(1)
|
|
62
55
|
|
|
63
56
|
|
|
64
57
|
@app.command(name="list_templates")
|
|
@@ -285,52 +278,24 @@ def _download_cli(*, force_download: bool = False) -> None:
|
|
|
285
278
|
typer.secho(f"Downloaded Tailwind CSS CLI to '{c.cli_path}'.", fg=typer.colors.GREEN)
|
|
286
279
|
|
|
287
280
|
|
|
288
|
-
DEFAULT_TAILWIND_CONFIG = """/** @type {import('tailwindcss').Config} */
|
|
289
|
-
const plugin = require("tailwindcss/plugin");
|
|
290
|
-
|
|
291
|
-
module.exports = {
|
|
292
|
-
content: ["./templates/**/*.html", "**/templates/**/*.html",'**/*.py'],
|
|
293
|
-
theme: {
|
|
294
|
-
extend: {},
|
|
295
|
-
},
|
|
296
|
-
plugins: [
|
|
297
|
-
require("@tailwindcss/typography"),
|
|
298
|
-
require("@tailwindcss/forms"),
|
|
299
|
-
require("@tailwindcss/aspect-ratio"),
|
|
300
|
-
require("@tailwindcss/container-queries"),
|
|
301
|
-
plugin(function ({ addVariant }) {
|
|
302
|
-
addVariant("htmx-settling", ["&.htmx-settling", ".htmx-settling &"]);
|
|
303
|
-
addVariant("htmx-request", ["&.htmx-request", ".htmx-request &"]);
|
|
304
|
-
addVariant("htmx-swapping", ["&.htmx-swapping", ".htmx-swapping &"]);
|
|
305
|
-
addVariant("htmx-added", ["&.htmx-added", ".htmx-added &"]);
|
|
306
|
-
}),
|
|
307
|
-
],
|
|
308
|
-
};
|
|
309
|
-
"""
|
|
310
|
-
|
|
311
281
|
DEFAULT_SOURCE_CSS = '@import "tailwindcss";\n'
|
|
282
|
+
DAISY_UI_SOURCE_CSS = '@import "tailwindcss";\n@plugin "daisyui";\n'
|
|
312
283
|
|
|
313
284
|
|
|
314
285
|
def _create_standard_config() -> None:
|
|
315
286
|
"""Create a standard Tailwind CSS config file."""
|
|
316
287
|
c = get_config()
|
|
317
288
|
|
|
318
|
-
if c.
|
|
319
|
-
|
|
320
|
-
|
|
289
|
+
if c.src_css and not c.src_css.exists():
|
|
290
|
+
c.src_css.parent.mkdir(parents=True, exist_ok=True)
|
|
291
|
+
if c.use_daisy_ui:
|
|
292
|
+
c.src_css.write_text(DAISY_UI_SOURCE_CSS)
|
|
293
|
+
else:
|
|
321
294
|
c.src_css.write_text(DEFAULT_SOURCE_CSS)
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
else:
|
|
327
|
-
if c.config_file and not c.config_file.exists():
|
|
328
|
-
c.config_file.parent.mkdir(parents=True, exist_ok=True)
|
|
329
|
-
c.config_file.write_text(DEFAULT_TAILWIND_CONFIG)
|
|
330
|
-
typer.secho(
|
|
331
|
-
f"Created Tailwind CSS config at '{c.config_file}'",
|
|
332
|
-
fg=typer.colors.GREEN,
|
|
333
|
-
)
|
|
295
|
+
typer.secho(
|
|
296
|
+
f"Created Tailwind Source CSS at '{c.src_css}'",
|
|
297
|
+
fg=typer.colors.GREEN,
|
|
298
|
+
)
|
|
334
299
|
|
|
335
300
|
|
|
336
301
|
def get_runserver_options(
|