1656885060
В этом руководстве вы узнаете, как настроить Flask с помощью htmx и Tailwind CSS . Цель как htmx, так и Tailwind — упростить современную веб-разработку, чтобы вы могли проектировать и обеспечивать интерактивность, не отказываясь от удобства и простоты HTML. Мы также рассмотрим, как использовать Flask-Assets для объединения и минимизации статических ресурсов в приложении Flask.
htmx — это библиотека, которая позволяет вам получать доступ к современным функциям браузера, таким как AJAX, переходы CSS, WebSockets и события, отправленные сервером, непосредственно из HTML, а не с помощью JavaScript. Он позволяет быстро создавать пользовательские интерфейсы непосредственно в разметке.
htmx расширяет несколько функций, уже встроенных в браузер, таких как выполнение HTTP-запросов и реагирование на события. Например, вместо того, чтобы делать запросы GET и POST только через элементы a
и form
, вы можете использовать атрибуты HTML для отправки запросов GET, POST, PUT, PATCH или DELETE для любого элемента HTML:
<button hx-delete="/user/1">Delete</button>
Вы также можете обновить части страницы, чтобы создать одностраничное приложение (SPA): ссылка CodePen
Откройте вкладку сети в инструментах разработчика браузера. При нажатии кнопки на конечную точку отправляется запрос XHR https://v2.jokeapi.dev/joke/Any?format=txt&safe-mode
. Затем ответ добавляется к p
элементу с id
выводом.
Дополнительные примеры см . на странице примеров пользовательского интерфейса в официальной документации htmx.
Плюсы :
Минусы :
Tailwind CSS — это CSS-фреймворк, ориентированный прежде всего на полезность. Вместо того, чтобы поставлять готовые компоненты (на которых специализируются такие фреймворки, как Bootstrap и Bulma ), он предоставляет строительные блоки в виде служебных классов, которые позволяют быстро и легко создавать макеты и проекты.
Например, возьмите следующий HTML и CSS:
<style>
.hello {
height: 5px;
width: 10px;
background: gray;
border-width: 1px;
border-radius: 3px;
padding: 5px;
}
</style>
<div class="hello">Hello World</div>
Это можно реализовать с помощью Tailwind следующим образом:
<div class="h-1 w-2 bg-gray-600 border rounded-sm p-1">Hello World</div>
Воспользуйтесь конвертером CSS Tailwind , чтобы преобразовать необработанный CSS в эквивалентные служебные классы в Tailwind. Сравните результаты.
Плюсы :
<div class="bg-white dark:bg-black">
.Минусы :
Flask-Assets — это расширение, предназначенное для управления статическими активами в приложении Flask. С его помощью вы создаете простой конвейер активов для:
Итак, давайте посмотрим, как работать с каждым из вышеперечисленных инструментов во Flask!
Для начала создайте новый каталог для нашего проекта, создайте и активируйте новую виртуальную среду и установите Flask вместе с Flask-Assets:
$ mkdir flask-htmx-tailwind && cd flask-htmx-tailwind
$ python3.10 -m venv venv
$ source venv/bin/activate
(venv)$
(venv)$ pip install Flask==2.1.1 Flask-Assets==2.0
Далее давайте установим pytailwindcss и загрузим его бинарник:
(venv)$ pip install pytailwindcss==0.1.4
(venv)$ tailwindcss
Затем добавьте файл app.py :
# app.py
from flask import Flask
from flask_assets import Bundle, Environment
app = Flask(__name__)
assets = Environment(app)
css = Bundle("src/main.css", output="dist/main.css")
assets.register("css", css)
css.build()
После импорта Bundle и Environment мы создали новый Environment
и зарегистрировали в нем наши активы CSS через файл Bundle
.
Созданный нами пакет принимает src/main.css в качестве входных данных, которые затем будут обработаны и выведены в dist/main.css при запуске интерфейса командной строки Tailwind CSS.
Поскольку все статические файлы Flask по умолчанию находятся в «статической» папке, вышеупомянутые папки «src» и «dist» находятся в «статической» папке.
Итак, давайте настроим Tailwind.
Начните с создания файла конфигурации Tailwind:
(venv)$ tailwindcss init
Эта команда создала файл tailwind.config.js в корне вашего проекта. Все настройки, связанные с Tailwind, находятся в этом файле.
Обновите tailwind.config.js следующим образом:
module.exports = {
content: [
'./templates/**/*.html',
],
theme: {
extend: {},
},
plugins: [],
}
Обратите внимание на раздел контента . Здесь вы настраиваете пути к HTML-шаблонам вашего проекта. Tailwind CSS просканирует ваши шаблоны в поисках имен классов Tailwind. Сгенерированный выходной файл CSS будет содержать только CSS для соответствующих имен классов, найденных в ваших файлах шаблонов. Это помогает уменьшить размер сгенерированных файлов CSS, поскольку они будут содержать только те стили, которые фактически используются.
Добавьте следующее в static/src/main.css :
/* static/src/main.css */
@tailwind base;
@tailwind components;
@tailwind utilities;
Здесь мы определили все классы base
, components
и utilities
из Tailwind CSS.
Теперь у вас есть подключенные Flask-Assets и Tailwind. Далее мы рассмотрим, как обслуживать файл index.html , чтобы увидеть CSS в действии.
Добавьте маршрут вместе с основным блоком для запуска сервера разработки Flask в app.py следующим образом:
# app.py
from flask import Flask, render_template
from flask_assets import Bundle, Environment
app = Flask(__name__)
assets = Environment(app)
css = Bundle("src/main.css", output="dist/main.css")
assets.register("css", css)
css.build()
@app.route("/")
def homepage():
return render_template("index.html")
if __name__ == "__main__":
app.run(debug=True)
Создайте папку «шаблоны». Затем добавьте к нему файл base.html :
<!-- templates/base.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
{% assets 'css' %}
<link rel="stylesheet" href="{{ ASSET_URL }}">
{% endassets %}
<title>Flask + htmlx + Tailwind CSS</title>
</head>
<body class="bg-blue-100">
{% block content %}
{% endblock content %}
</body>
</html>
Обратите внимание на {% assets 'css' %}
блок. Поскольку мы зарегистрировали пакет CSS в среде приложения, мы можем получить к нему доступ, используя зарегистрированное имя, css
и {{ ASSET_URL }}
автоматически будет использоваться путь.
Кроме того, мы добавили некоторый цвет в тело HTML с помощью bg-blue-100
, который меняет цвет фона на светло-голубой.
Добавьте файл index.html :
<!-- templates/index.html -->
{% extends "base.html" %}
{% block content %}
<h1>Hello World</h1>
{% endblock content %}
Теперь выполните следующую команду в корне проекта, чтобы отсканировать шаблоны на наличие классов и сгенерировать файл CSS:
(venv)$ tailwindcss -i ./static/src/main.css -o ./static/dist/main.css --minify
Вы должны увидеть новый каталог с именем «dist» внутри «статической» папки.
Обратите внимание на сгенерированный файл static/dist/main.css .
Запустите сервер разработки через python app.py
и перейдите по адресу http://localhost:5000 в браузере, чтобы увидеть результаты.
С настроенным Tailwind давайте добавим htmx и создадим живой поиск, который отображает результаты по мере ввода.
Вместо того, чтобы извлекать библиотеку htmx из CDN, давайте загрузим ее и используем Flask-Assets для ее объединения.
Загрузите библиотеку с https://unpkg.com/htmx.org@1.7.0/dist/htmx.js и сохраните ее в «static/src».
Теперь, чтобы создать новый пакет для наших файлов JavaScript, обновите app.py следующим образом:
# app.py
from flask import Flask, render_template
from flask_assets import Bundle, Environment
app = Flask(__name__)
assets = Environment(app)
css = Bundle("src/main.css", output="dist/main.css")
js = Bundle("src/*.js", output="dist/main.js") # new
assets.register("css", css)
assets.register("js", js) # new
css.build()
js.build() # new
@app.route("/")
def homepage():
return render_template("index.html")
if __name__ == "__main__":
app.run(debug=True)
Здесь мы создали новый пакет с именем js
, который выводит в static/dist/main.js . Поскольку здесь мы не используем никаких фильтров, исходный и целевой файлы будут одинаковыми.
Затем добавьте новый актив в наш файл base.html :
<!-- templates/base.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
{% assets 'css' %}
<link rel="stylesheet" href="{{ ASSET_URL }}">
{% endassets %}
<!-- new -->
{% assets 'js' %}
<script type="text/javascript" src="{{ ASSET_URL }}"></script>
{% endassets %}
<title>Flask + htmlx + Tailwind CSS</title>
</head>
<body class="bg-blue-100">
{% block content %}
{% endblock content %}
</body>
</html>
Чтобы у нас были данные для работы, сохраните https://github.com/testdrivenio/flask-htmx-tailwind/blob/master/todo.py в новый файл с именем todo.py.
Мы добавим возможность поиска по названию каждой задачи.
Обновите файл index.html следующим образом:
<!-- templates/index.html -->
{% extends 'base.html' %}
{% block content %}
<div class="w-small w-2/3 mx-auto py-10 text-gray-600">
<input
type="text"
name="search"
hx-post="/search"
hx-trigger="keyup changed delay:250ms"
hx-indicator=".htmx-indicator"
hx-target="#todo-results"
placeholder="Search"
class="bg-white h-10 px-5 pr-10 rounded-full text-2xl focus:outline-none"
>
<span class="htmx-indicator">Searching...</span>
</div>
<table class="border-collapse w-small w-2/3 mx-auto">
<thead>
<tr>
<th class="p-3 font-bold uppercase bg-gray-200 text-gray-600 border border-gray-300 hidden lg:table-cell">#</th>
<th class="p-3 font-bold uppercase bg-gray-200 text-gray-600 border border-gray-300 hidden lg:table-cell">Title</th>
<th class="p-3 font-bold uppercase bg-gray-200 text-gray-600 border border-gray-300 hidden lg:table-cell">Completed</th>
</tr>
</thead>
<tbody id="todo-results">
{% include 'todo.html' %}
</tbody>
</table>
{% endblock content %}
Давайте рассмотрим атрибуты, определенные в htmx:
<input
type="text"
name="search"
hx-post="/search"
hx-trigger="keyup changed delay:250ms"
hx-indicator=".htmx-indicator"
hx-target="#todo-results"
placeholder="Search"
class="bg-white h-10 px-5 pr-10 rounded-full text-2xl focus:outline-none"
>
/search
конечную точку.#todo-results
элементе.Добавьте файл templates/todo.html :
<!-- templates/todo.html -->
{% if todos|length>0 %}
{% for todo in todos %}
<tr class="bg-white lg:hover:bg-gray-100 flex lg:table-row flex-row lg:flex-row flex-wrap lg:flex-no-wrap mb-10 lg:mb-0">
<td class="w-full lg:w-auto p-3 text-gray-800 text-center border border-b block lg:table-cell relative lg:static">{{todo.id}}</td>
<td class="w-full lg:w-auto p-3 text-gray-800 text-center border border-b block lg:table-cell relative lg:static">{{todo.title}}</td>
<td class="w-full lg:w-auto p-3 text-gray-800 text-center border border-b block lg:table-cell relative lg:static">
{% if todo.completed %}
<span class="rounded bg-green-400 py-1 px-3 text-xs font-bold">Yes</span>
{% else %}
<span class="rounded bg-red-400 py-1 px-3 text-xs font-bold">No</span>
{% endif %}
</td>
</tr>
{% endfor %}
{% endif %}
Этот файл отображает задачи, соответствующие нашему поисковому запросу.
Наконец, добавьте обработчик маршрута в app.py :
@app.route("/search", methods=["POST"])
def search_todo():
search_term = request.form.get("search")
if not len(search_term):
return render_template("todo.html", todos=[])
res_todos = []
for todo in todos:
if search_term in todo["title"]:
res_todos.append(todo)
return render_template("todo.html", todos=res_todos)
Конечная /search
точка выполняет поиск задач и отображает шаблон todo.html со всеми результатами.
Обновите импорт вверху:
from flask import Flask, render_template, request
from flask_assets import Bundle, Environment
from todo import todos
Затем обновите выходной файл CSS:
(venv)$ tailwindcss -i ./static/src/main.css -o ./static/dist/main.css --minify
Запустите приложение с помощью python app.py
и снова перейдите по адресу http://localhost:5000 , чтобы проверить его:
В этом уроке мы рассмотрели, как:
htmx может отображать элементы без перезагрузки страницы. Самое главное, вы можете добиться этого без написания JavaScript. Хотя это уменьшает объем работы, необходимой на стороне клиента, данные, отправляемые с сервера, могут быть выше, поскольку он отправляет обработанный HTML.
Подобные частичные HTML-шаблоны были популярны в начале 2000-х годов. htmx предлагает современный подход к этому подходу. В целом, обслуживание частичных шаблонов снова становится популярным из-за сложности таких фреймворков, как React и Vue. Вы также можете добавить WebSockets для внесения изменений в реальном времени. Этот же подход используется в знаменитом Phoenix LiveView . Вы можете узнать больше о HTML поверх WebSockets в статье Будущее веб-программного обеспечения — это HTML поверх WebSockets и HTML поверх WebSockets .
Библиотека еще молода, но будущее у нее очень светлое.
Источник: https://testdriven.io
1656885060
В этом руководстве вы узнаете, как настроить Flask с помощью htmx и Tailwind CSS . Цель как htmx, так и Tailwind — упростить современную веб-разработку, чтобы вы могли проектировать и обеспечивать интерактивность, не отказываясь от удобства и простоты HTML. Мы также рассмотрим, как использовать Flask-Assets для объединения и минимизации статических ресурсов в приложении Flask.
htmx — это библиотека, которая позволяет вам получать доступ к современным функциям браузера, таким как AJAX, переходы CSS, WebSockets и события, отправленные сервером, непосредственно из HTML, а не с помощью JavaScript. Он позволяет быстро создавать пользовательские интерфейсы непосредственно в разметке.
htmx расширяет несколько функций, уже встроенных в браузер, таких как выполнение HTTP-запросов и реагирование на события. Например, вместо того, чтобы делать запросы GET и POST только через элементы a
и form
, вы можете использовать атрибуты HTML для отправки запросов GET, POST, PUT, PATCH или DELETE для любого элемента HTML:
<button hx-delete="/user/1">Delete</button>
Вы также можете обновить части страницы, чтобы создать одностраничное приложение (SPA): ссылка CodePen
Откройте вкладку сети в инструментах разработчика браузера. При нажатии кнопки на конечную точку отправляется запрос XHR https://v2.jokeapi.dev/joke/Any?format=txt&safe-mode
. Затем ответ добавляется к p
элементу с id
выводом.
Дополнительные примеры см . на странице примеров пользовательского интерфейса в официальной документации htmx.
Плюсы :
Минусы :
Tailwind CSS — это CSS-фреймворк, ориентированный прежде всего на полезность. Вместо того, чтобы поставлять готовые компоненты (на которых специализируются такие фреймворки, как Bootstrap и Bulma ), он предоставляет строительные блоки в виде служебных классов, которые позволяют быстро и легко создавать макеты и проекты.
Например, возьмите следующий HTML и CSS:
<style>
.hello {
height: 5px;
width: 10px;
background: gray;
border-width: 1px;
border-radius: 3px;
padding: 5px;
}
</style>
<div class="hello">Hello World</div>
Это можно реализовать с помощью Tailwind следующим образом:
<div class="h-1 w-2 bg-gray-600 border rounded-sm p-1">Hello World</div>
Воспользуйтесь конвертером CSS Tailwind , чтобы преобразовать необработанный CSS в эквивалентные служебные классы в Tailwind. Сравните результаты.
Плюсы :
<div class="bg-white dark:bg-black">
.Минусы :
Flask-Assets — это расширение, предназначенное для управления статическими активами в приложении Flask. С его помощью вы создаете простой конвейер активов для:
Итак, давайте посмотрим, как работать с каждым из вышеперечисленных инструментов во Flask!
Для начала создайте новый каталог для нашего проекта, создайте и активируйте новую виртуальную среду и установите Flask вместе с Flask-Assets:
$ mkdir flask-htmx-tailwind && cd flask-htmx-tailwind
$ python3.10 -m venv venv
$ source venv/bin/activate
(venv)$
(venv)$ pip install Flask==2.1.1 Flask-Assets==2.0
Далее давайте установим pytailwindcss и загрузим его бинарник:
(venv)$ pip install pytailwindcss==0.1.4
(venv)$ tailwindcss
Затем добавьте файл app.py :
# app.py
from flask import Flask
from flask_assets import Bundle, Environment
app = Flask(__name__)
assets = Environment(app)
css = Bundle("src/main.css", output="dist/main.css")
assets.register("css", css)
css.build()
После импорта Bundle и Environment мы создали новый Environment
и зарегистрировали в нем наши активы CSS через файл Bundle
.
Созданный нами пакет принимает src/main.css в качестве входных данных, которые затем будут обработаны и выведены в dist/main.css при запуске интерфейса командной строки Tailwind CSS.
Поскольку все статические файлы Flask по умолчанию находятся в «статической» папке, вышеупомянутые папки «src» и «dist» находятся в «статической» папке.
Итак, давайте настроим Tailwind.
Начните с создания файла конфигурации Tailwind:
(venv)$ tailwindcss init
Эта команда создала файл tailwind.config.js в корне вашего проекта. Все настройки, связанные с Tailwind, находятся в этом файле.
Обновите tailwind.config.js следующим образом:
module.exports = {
content: [
'./templates/**/*.html',
],
theme: {
extend: {},
},
plugins: [],
}
Обратите внимание на раздел контента . Здесь вы настраиваете пути к HTML-шаблонам вашего проекта. Tailwind CSS просканирует ваши шаблоны в поисках имен классов Tailwind. Сгенерированный выходной файл CSS будет содержать только CSS для соответствующих имен классов, найденных в ваших файлах шаблонов. Это помогает уменьшить размер сгенерированных файлов CSS, поскольку они будут содержать только те стили, которые фактически используются.
Добавьте следующее в static/src/main.css :
/* static/src/main.css */
@tailwind base;
@tailwind components;
@tailwind utilities;
Здесь мы определили все классы base
, components
и utilities
из Tailwind CSS.
Теперь у вас есть подключенные Flask-Assets и Tailwind. Далее мы рассмотрим, как обслуживать файл index.html , чтобы увидеть CSS в действии.
Добавьте маршрут вместе с основным блоком для запуска сервера разработки Flask в app.py следующим образом:
# app.py
from flask import Flask, render_template
from flask_assets import Bundle, Environment
app = Flask(__name__)
assets = Environment(app)
css = Bundle("src/main.css", output="dist/main.css")
assets.register("css", css)
css.build()
@app.route("/")
def homepage():
return render_template("index.html")
if __name__ == "__main__":
app.run(debug=True)
Создайте папку «шаблоны». Затем добавьте к нему файл base.html :
<!-- templates/base.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
{% assets 'css' %}
<link rel="stylesheet" href="{{ ASSET_URL }}">
{% endassets %}
<title>Flask + htmlx + Tailwind CSS</title>
</head>
<body class="bg-blue-100">
{% block content %}
{% endblock content %}
</body>
</html>
Обратите внимание на {% assets 'css' %}
блок. Поскольку мы зарегистрировали пакет CSS в среде приложения, мы можем получить к нему доступ, используя зарегистрированное имя, css
и {{ ASSET_URL }}
автоматически будет использоваться путь.
Кроме того, мы добавили некоторый цвет в тело HTML с помощью bg-blue-100
, который меняет цвет фона на светло-голубой.
Добавьте файл index.html :
<!-- templates/index.html -->
{% extends "base.html" %}
{% block content %}
<h1>Hello World</h1>
{% endblock content %}
Теперь выполните следующую команду в корне проекта, чтобы отсканировать шаблоны на наличие классов и сгенерировать файл CSS:
(venv)$ tailwindcss -i ./static/src/main.css -o ./static/dist/main.css --minify
Вы должны увидеть новый каталог с именем «dist» внутри «статической» папки.
Обратите внимание на сгенерированный файл static/dist/main.css .
Запустите сервер разработки через python app.py
и перейдите по адресу http://localhost:5000 в браузере, чтобы увидеть результаты.
С настроенным Tailwind давайте добавим htmx и создадим живой поиск, который отображает результаты по мере ввода.
Вместо того, чтобы извлекать библиотеку htmx из CDN, давайте загрузим ее и используем Flask-Assets для ее объединения.
Загрузите библиотеку с https://unpkg.com/htmx.org@1.7.0/dist/htmx.js и сохраните ее в «static/src».
Теперь, чтобы создать новый пакет для наших файлов JavaScript, обновите app.py следующим образом:
# app.py
from flask import Flask, render_template
from flask_assets import Bundle, Environment
app = Flask(__name__)
assets = Environment(app)
css = Bundle("src/main.css", output="dist/main.css")
js = Bundle("src/*.js", output="dist/main.js") # new
assets.register("css", css)
assets.register("js", js) # new
css.build()
js.build() # new
@app.route("/")
def homepage():
return render_template("index.html")
if __name__ == "__main__":
app.run(debug=True)
Здесь мы создали новый пакет с именем js
, который выводит в static/dist/main.js . Поскольку здесь мы не используем никаких фильтров, исходный и целевой файлы будут одинаковыми.
Затем добавьте новый актив в наш файл base.html :
<!-- templates/base.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
{% assets 'css' %}
<link rel="stylesheet" href="{{ ASSET_URL }}">
{% endassets %}
<!-- new -->
{% assets 'js' %}
<script type="text/javascript" src="{{ ASSET_URL }}"></script>
{% endassets %}
<title>Flask + htmlx + Tailwind CSS</title>
</head>
<body class="bg-blue-100">
{% block content %}
{% endblock content %}
</body>
</html>
Чтобы у нас были данные для работы, сохраните https://github.com/testdrivenio/flask-htmx-tailwind/blob/master/todo.py в новый файл с именем todo.py.
Мы добавим возможность поиска по названию каждой задачи.
Обновите файл index.html следующим образом:
<!-- templates/index.html -->
{% extends 'base.html' %}
{% block content %}
<div class="w-small w-2/3 mx-auto py-10 text-gray-600">
<input
type="text"
name="search"
hx-post="/search"
hx-trigger="keyup changed delay:250ms"
hx-indicator=".htmx-indicator"
hx-target="#todo-results"
placeholder="Search"
class="bg-white h-10 px-5 pr-10 rounded-full text-2xl focus:outline-none"
>
<span class="htmx-indicator">Searching...</span>
</div>
<table class="border-collapse w-small w-2/3 mx-auto">
<thead>
<tr>
<th class="p-3 font-bold uppercase bg-gray-200 text-gray-600 border border-gray-300 hidden lg:table-cell">#</th>
<th class="p-3 font-bold uppercase bg-gray-200 text-gray-600 border border-gray-300 hidden lg:table-cell">Title</th>
<th class="p-3 font-bold uppercase bg-gray-200 text-gray-600 border border-gray-300 hidden lg:table-cell">Completed</th>
</tr>
</thead>
<tbody id="todo-results">
{% include 'todo.html' %}
</tbody>
</table>
{% endblock content %}
Давайте рассмотрим атрибуты, определенные в htmx:
<input
type="text"
name="search"
hx-post="/search"
hx-trigger="keyup changed delay:250ms"
hx-indicator=".htmx-indicator"
hx-target="#todo-results"
placeholder="Search"
class="bg-white h-10 px-5 pr-10 rounded-full text-2xl focus:outline-none"
>
/search
конечную точку.#todo-results
элементе.Добавьте файл templates/todo.html :
<!-- templates/todo.html -->
{% if todos|length>0 %}
{% for todo in todos %}
<tr class="bg-white lg:hover:bg-gray-100 flex lg:table-row flex-row lg:flex-row flex-wrap lg:flex-no-wrap mb-10 lg:mb-0">
<td class="w-full lg:w-auto p-3 text-gray-800 text-center border border-b block lg:table-cell relative lg:static">{{todo.id}}</td>
<td class="w-full lg:w-auto p-3 text-gray-800 text-center border border-b block lg:table-cell relative lg:static">{{todo.title}}</td>
<td class="w-full lg:w-auto p-3 text-gray-800 text-center border border-b block lg:table-cell relative lg:static">
{% if todo.completed %}
<span class="rounded bg-green-400 py-1 px-3 text-xs font-bold">Yes</span>
{% else %}
<span class="rounded bg-red-400 py-1 px-3 text-xs font-bold">No</span>
{% endif %}
</td>
</tr>
{% endfor %}
{% endif %}
Этот файл отображает задачи, соответствующие нашему поисковому запросу.
Наконец, добавьте обработчик маршрута в app.py :
@app.route("/search", methods=["POST"])
def search_todo():
search_term = request.form.get("search")
if not len(search_term):
return render_template("todo.html", todos=[])
res_todos = []
for todo in todos:
if search_term in todo["title"]:
res_todos.append(todo)
return render_template("todo.html", todos=res_todos)
Конечная /search
точка выполняет поиск задач и отображает шаблон todo.html со всеми результатами.
Обновите импорт вверху:
from flask import Flask, render_template, request
from flask_assets import Bundle, Environment
from todo import todos
Затем обновите выходной файл CSS:
(venv)$ tailwindcss -i ./static/src/main.css -o ./static/dist/main.css --minify
Запустите приложение с помощью python app.py
и снова перейдите по адресу http://localhost:5000 , чтобы проверить его:
В этом уроке мы рассмотрели, как:
htmx может отображать элементы без перезагрузки страницы. Самое главное, вы можете добиться этого без написания JavaScript. Хотя это уменьшает объем работы, необходимой на стороне клиента, данные, отправляемые с сервера, могут быть выше, поскольку он отправляет обработанный HTML.
Подобные частичные HTML-шаблоны были популярны в начале 2000-х годов. htmx предлагает современный подход к этому подходу. В целом, обслуживание частичных шаблонов снова становится популярным из-за сложности таких фреймворков, как React и Vue. Вы также можете добавить WebSockets для внесения изменений в реальном времени. Этот же подход используется в знаменитом Phoenix LiveView . Вы можете узнать больше о HTML поверх WebSockets в статье Будущее веб-программного обеспечения — это HTML поверх WebSockets и HTML поверх WebSockets .
Библиотека еще молода, но будущее у нее очень светлое.
Источник: https://testdriven.io
1657018860
В этом руководстве вы узнаете, как настроить Django с помощью htmx и Tailwind CSS . Цель как htmx, так и Tailwind — упростить современную веб-разработку, чтобы вы могли проектировать и обеспечивать интерактивность, не отказываясь от удобства и простоты HTML. Мы также рассмотрим, как использовать Django Compressor для объединения и минимизации статических ресурсов в приложении Django.
htmx — это библиотека, которая позволяет вам получать доступ к современным функциям браузера, таким как AJAX, переходы CSS, WebSockets и события, отправленные сервером, непосредственно из HTML, а не с помощью JavaScript. Он позволяет быстро создавать пользовательские интерфейсы непосредственно в разметке.
htmx расширяет несколько функций, уже встроенных в браузер, таких как выполнение HTTP-запросов и реагирование на события. Например, вместо того, чтобы делать запросы GET и POST только через элементы a
и form
, вы можете использовать атрибуты HTML для отправки запросов GET, POST, PUT, PATCH или DELETE для любого элемента HTML:
<button hx-delete="/user/1">Delete</button>
Вы также можете обновить части страницы, чтобы создать одностраничное приложение (SPA): ссылка CodePen
Откройте вкладку сети в инструментах разработчика браузера. При нажатии кнопки на конечную точку отправляется запрос XHR https://v2.jokeapi.dev/joke/Any?format=txt&safe-mode
. Затем ответ добавляется к p
элементу с id
выводом.
Дополнительные примеры см . на странице примеров пользовательского интерфейса в официальной документации htmx.
Плюсы :
Минусы :
Tailwind CSS — это CSS-фреймворк, ориентированный прежде всего на полезность. Вместо того, чтобы поставлять готовые компоненты (на которых специализируются такие фреймворки, как Bootstrap и Bulma ), он предоставляет строительные блоки в виде служебных классов, которые позволяют быстро и легко создавать макеты и проекты.
Например, возьмите следующий HTML и CSS:
<style>
.hello {
height: 5px;
width: 10px;
background: gray;
border-width: 1px;
border-radius: 3px;
padding: 5px;
}
</style>
<div class="hello">Hello World</div>
Это можно реализовать с помощью Tailwind следующим образом:
<div class="h-1 w-2 bg-gray-600 border rounded-sm p-1">Hello World</div>
Воспользуйтесь конвертером CSS Tailwind , чтобы преобразовать необработанный CSS в эквивалентные служебные классы в Tailwind. Сравните результаты.
Плюсы :
<div class="bg-white dark:bg-black">
.Минусы :
Django Compressor — это расширение, предназначенное для управления (сжатия/кэширования) статическими ресурсами в приложении Django. С его помощью вы создаете простой конвейер активов для:
Итак, давайте посмотрим, как работать с каждым из вышеперечисленных инструментов в Django!
Для начала создайте новую папку для нашего проекта, создайте и активируйте новую виртуальную среду и установите Django вместе с Django Compressor:
$ mkdir django-htmx-tailwind && cd django-htmx-tailwind
$ python3.10 -m venv venv
$ source venv/bin/activate
(venv)$
(venv)$ pip install Django==4.0.3 django-compressor==3.1
Далее давайте установим pytailwindcss и загрузим его бинарник:
(venv)$ pip install pytailwindcss==0.1.4
(venv)$ tailwindcss
Создайте новый проект Django и todos
приложение:
(venv)$ django-admin startproject config .
(venv)$ python manage.py startapp todos
Добавьте приложения в INSTALLED_APPS
список в config/settings.py :
# config/settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'todos', # new
'compressor', # new
]
Создайте папку «templates» в корне вашего проекта. Затем обновите TEMPLATES
настройки следующим образом:
# config/settings.py
TEMPLATES = [
{
...
'DIRS': [BASE_DIR / 'templates'], # new
...
},
]
Давайте добавим некоторую конфигурацию в config/settings.py для compressor
:
# config/settings.py
COMPRESS_ROOT = BASE_DIR / 'static'
COMPRESS_ENABLED = True
STATICFILES_FINDERS = ('compressor.finders.CompressorFinder',)
Заметки:
DEBUG
.django.contrib.staticfiles
установке.Инициализируйте Tailwind CSS в своем проекте:
(venv)$ tailwindcss init
Эта команда создала файл tailwind.config.js в корне вашего проекта. Все настройки, связанные с Tailwind, находятся в этом файле.
Обновите tailwind.config.js следующим образом:
module.exports = {
content: [
'./templates/**/*.html',
],
theme: {
extend: {},
},
plugins: [],
}
Обратите внимание на раздел контента . Здесь вы настраиваете пути к HTML-шаблонам вашего проекта. Tailwind CSS просканирует ваши шаблоны в поисках имен классов Tailwind. Сгенерированный выходной файл CSS будет содержать только CSS для соответствующих имен классов, найденных в ваших файлах шаблонов. Это помогает уменьшить размер сгенерированных файлов CSS, поскольку они будут содержать только те стили, которые фактически используются.
Далее в корне проекта создайте следующие файлы и папки:
static
└── src
└── main.css
Затем добавьте в static/src/main.css следующее :
/* static/src/main.css */
@tailwind base;
@tailwind components;
@tailwind utilities;
Здесь мы определили все классы base
, components
и utilities
из Tailwind CSS.
Вот и все. Теперь у вас подключены Django Compressor и Tailwind. Далее мы рассмотрим, как обслуживать файл index.html , чтобы увидеть CSS в действии.
Обновите файл todos/views.py следующим образом:
# todos/views.py
from django.shortcuts import render
def index(request):
return render(request, 'index.html')
Добавьте представление в todos/urls.py :
# todos/urls.py
from django.urls import path
from .views import index
urlpatterns = [
path('', index, name='index'),
]
Затем добавьте todos.urls
в config/urls.py :
# config/urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('todos.urls')), # new
]
Добавьте файл _base.html в «шаблоны»:
<!-- templates/_base.html -->
{% load compress %}
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Django + HTMX + Tailwind CSS</title>
{% compress css %}
<link rel="stylesheet" href="{% static 'src/output.css' %}">
{% endcompress %}
</head>
<body class="bg-blue-100">
{% block content %}
{% endblock content %}
</body>
</html>
Заметки:
{% load compress %}
импортирует все необходимые теги для работы с Django Compressor.{% load static %}
загружает статические файлы в шаблон.{% compress css %}
применяет соответствующие фильтры к файлу static/src/main.css .Кроме того, мы добавили немного цвета в тело HTML с помощью <body class="bg-blue-100">
. bg-blue-100
используется для изменения цвета фона на голубой.
Добавьте файл index.html :
<!-- templates/index.html -->
{% extends "_base.html" %}
{% block content %}
<h1>Hello World</h1>
{% endblock content %}
Теперь выполните следующую команду в корне проекта, чтобы отсканировать шаблоны на наличие классов и сгенерировать файл CSS:
(venv)$ tailwindcss -i ./static/src/main.css -o ./static/src/output.css --minify
Примените миграции и запустите сервер разработки:
(venv)$ python manage.py migrate
(venv)$ python manage.py runserver
Перейдите по адресу http://localhost:8000 в браузере, чтобы увидеть результаты. Также обратите внимание на сгенерированный файл в папке «static/CACHE/css».
С настроенным Tailwind давайте добавим htmx и создадим живой поиск, который отображает результаты по мере ввода.
Вместо того, чтобы извлекать библиотеку htmx из CDN, давайте загрузим ее и используем Django Compressor для ее сборки.
Загрузите библиотеку с https://unpkg.com/htmx.org@1.7.0/dist/htmx.js и сохраните ее в static/src/htmx.js .
Чтобы у нас были данные для работы, сохраните https://github.com/testdrivenio/django-htmx-tailwind/blob/master/todos/todo.py в новый файл с именем todos/todo.py .
Теперь добавьте представление для реализации функции поиска в todos/views.py :
# todos/views.py
from django.shortcuts import render
from django.views.decorators.http import require_http_methods # new
from .todo import todos # new
def index(request):
return render(request, 'index.html', {'todos': []}) # modified
# new
@require_http_methods(['POST'])
def search(request):
res_todos = []
search = request.POST['search']
if len(search) == 0:
return render(request, 'todo.html', {'todos': []})
for i in todos:
if search in i['title']:
res_todos.append(i)
return render(request, 'todo.html', {'todos': res_todos})
Мы добавили новое представление, search
которое ищет задачи и отображает шаблон todo.html со всеми результатами.
Добавьте только что созданное представление в todos/urls.py :
# todos/urls.py
from django.urls import path
from .views import index, search # modified
urlpatterns = [
path('', index, name='index'),
path('search/', search, name='search'), # new
]
Затем добавьте новый ресурс в файл _base.html :
<!-- templates/base.html -->
{% load compress %}
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Django + HTMX + Tailwind CSS</title>
{% compress css %}
<link rel="stylesheet" href="{% static 'src/output.css' %}">
{% endcompress %}
</head>
<body class="bg-blue-100">
{% block content %}
{% endblock content %}
<!-- new -->
{% compress js %}
<script type="text/javascript" src="{% static 'src/htmx.js' %}"></script>
{% endcompress %}
<!-- new -->
<script>
document.body.addEventListener('htmx:configRequest', (event) => {
event.detail.headers['X-CSRFToken'] = '{{ csrf_token }}';
})
</script>
</body>
</html>
Мы загрузили библиотеку htmx с помощью {% compress js %}
тега. Тег js
по умолчанию применяется JSMinFilter
(который, в свою очередь, применяет rjsmin ). Таким образом, это минимизирует static/src/htmx.js и будет обслуживать его из папки «static/CACHE».
Мы также добавили следующий скрипт:
document.body.addEventListener('htmx:configRequest', (event) => {
event.detail.headers['X-CSRFToken'] = '{{ csrf_token }}';
})
Этот прослушиватель событий добавляет токен CSRF в заголовок запроса.
Далее давайте добавим возможность поиска по названию каждой задачи.
Обновите файл index.html следующим образом:
<!-- templates/index.html -->
{% extends "_base.html" %}
{% block content %}
<div class="w-small w-2/3 mx-auto py-10 text-gray-600">
<input
type="text"
name="search"
hx-post="/search/"
hx-trigger="keyup changed delay:250ms"
hx-indicator=".htmx-indicator"
hx-target="#todo-results"
placeholder="Search"
class="bg-white h-10 px-5 pr-10 rounded-full text-2xl focus:outline-none"
>
<span class="htmx-indicator">Searching...</span>
</div>
<table class="border-collapse w-small w-2/3 mx-auto">
<thead>
<tr>
<th class="p-3 font-bold uppercase bg-gray-200 text-gray-600 border border-gray-300 hidden lg:table-cell">#</th>
<th class="p-3 font-bold uppercase bg-gray-200 text-gray-600 border border-gray-300 hidden lg:table-cell">Title</th>
<th class="p-3 font-bold uppercase bg-gray-200 text-gray-600 border border-gray-300 hidden lg:table-cell">Completed</th>
</tr>
</thead>
<tbody id="todo-results">
{% include "todo.html" %}
</tbody>
</table>
{% endblock content %}
Давайте рассмотрим атрибуты, определенные в htmx:
<input
type="text"
name="search"
hx-post="/search/"
hx-trigger="keyup changed delay:250ms"
hx-indicator=".htmx-indicator"
hx-target="#todo-results"
placeholder="Search"
class="bg-white h-10 px-5 pr-10 rounded-full text-2xl focus:outline-none"
>
/search
конечную точку.#todo-results
элементе.Добавьте файл templates/todo.html :
<!-- templates/todo.html -->
{% for todo in todos %}
<tr
class="bg-white lg:hover:bg-gray-100 flex lg:table-row flex-row lg:flex-row flex-wrap lg:flex-no-wrap mb-10 lg:mb-0">
<td class="w-full lg:w-auto p-3 text-gray-800 text-center border border-b block lg:table-cell relative lg:static">
{{todo.id}}
</td>
<td class="w-full lg:w-auto p-3 text-gray-800 text-center border border-b block lg:table-cell relative lg:static">
{{todo.title}}
</td>
<td class="w-full lg:w-auto p-3 text-gray-800 text-center border border-b block lg:table-cell relative lg:static">
{% if todo.completed %}
<span class="rounded bg-green-400 py-1 px-3 text-xs font-bold">Yes</span>
{% else %}
<span class="rounded bg-red-400 py-1 px-3 text-xs font-bold">No</span>
{% endif %}
</td>
</tr>
{% endfor %}
Этот файл отображает задачи, соответствующие нашему поисковому запросу.
Создайте новый файл src/output.css :
(venv)$ tailwindcss -i ./static/src/main.css -o ./static/src/output.css --minify
Запустите приложение с помощью python manage.py runserver
и снова перейдите по адресу http://localhost:8000 , чтобы проверить его.
В этом уроке мы рассмотрели, как:
htmx может отображать элементы без перезагрузки страницы. Самое главное, вы можете добиться этого без написания JavaScript. Хотя это уменьшает объем работы, необходимой на стороне клиента, данные, отправляемые с сервера, могут быть выше, поскольку он отправляет обработанный HTML.
Подобные частичные HTML-шаблоны были популярны в начале 2000-х годов. htmx предлагает современный подход к этому подходу. В целом, обслуживание частичных шаблонов снова становится популярным из-за сложности таких фреймворков, как React и Vue. Вы также можете добавить WebSockets для внесения изменений в реальном времени. Этот же подход используется в знаменитом Phoenix LiveView . Вы можете узнать больше о HTML поверх WebSockets в статье Будущее веб-программного обеспечения — это HTML поверх WebSockets и HTML поверх WebSockets .
Библиотека еще молода, но будущее у нее очень светлое.
Tailwind — это мощная CSS-инфраструктура, ориентированная на продуктивность разработчиков. Хотя это руководство не затрагивало этого, Tailwind легко настраивается.
При использовании Django обязательно соедините htmx и Tailwind с Django Compressor, чтобы упростить управление статическими активами.
Полный код можно найти в репозитории django-htmx-tailwind .
Источник: https://testdriven.io
1596530868
Want to develop a website or re-design using CSS Development?
We build a website and we implemented CSS successfully if you are planning to Hire CSS Developer from HourlyDeveloper.io, We can fill your Page with creative colors and attractive Designs. We provide services in Web Designing, Website Redesigning and etc.
For more details…!!
Consult with our experts:- https://bit.ly/3hUdppS
#hire css developer #css development company #css development services #css development #css developer #css
1602955151
In this tutorial I would like to introduce you to one of the fastest growing and promising CSS Frameworks at the moment, Tailwind CSS. It is different from other frameworks, such as Bootstrap, because it is built on a new way of building user interfaces using a utility-first CSS classes structure, as opposed to the OOCSS structure from other frameworks.
By the end of this guide you will be able to install, configure and build a responsive hero section (live demo) using the utility-first classes from Tailwind CSS and configure the project using the recommended PostCSS powered Tailwind configuration file for better maintainability and versatility.
Here’s the table of contents for this tutorial for Tailwind CSS:
Read the full tutorial from Themesberg.
#tailwind #tailwind-css #tailwind-css-tutorial #tutorial #open-source
1604404836
By reading this article you will browse a list of the most popular plugins and extensions for the utility-first CSS framework, Tailwind CSS. Although the default code base of the framework already covers a lot of the needs when building user interfaces, you can never get enough plugins and extensions powered by the open-source community.
One of the requirements for a plugin to appear on this list is to be open-source with no other strings attached so that the developers browsing this list can stay assured that they can use the plugin for their Tailwind CSS powered project.
Check out the list of Tailwind CSS Plugins and Extensions on Themesberg.
#tailwindcss #tailwind #tailwind-css #tailwind-css-plugins #themesberg