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.
Files changed (50) hide show
  1. {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/.pre-commit-config.yaml +8 -3
  2. {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/CHANGELOG.md +40 -0
  3. {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/PKG-INFO +11 -3
  4. {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/README.md +9 -2
  5. {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/docs/installation.md +0 -9
  6. django_tailwind_cli-4.2.0/docs/requirements.txt +2 -0
  7. django_tailwind_cli-4.2.0/docs/settings.md +101 -0
  8. {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/docs/usage.md +32 -4
  9. {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/justfile +1 -1
  10. {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/mkdocs.yml +1 -0
  11. {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/pyproject.toml +4 -5
  12. django_tailwind_cli-4.2.0/src/django_tailwind_cli/config.py +174 -0
  13. {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/src/django_tailwind_cli/management/commands/tailwind.py +18 -53
  14. {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/src/django_tailwind_cli/templatetags/tailwind_cli.py +2 -4
  15. {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/tests/test_config.py +95 -75
  16. {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/tests/test_management_commands.py +15 -31
  17. {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/tox.ini +1 -1
  18. {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/uv.lock +156 -280
  19. django_tailwind_cli-4.0.1/docs/requirements.txt +0 -1
  20. django_tailwind_cli-4.0.1/docs/settings.md +0 -123
  21. django_tailwind_cli-4.0.1/src/django_tailwind_cli/config.py +0 -131
  22. {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/.github/dependabot.yml +0 -0
  23. {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/.github/workflows/release.yml +0 -0
  24. {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/.github/workflows/test.yml +0 -0
  25. {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/.gitignore +0 -0
  26. {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/.readthedocs.yml +0 -0
  27. {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/CODE_OF_CONDUCT.md +0 -0
  28. {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/LICENSE +0 -0
  29. {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/docs/base_template.md +0 -0
  30. {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/docs/changelog.md +0 -0
  31. {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/docs/index.md +0 -0
  32. {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/docs/template_tags.md +0 -0
  33. {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/src/django_tailwind_cli/__init__.py +0 -0
  34. {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/src/django_tailwind_cli/apps.py +0 -0
  35. {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/src/django_tailwind_cli/management/__init__.py +0 -0
  36. {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/src/django_tailwind_cli/management/commands/__init__.py +0 -0
  37. {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/src/django_tailwind_cli/py.typed +0 -0
  38. {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/src/django_tailwind_cli/templates/tailwind_cli/base.html +0 -0
  39. {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/src/django_tailwind_cli/templates/tailwind_cli/tailwind_css.html +0 -0
  40. {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/src/django_tailwind_cli/templatetags/__init__.py +0 -0
  41. {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/tests/.gitignore +0 -0
  42. {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/tests/__init__.py +0 -0
  43. {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/tests/assets/css/.gitkeep +0 -0
  44. {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/tests/assets/css/tailwind.css +0 -0
  45. {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/tests/conftest.py +0 -0
  46. {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/tests/settings.py +0 -0
  47. {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/tests/templates/tests/base.html +0 -0
  48. {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/tests/templates/tests/dummy.email +0 -0
  49. {django_tailwind_cli-4.0.1 → django_tailwind_cli-4.2.0}/tests/test_get_runserver_options.py +0 -0
  50. {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.7.4"
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.0
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.22.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.1
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
  [![Downloads](https://static.pepy.tech/badge/django-tailwind-cli)](https://pepy.tech/project/django-tailwind-cli)
67
68
  [![Downloads / Month](https://pepy.tech/badge/django-tailwind-cli/month)](<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 3.x and 4.x. Check the [update instructions](https://django-tailwind-cli.rtfd.io/latest/installation/#upgrade-from-tailwind-css-3x-to-4x).
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 Tailwind 3.x and Tailwinc 4.x.
141
+ - Sane default configurations for Tailwinc 4.x.
134
142
 
135
143
  ## Requirements
136
144
 
@@ -10,6 +10,11 @@
10
10
  [![Downloads](https://static.pepy.tech/badge/django-tailwind-cli)](https://pepy.tech/project/django-tailwind-cli)
11
11
  [![Downloads / Month](https://pepy.tech/badge/django-tailwind-cli/month)](<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 3.x and 4.x. Check the [update instructions](https://django-tailwind-cli.rtfd.io/latest/installation/#upgrade-from-tailwind-css-3x-to-4x).
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 Tailwind 3.x and Tailwinc 4.x.
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,2 @@
1
+ mkdocs-material
2
+ markdown-callouts
@@ -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.
@@ -41,4 +41,4 @@ VENV_DIRNAME := ".venv"
41
41
 
42
42
  # serve docs during development
43
43
  @serve-docs: check_uv
44
- uvx --with mkdocs-material mkdocs serve
44
+ uvx --with markdown-callouts --with mkdocs-material mkdocs serve
@@ -42,6 +42,7 @@ markdown_extensions:
42
42
  - footnotes
43
43
  - tables
44
44
  - sane_lists
45
+ - github-callouts
45
46
  - pymdownx.snippets:
46
47
  check_paths: true
47
48
  extra:
@@ -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 = "py38"
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 = ["solomon"]
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
- c = get_config()
26
+ config = get_config()
27
27
  _download_cli()
28
28
  _create_standard_config()
29
29
 
30
30
  try:
31
- subprocess.run(c.build_cmd, cwd=settings.BASE_DIR, check=True, capture_output=True)
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
- typer.secho(
36
- f"Failed to build production stylesheet: {e.stderr.decode()}",
37
- fg=typer.colors.RED,
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
- f"Failed to start in watch mode: {e.stderr.decode()}",
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.version.major >= 4:
319
- if c.src_css and not c.src_css.exists():
320
- c.src_css.parent.mkdir(parents=True, exist_ok=True)
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
- typer.secho(
323
- f"Created Tailwind Source CSS at '{c.src_css}'",
324
- fg=typer.colors.GREEN,
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(