plain.tailwind 0.1.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.
- plain_tailwind-0.1.0/LICENSE +28 -0
- plain_tailwind-0.1.0/PKG-INFO +144 -0
- plain_tailwind-0.1.0/README.md +120 -0
- plain_tailwind-0.1.0/plain/tailwind/README.md +118 -0
- plain_tailwind-0.1.0/plain/tailwind/__init__.py +3 -0
- plain_tailwind-0.1.0/plain/tailwind/cli.py +108 -0
- plain_tailwind-0.1.0/plain/tailwind/core.py +167 -0
- plain_tailwind-0.1.0/plain/tailwind/default_settings.py +4 -0
- plain_tailwind-0.1.0/plain/tailwind/jinja.py +15 -0
- plain_tailwind-0.1.0/plain/tailwind/templates/tailwind/css.html +1 -0
- plain_tailwind-0.1.0/pyproject.toml +31 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
BSD 3-Clause License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023, Dropseed, LLC
|
|
4
|
+
|
|
5
|
+
Redistribution and use in source and binary forms, with or without
|
|
6
|
+
modification, are permitted provided that the following conditions are met:
|
|
7
|
+
|
|
8
|
+
1. Redistributions of source code must retain the above copyright notice, this
|
|
9
|
+
list of conditions and the following disclaimer.
|
|
10
|
+
|
|
11
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
12
|
+
this list of conditions and the following disclaimer in the documentation
|
|
13
|
+
and/or other materials provided with the distribution.
|
|
14
|
+
|
|
15
|
+
3. Neither the name of the copyright holder nor the names of its
|
|
16
|
+
contributors may be used to endorse or promote products derived from
|
|
17
|
+
this software without specific prior written permission.
|
|
18
|
+
|
|
19
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
20
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
21
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
22
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
23
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
24
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
25
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
26
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
27
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
28
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: plain.tailwind
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Integrate Tailwind CSS with Plain.
|
|
5
|
+
Home-page: https://plainframework.com
|
|
6
|
+
License: BSD-3-Clause
|
|
7
|
+
Author: Dave Gaeddert
|
|
8
|
+
Author-email: dave.gaeddert@dropseed.dev
|
|
9
|
+
Requires-Python: >=3.8,<4.0
|
|
10
|
+
Classifier: License :: OSI Approved :: BSD License
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Requires-Dist: click (>=8.0.0)
|
|
18
|
+
Requires-Dist: requests (>=2.0.0)
|
|
19
|
+
Requires-Dist: tomlkit (>=0.12.1,<0.13.0)
|
|
20
|
+
Project-URL: Documentation, https://plainframework.com/docs/
|
|
21
|
+
Project-URL: Repository, https://github.com/dropseed/plain
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
|
|
24
|
+
<!-- This file is compiled from plain-tailwind/plain/tailwind/README.md. Do not edit this file directly. -->
|
|
25
|
+
|
|
26
|
+
# plain.tailwind
|
|
27
|
+
|
|
28
|
+
Integrate Tailwind CSS without JavaScript or npm.
|
|
29
|
+
|
|
30
|
+
Made possible by the [Tailwind standalone CLI](https://tailwindcss.com/blog/standalone-cli),
|
|
31
|
+
which is installed for you.
|
|
32
|
+
|
|
33
|
+
```console
|
|
34
|
+
$ plain tailwind
|
|
35
|
+
Usage: plain tailwind [OPTIONS] COMMAND [ARGS]...
|
|
36
|
+
|
|
37
|
+
Tailwind CSS
|
|
38
|
+
|
|
39
|
+
Options:
|
|
40
|
+
--help Show this message and exit.
|
|
41
|
+
|
|
42
|
+
Commands:
|
|
43
|
+
compile Compile a Tailwind CSS file
|
|
44
|
+
init Install Tailwind, create a tailwind.config.js...
|
|
45
|
+
update Update the Tailwind CSS version
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Installation
|
|
49
|
+
|
|
50
|
+
Add `plain.tailwind` to your `INSTALLED_PACKAGES`:
|
|
51
|
+
|
|
52
|
+
```python
|
|
53
|
+
# settings.py
|
|
54
|
+
INSTALLED_PACKAGES = [
|
|
55
|
+
# ...
|
|
56
|
+
"plain.tailwind",
|
|
57
|
+
]
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Create a new `tailwind.config.js` file in your project root:
|
|
61
|
+
|
|
62
|
+
```sh
|
|
63
|
+
plain tailwind init
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
This will also create a `tailwind.css` file at `static/src/tailwind.css` where additional CSS can be added.
|
|
67
|
+
You can customize where these files are located if you need to,
|
|
68
|
+
but this is the default (requires `STATICFILES_DIR = BASE_DIR / "static"`).
|
|
69
|
+
|
|
70
|
+
The `src/tailwind.css` file is then compiled into `dist/tailwind.css` by running `tailwind compile`:
|
|
71
|
+
|
|
72
|
+
```sh
|
|
73
|
+
plain tailwind compile
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
When you're working locally, add `--watch` to automatically compile as changes are made:
|
|
77
|
+
|
|
78
|
+
```sh
|
|
79
|
+
plain tailwind compile --watch
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Then include the compiled CSS in your base template `<head>`:
|
|
83
|
+
|
|
84
|
+
```html
|
|
85
|
+
{% tailwind_css %}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
In your repo you will notice a new `.plain` directory that contains `tailwind` (the standalone CLI binary) and `tailwind.version` (to track the version currently installed).
|
|
89
|
+
You should add `.plain` to your `.gitignore` file.
|
|
90
|
+
|
|
91
|
+
## Updating Tailwind
|
|
92
|
+
|
|
93
|
+
This package manages the Tailwind versioning by comparing the value in your `pyproject.toml` to `.plain/tailwind.version`.
|
|
94
|
+
|
|
95
|
+
```toml
|
|
96
|
+
# pyproject.toml
|
|
97
|
+
[tool.plain.tailwind]
|
|
98
|
+
version = "3.4.1"
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
When you run `tailwind compile`,
|
|
102
|
+
it will automatically check whether your local installation needs to be updated and will update it if necessary.
|
|
103
|
+
|
|
104
|
+
You can use the `update` command to update your project to the latest version of Tailwind:
|
|
105
|
+
|
|
106
|
+
```sh
|
|
107
|
+
plain tailwind update
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## Adding custom CSS
|
|
111
|
+
|
|
112
|
+
If you need to actually write some CSS,
|
|
113
|
+
it should be done in `app/static/src/tailwind.css`.
|
|
114
|
+
|
|
115
|
+
```css
|
|
116
|
+
@tailwind base;
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
@tailwind components;
|
|
120
|
+
|
|
121
|
+
/* Add your own "components" here */
|
|
122
|
+
.btn {
|
|
123
|
+
@apply bg-blue-500 hover:bg-blue-700 text-white;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
@tailwind utilities;
|
|
127
|
+
|
|
128
|
+
/* Add your own "utilities" here */
|
|
129
|
+
.bg-pattern-stars {
|
|
130
|
+
background-image: url("/static/images/stars.png");
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
[Read the Tailwind docs for more about using custom styles →](https://tailwindcss.com/docs/adding-custom-styles)
|
|
136
|
+
|
|
137
|
+
## Deployment
|
|
138
|
+
|
|
139
|
+
If possible, you should add `static/dist/tailwind.css` to your `.gitignore` and run the `plain tailwind compile --minify` command as a part of your deployment pipeline.
|
|
140
|
+
|
|
141
|
+
When you run `plain tailwind compile`, it will automatically check whether the Tailwind standalone CLI has been installed, and install it if it isn't.
|
|
142
|
+
|
|
143
|
+
When using Plain on Heroku, we do this for you automatically in our [Plain buildpack](https://github.com/plainpackages/heroku-buildpack-plain/blob/master/bin/files/post_compile).
|
|
144
|
+
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
<!-- This file is compiled from plain-tailwind/plain/tailwind/README.md. Do not edit this file directly. -->
|
|
2
|
+
|
|
3
|
+
# plain.tailwind
|
|
4
|
+
|
|
5
|
+
Integrate Tailwind CSS without JavaScript or npm.
|
|
6
|
+
|
|
7
|
+
Made possible by the [Tailwind standalone CLI](https://tailwindcss.com/blog/standalone-cli),
|
|
8
|
+
which is installed for you.
|
|
9
|
+
|
|
10
|
+
```console
|
|
11
|
+
$ plain tailwind
|
|
12
|
+
Usage: plain tailwind [OPTIONS] COMMAND [ARGS]...
|
|
13
|
+
|
|
14
|
+
Tailwind CSS
|
|
15
|
+
|
|
16
|
+
Options:
|
|
17
|
+
--help Show this message and exit.
|
|
18
|
+
|
|
19
|
+
Commands:
|
|
20
|
+
compile Compile a Tailwind CSS file
|
|
21
|
+
init Install Tailwind, create a tailwind.config.js...
|
|
22
|
+
update Update the Tailwind CSS version
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Installation
|
|
26
|
+
|
|
27
|
+
Add `plain.tailwind` to your `INSTALLED_PACKAGES`:
|
|
28
|
+
|
|
29
|
+
```python
|
|
30
|
+
# settings.py
|
|
31
|
+
INSTALLED_PACKAGES = [
|
|
32
|
+
# ...
|
|
33
|
+
"plain.tailwind",
|
|
34
|
+
]
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Create a new `tailwind.config.js` file in your project root:
|
|
38
|
+
|
|
39
|
+
```sh
|
|
40
|
+
plain tailwind init
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
This will also create a `tailwind.css` file at `static/src/tailwind.css` where additional CSS can be added.
|
|
44
|
+
You can customize where these files are located if you need to,
|
|
45
|
+
but this is the default (requires `STATICFILES_DIR = BASE_DIR / "static"`).
|
|
46
|
+
|
|
47
|
+
The `src/tailwind.css` file is then compiled into `dist/tailwind.css` by running `tailwind compile`:
|
|
48
|
+
|
|
49
|
+
```sh
|
|
50
|
+
plain tailwind compile
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
When you're working locally, add `--watch` to automatically compile as changes are made:
|
|
54
|
+
|
|
55
|
+
```sh
|
|
56
|
+
plain tailwind compile --watch
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Then include the compiled CSS in your base template `<head>`:
|
|
60
|
+
|
|
61
|
+
```html
|
|
62
|
+
{% tailwind_css %}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
In your repo you will notice a new `.plain` directory that contains `tailwind` (the standalone CLI binary) and `tailwind.version` (to track the version currently installed).
|
|
66
|
+
You should add `.plain` to your `.gitignore` file.
|
|
67
|
+
|
|
68
|
+
## Updating Tailwind
|
|
69
|
+
|
|
70
|
+
This package manages the Tailwind versioning by comparing the value in your `pyproject.toml` to `.plain/tailwind.version`.
|
|
71
|
+
|
|
72
|
+
```toml
|
|
73
|
+
# pyproject.toml
|
|
74
|
+
[tool.plain.tailwind]
|
|
75
|
+
version = "3.4.1"
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
When you run `tailwind compile`,
|
|
79
|
+
it will automatically check whether your local installation needs to be updated and will update it if necessary.
|
|
80
|
+
|
|
81
|
+
You can use the `update` command to update your project to the latest version of Tailwind:
|
|
82
|
+
|
|
83
|
+
```sh
|
|
84
|
+
plain tailwind update
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Adding custom CSS
|
|
88
|
+
|
|
89
|
+
If you need to actually write some CSS,
|
|
90
|
+
it should be done in `app/static/src/tailwind.css`.
|
|
91
|
+
|
|
92
|
+
```css
|
|
93
|
+
@tailwind base;
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
@tailwind components;
|
|
97
|
+
|
|
98
|
+
/* Add your own "components" here */
|
|
99
|
+
.btn {
|
|
100
|
+
@apply bg-blue-500 hover:bg-blue-700 text-white;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
@tailwind utilities;
|
|
104
|
+
|
|
105
|
+
/* Add your own "utilities" here */
|
|
106
|
+
.bg-pattern-stars {
|
|
107
|
+
background-image: url("/static/images/stars.png");
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
[Read the Tailwind docs for more about using custom styles →](https://tailwindcss.com/docs/adding-custom-styles)
|
|
113
|
+
|
|
114
|
+
## Deployment
|
|
115
|
+
|
|
116
|
+
If possible, you should add `static/dist/tailwind.css` to your `.gitignore` and run the `plain tailwind compile --minify` command as a part of your deployment pipeline.
|
|
117
|
+
|
|
118
|
+
When you run `plain tailwind compile`, it will automatically check whether the Tailwind standalone CLI has been installed, and install it if it isn't.
|
|
119
|
+
|
|
120
|
+
When using Plain on Heroku, we do this for you automatically in our [Plain buildpack](https://github.com/plainpackages/heroku-buildpack-plain/blob/master/bin/files/post_compile).
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# plain.tailwind
|
|
2
|
+
|
|
3
|
+
Integrate Tailwind CSS without JavaScript or npm.
|
|
4
|
+
|
|
5
|
+
Made possible by the [Tailwind standalone CLI](https://tailwindcss.com/blog/standalone-cli),
|
|
6
|
+
which is installed for you.
|
|
7
|
+
|
|
8
|
+
```console
|
|
9
|
+
$ plain tailwind
|
|
10
|
+
Usage: plain tailwind [OPTIONS] COMMAND [ARGS]...
|
|
11
|
+
|
|
12
|
+
Tailwind CSS
|
|
13
|
+
|
|
14
|
+
Options:
|
|
15
|
+
--help Show this message and exit.
|
|
16
|
+
|
|
17
|
+
Commands:
|
|
18
|
+
compile Compile a Tailwind CSS file
|
|
19
|
+
init Install Tailwind, create a tailwind.config.js...
|
|
20
|
+
update Update the Tailwind CSS version
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Installation
|
|
24
|
+
|
|
25
|
+
Add `plain.tailwind` to your `INSTALLED_PACKAGES`:
|
|
26
|
+
|
|
27
|
+
```python
|
|
28
|
+
# settings.py
|
|
29
|
+
INSTALLED_PACKAGES = [
|
|
30
|
+
# ...
|
|
31
|
+
"plain.tailwind",
|
|
32
|
+
]
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Create a new `tailwind.config.js` file in your project root:
|
|
36
|
+
|
|
37
|
+
```sh
|
|
38
|
+
plain tailwind init
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
This will also create a `tailwind.css` file at `static/src/tailwind.css` where additional CSS can be added.
|
|
42
|
+
You can customize where these files are located if you need to,
|
|
43
|
+
but this is the default (requires `STATICFILES_DIR = BASE_DIR / "static"`).
|
|
44
|
+
|
|
45
|
+
The `src/tailwind.css` file is then compiled into `dist/tailwind.css` by running `tailwind compile`:
|
|
46
|
+
|
|
47
|
+
```sh
|
|
48
|
+
plain tailwind compile
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
When you're working locally, add `--watch` to automatically compile as changes are made:
|
|
52
|
+
|
|
53
|
+
```sh
|
|
54
|
+
plain tailwind compile --watch
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Then include the compiled CSS in your base template `<head>`:
|
|
58
|
+
|
|
59
|
+
```html
|
|
60
|
+
{% tailwind_css %}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
In your repo you will notice a new `.plain` directory that contains `tailwind` (the standalone CLI binary) and `tailwind.version` (to track the version currently installed).
|
|
64
|
+
You should add `.plain` to your `.gitignore` file.
|
|
65
|
+
|
|
66
|
+
## Updating Tailwind
|
|
67
|
+
|
|
68
|
+
This package manages the Tailwind versioning by comparing the value in your `pyproject.toml` to `.plain/tailwind.version`.
|
|
69
|
+
|
|
70
|
+
```toml
|
|
71
|
+
# pyproject.toml
|
|
72
|
+
[tool.plain.tailwind]
|
|
73
|
+
version = "3.4.1"
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
When you run `tailwind compile`,
|
|
77
|
+
it will automatically check whether your local installation needs to be updated and will update it if necessary.
|
|
78
|
+
|
|
79
|
+
You can use the `update` command to update your project to the latest version of Tailwind:
|
|
80
|
+
|
|
81
|
+
```sh
|
|
82
|
+
plain tailwind update
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Adding custom CSS
|
|
86
|
+
|
|
87
|
+
If you need to actually write some CSS,
|
|
88
|
+
it should be done in `app/static/src/tailwind.css`.
|
|
89
|
+
|
|
90
|
+
```css
|
|
91
|
+
@tailwind base;
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
@tailwind components;
|
|
95
|
+
|
|
96
|
+
/* Add your own "components" here */
|
|
97
|
+
.btn {
|
|
98
|
+
@apply bg-blue-500 hover:bg-blue-700 text-white;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
@tailwind utilities;
|
|
102
|
+
|
|
103
|
+
/* Add your own "utilities" here */
|
|
104
|
+
.bg-pattern-stars {
|
|
105
|
+
background-image: url("/static/images/stars.png");
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
[Read the Tailwind docs for more about using custom styles →](https://tailwindcss.com/docs/adding-custom-styles)
|
|
111
|
+
|
|
112
|
+
## Deployment
|
|
113
|
+
|
|
114
|
+
If possible, you should add `static/dist/tailwind.css` to your `.gitignore` and run the `plain tailwind compile --minify` command as a part of your deployment pipeline.
|
|
115
|
+
|
|
116
|
+
When you run `plain tailwind compile`, it will automatically check whether the Tailwind standalone CLI has been installed, and install it if it isn't.
|
|
117
|
+
|
|
118
|
+
When using Plain on Heroku, we do this for you automatically in our [Plain buildpack](https://github.com/plainpackages/heroku-buildpack-plain/blob/master/bin/files/post_compile).
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
3
|
+
import click
|
|
4
|
+
|
|
5
|
+
from plain.packages import packages
|
|
6
|
+
from plain.runtime import APP_PATH
|
|
7
|
+
|
|
8
|
+
from .core import Tailwind
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@click.group("tailwind")
|
|
12
|
+
def cli():
|
|
13
|
+
"""Tailwind CSS"""
|
|
14
|
+
pass
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@cli.command()
|
|
18
|
+
def init():
|
|
19
|
+
"""Install Tailwind, create a tailwind.config.js and app/assets/src/tailwind.css"""
|
|
20
|
+
tailwind = Tailwind()
|
|
21
|
+
|
|
22
|
+
tailwind_installed = tailwind.is_installed()
|
|
23
|
+
|
|
24
|
+
if not tailwind_installed:
|
|
25
|
+
# Need to do an initial download to run init
|
|
26
|
+
tailwind.download()
|
|
27
|
+
|
|
28
|
+
# Config needs to exist first so we can save the version here
|
|
29
|
+
if not tailwind.config_exists():
|
|
30
|
+
click.secho("Creating Tailwind config...", bold=True)
|
|
31
|
+
tailwind.create_config()
|
|
32
|
+
|
|
33
|
+
if not tailwind_installed:
|
|
34
|
+
# Mostly need to save the version to config...
|
|
35
|
+
click.secho("Installing Tailwind standalone...", bold=True, nl=False)
|
|
36
|
+
version = tailwind.install()
|
|
37
|
+
click.secho(f"Tailwind {version} installed", fg="green")
|
|
38
|
+
|
|
39
|
+
if not tailwind.src_css_exists():
|
|
40
|
+
click.secho("Creating Tailwind source CSS...", bold=True)
|
|
41
|
+
tailwind.create_src_css()
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
@cli.command()
|
|
45
|
+
@click.option("--watch", is_flag=True)
|
|
46
|
+
@click.option("--minify", is_flag=True)
|
|
47
|
+
def compile(watch, minify):
|
|
48
|
+
"""Compile a Tailwind CSS file"""
|
|
49
|
+
tailwind = Tailwind()
|
|
50
|
+
|
|
51
|
+
if not tailwind.is_installed() or tailwind.needs_update():
|
|
52
|
+
version_to_install = tailwind.get_version_from_config()
|
|
53
|
+
if version_to_install:
|
|
54
|
+
click.secho(
|
|
55
|
+
f"Installing Tailwind standalone {version_to_install}...",
|
|
56
|
+
bold=True,
|
|
57
|
+
nl=False,
|
|
58
|
+
)
|
|
59
|
+
version = tailwind.install(version_to_install)
|
|
60
|
+
else:
|
|
61
|
+
click.secho("Installing Tailwind standalone...", bold=True, nl=False)
|
|
62
|
+
version = tailwind.install()
|
|
63
|
+
click.secho(f"Tailwind {version} installed", fg="green")
|
|
64
|
+
|
|
65
|
+
args = []
|
|
66
|
+
args.append("-i")
|
|
67
|
+
print(f"Input: {tailwind.src_css_path}")
|
|
68
|
+
args.append(tailwind.src_css_path)
|
|
69
|
+
|
|
70
|
+
args.append("-o")
|
|
71
|
+
print(f"Output: {tailwind.dist_css_path}")
|
|
72
|
+
args.append(tailwind.dist_css_path)
|
|
73
|
+
|
|
74
|
+
# These paths should actually work on Windows too
|
|
75
|
+
# https://github.com/mrmlnc/fast-glob#how-to-write-patterns-on-windows
|
|
76
|
+
args.append("--content")
|
|
77
|
+
paths = [
|
|
78
|
+
os.path.relpath(APP_PATH) + "/**/*.{html,js}",
|
|
79
|
+
]
|
|
80
|
+
|
|
81
|
+
# Add paths from installed packages
|
|
82
|
+
for package_config in packages.get_package_configs():
|
|
83
|
+
paths.append(os.path.relpath(package_config.path) + "/**/*.{html,js}")
|
|
84
|
+
|
|
85
|
+
content = ",".join(paths)
|
|
86
|
+
print(f"Content: {content}")
|
|
87
|
+
args.append(content)
|
|
88
|
+
|
|
89
|
+
if watch:
|
|
90
|
+
args.append("--watch")
|
|
91
|
+
|
|
92
|
+
if minify:
|
|
93
|
+
args.append("--minify")
|
|
94
|
+
|
|
95
|
+
tailwind.invoke(*args, cwd=os.path.dirname(APP_PATH))
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
@cli.command()
|
|
99
|
+
def update():
|
|
100
|
+
"""Update the Tailwind CSS version"""
|
|
101
|
+
tailwind = Tailwind()
|
|
102
|
+
click.secho("Installing Tailwind standalone...", bold=True, nl=True)
|
|
103
|
+
version = tailwind.install()
|
|
104
|
+
click.secho(f"Tailwind {version} installed", fg="green")
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
if __name__ == "__main__":
|
|
108
|
+
cli()
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import platform
|
|
3
|
+
import subprocess
|
|
4
|
+
import sys
|
|
5
|
+
|
|
6
|
+
import requests
|
|
7
|
+
import tomlkit
|
|
8
|
+
|
|
9
|
+
from plain.runtime import settings
|
|
10
|
+
|
|
11
|
+
DEFAULT_CSS = """@tailwind base;
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@tailwind components;
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@tailwind utilities;
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class Tailwind:
|
|
22
|
+
@property
|
|
23
|
+
def target_directory(self) -> str:
|
|
24
|
+
return str(settings.PLAIN_TEMP_PATH)
|
|
25
|
+
|
|
26
|
+
@property
|
|
27
|
+
def standalone_path(self) -> str:
|
|
28
|
+
return os.path.join(self.target_directory, "tailwind")
|
|
29
|
+
|
|
30
|
+
@property
|
|
31
|
+
def version_lockfile_path(self) -> str:
|
|
32
|
+
return os.path.join(self.target_directory, "tailwind.version")
|
|
33
|
+
|
|
34
|
+
@property
|
|
35
|
+
def config_path(self) -> str:
|
|
36
|
+
return os.path.join(
|
|
37
|
+
os.path.dirname(self.target_directory), "tailwind.config.js"
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
@property
|
|
41
|
+
def src_css_path(self) -> str:
|
|
42
|
+
return settings.TAILWIND_SRC_PATH
|
|
43
|
+
|
|
44
|
+
@property
|
|
45
|
+
def dist_css_path(self) -> str:
|
|
46
|
+
return settings.TAILWIND_DIST_PATH
|
|
47
|
+
|
|
48
|
+
def invoke(self, *args, cwd=None) -> None:
|
|
49
|
+
result = subprocess.run([self.standalone_path] + list(args), cwd=cwd)
|
|
50
|
+
if result.returncode != 0:
|
|
51
|
+
sys.exit(result.returncode)
|
|
52
|
+
|
|
53
|
+
def is_installed(self) -> bool:
|
|
54
|
+
if not os.path.exists(self.target_directory):
|
|
55
|
+
os.mkdir(self.target_directory)
|
|
56
|
+
return os.path.exists(os.path.join(self.target_directory, "tailwind"))
|
|
57
|
+
|
|
58
|
+
def config_exists(self) -> bool:
|
|
59
|
+
return os.path.exists(self.config_path)
|
|
60
|
+
|
|
61
|
+
def create_config(self):
|
|
62
|
+
self.invoke("init", self.config_path)
|
|
63
|
+
|
|
64
|
+
def src_css_exists(self) -> bool:
|
|
65
|
+
return os.path.exists(self.src_css_path)
|
|
66
|
+
|
|
67
|
+
def create_src_css(self):
|
|
68
|
+
os.makedirs(os.path.dirname(self.src_css_path), exist_ok=True)
|
|
69
|
+
with open(self.src_css_path, "w") as f:
|
|
70
|
+
f.write(DEFAULT_CSS)
|
|
71
|
+
|
|
72
|
+
def needs_update(self) -> bool:
|
|
73
|
+
if not os.path.exists(self.version_lockfile_path):
|
|
74
|
+
return True
|
|
75
|
+
|
|
76
|
+
with open(self.version_lockfile_path) as f:
|
|
77
|
+
locked_version = f.read().strip()
|
|
78
|
+
|
|
79
|
+
if locked_version != self.get_version_from_config():
|
|
80
|
+
return True
|
|
81
|
+
|
|
82
|
+
return False
|
|
83
|
+
|
|
84
|
+
def get_version_from_config(self) -> str:
|
|
85
|
+
pyproject_path = os.path.join(
|
|
86
|
+
os.path.dirname(self.target_directory), "pyproject.toml"
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
if not os.path.exists(pyproject_path):
|
|
90
|
+
return ""
|
|
91
|
+
|
|
92
|
+
with open(pyproject_path) as f:
|
|
93
|
+
config = tomlkit.load(f)
|
|
94
|
+
return (
|
|
95
|
+
config.get("tool", {})
|
|
96
|
+
.get("plain", {})
|
|
97
|
+
.get("tailwind", {})
|
|
98
|
+
.get("version", "")
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
def set_version_in_config(self, version):
|
|
102
|
+
pyproject_path = os.path.join(
|
|
103
|
+
os.path.dirname(self.target_directory), "pyproject.toml"
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
with open(pyproject_path) as f:
|
|
107
|
+
config = tomlkit.load(f)
|
|
108
|
+
|
|
109
|
+
config.setdefault("tool", {}).setdefault("plain", {}).setdefault(
|
|
110
|
+
"tailwind", {}
|
|
111
|
+
)["version"] = version
|
|
112
|
+
|
|
113
|
+
with open(pyproject_path, "w") as f:
|
|
114
|
+
tomlkit.dump(config, f)
|
|
115
|
+
|
|
116
|
+
def download(self, version="") -> str:
|
|
117
|
+
if version:
|
|
118
|
+
if not version.startswith("v"):
|
|
119
|
+
version = f"v{version}"
|
|
120
|
+
url = f"https://github.com/tailwindlabs/tailwindcss/releases/download/{version}/tailwindcss-{self.detect_platform_slug()}"
|
|
121
|
+
else:
|
|
122
|
+
url = f"https://github.com/tailwindlabs/tailwindcss/releases/latest/download/tailwindcss-{self.detect_platform_slug()}"
|
|
123
|
+
|
|
124
|
+
with requests.get(url, stream=True) as response:
|
|
125
|
+
response.raise_for_status()
|
|
126
|
+
with open(self.standalone_path, "wb") as f:
|
|
127
|
+
for chunk in response.iter_content(chunk_size=8192):
|
|
128
|
+
f.write(chunk)
|
|
129
|
+
|
|
130
|
+
os.chmod(self.standalone_path, 0o755)
|
|
131
|
+
|
|
132
|
+
if not version:
|
|
133
|
+
# Get the version from the redirect chain (latest -> vX.Y.Z)
|
|
134
|
+
version = response.history[1].url.split("/")[-2]
|
|
135
|
+
|
|
136
|
+
version = version.lstrip("v")
|
|
137
|
+
|
|
138
|
+
with open(self.version_lockfile_path, "w") as f:
|
|
139
|
+
f.write(version)
|
|
140
|
+
|
|
141
|
+
return version
|
|
142
|
+
|
|
143
|
+
def install(self, version="") -> str:
|
|
144
|
+
installed_version = self.download(version)
|
|
145
|
+
self.set_version_in_config(installed_version)
|
|
146
|
+
return installed_version
|
|
147
|
+
|
|
148
|
+
@staticmethod
|
|
149
|
+
def detect_platform_slug() -> str:
|
|
150
|
+
uname = platform.uname()[0]
|
|
151
|
+
|
|
152
|
+
if uname == "Windows":
|
|
153
|
+
return "windows-x64.exe"
|
|
154
|
+
|
|
155
|
+
if uname == "Linux" and platform.uname()[4] == "aarch64":
|
|
156
|
+
return "linux-arm64"
|
|
157
|
+
|
|
158
|
+
if uname == "Linux":
|
|
159
|
+
return "linux-x64"
|
|
160
|
+
|
|
161
|
+
if uname == "Darwin" and platform.uname().machine == "arm64":
|
|
162
|
+
return "macos-arm64"
|
|
163
|
+
|
|
164
|
+
if uname == "Darwin":
|
|
165
|
+
return "macos-x64"
|
|
166
|
+
|
|
167
|
+
raise Exception("Unsupported platform for Tailwind standalone")
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from plain.assets.finders import APP_ASSETS_DIR
|
|
2
|
+
from plain.runtime import settings
|
|
3
|
+
from plain.templates.jinja.extensions import InclusionTagExtension
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class TailwindCSSExtension(InclusionTagExtension):
|
|
7
|
+
tags = {"tailwind_css"}
|
|
8
|
+
template_name = "tailwind/css.html"
|
|
9
|
+
|
|
10
|
+
def get_context(self, context, *args, **kwargs):
|
|
11
|
+
tailwind_css_path = str(settings.TAILWIND_DIST_PATH.relative_to(APP_ASSETS_DIR))
|
|
12
|
+
return {"tailwind_css_path": tailwind_css_path}
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
extensions = [TailwindCSSExtension]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<link href="{{ asset(tailwind_css_path) }}" rel="stylesheet">
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
[tool.poetry]
|
|
2
|
+
|
|
3
|
+
name = "plain.tailwind"
|
|
4
|
+
packages = [
|
|
5
|
+
{ include = "plain" },
|
|
6
|
+
]
|
|
7
|
+
|
|
8
|
+
version = "0.1.0"
|
|
9
|
+
description = "Integrate Tailwind CSS with Plain."
|
|
10
|
+
authors = ["Dave Gaeddert <dave.gaeddert@dropseed.dev>"]
|
|
11
|
+
license = "BSD-3-Clause"
|
|
12
|
+
readme = "README.md"
|
|
13
|
+
homepage = "https://plainframework.com"
|
|
14
|
+
documentation = "https://plainframework.com/docs/"
|
|
15
|
+
repository = "https://github.com/dropseed/plain"
|
|
16
|
+
|
|
17
|
+
[tool.poetry.dependencies]
|
|
18
|
+
python = "^3.8"
|
|
19
|
+
click = ">=8.0.0"
|
|
20
|
+
requests = ">=2.0.0"
|
|
21
|
+
tomlkit = "^0.12.1"
|
|
22
|
+
|
|
23
|
+
[tool.poetry.dev-dependencies]
|
|
24
|
+
pytest = "^7.1.2"
|
|
25
|
+
ipdb = "^0.13.9"
|
|
26
|
+
isort = "^5.10.1"
|
|
27
|
+
black = "^22.3.0"
|
|
28
|
+
|
|
29
|
+
[build-system]
|
|
30
|
+
requires = ["poetry-core>=1.0.0"]
|
|
31
|
+
build-backend = "poetry.core.masonry.api"
|