Как настроить Flask с помощью htmx и Tailwind CSS

В этом руководстве вы узнаете, как настроить Flask с помощью htmx и Tailwind CSS . Цель как htmx, так и Tailwind — упростить современную веб-разработку, чтобы вы могли проектировать и обеспечивать интерактивность, не отказываясь от удобства и простоты HTML. Мы также рассмотрим, как использовать Flask-Assets для объединения и минимизации статических ресурсов в приложении Flask.

htmx

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.

Плюсы и минусы

Плюсы :

  1. Продуктивность разработчиков : вы можете создавать современные пользовательские интерфейсы, не затрагивая JavaScript. Чтобы узнать больше об этом, ознакомьтесь с альтернативой SPA .
  2. Упаковывает удар : сама библиотека небольшая (~ 10 000 мин. gz'd), свободная от зависимостей и расширяемая .

Минусы :

  1. Зрелость библиотеки : Поскольку библиотека довольно новая, документация и примеры реализации скудны.
  2. Размер передаваемых данных . Как правило, фреймворки SPA (например, React и Vue) работают, передавая данные между клиентом и сервером в формате JSON. Полученные данные затем обрабатываются клиентом. htmx, с другой стороны, получает отрендеренный HTML-код с сервера и заменяет целевой элемент ответом. HTML-код в отображаемом формате обычно больше по размеру, чем ответ JSON.

Попутный ветер CSS

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. Сравните результаты.

Плюсы и минусы

Плюсы :

  1. Широкие возможности настройки : хотя Tailwind поставляется с готовыми классами, их можно перезаписать с помощью файла tailwind.config.js .
  2. Оптимизация : вы можете настроить Tailwind для оптимизации вывода CSS, загружая только те классы, которые фактически используются.
  3. Темный режим : реализовать темный режим несложно — например, <div class="bg-white dark:bg-black">.

Минусы :

  1. Компоненты : Tailwind не предоставляет каких-либо официальных готовых компонентов, таких как кнопки, карточки, панели навигации и т. д. Компоненты должны быть созданы с нуля. Существует несколько управляемых сообществом ресурсов для таких компонентов, как Tailwind CSS Components и Tailwind Toolbox , и это лишь некоторые из них. Также есть мощная, хотя и платная, библиотека компонентов от создателей Tailwind под названием Tailwind UI .
  2. Встроенный CSS : он объединяет контент и дизайн, что увеличивает размер страницы и загромождает HTML.

Flask-активы

Flask-Assets — это расширение, предназначенное для управления статическими активами в приложении Flask. С его помощью вы создаете простой конвейер активов для:

  1. Компиляция Sass и LESS в таблицы стилей CSS
  2. Объединение и минимизация нескольких файлов CSS и JavaScript в один файл для каждого
  3. Создание пакетов ресурсов для использования в ваших шаблонах

Итак, давайте посмотрим, как работать с каждым из вышеперечисленных инструментов во 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"
>
  1. Вход отправляет запрос POST в /searchконечную точку.
  2. Запрос запускается через событие keyup с задержкой 250 мс. Таким образом, если новое событие нажатия клавиши вводится до истечения 250 мс после последнего нажатия клавиши, запрос не запускается.
  3. Затем HTML-ответ на запрос отображается в #todo-resultsэлементе.
  4. У нас также есть индикатор, элемент загрузки, который появляется после отправки запроса и исчезает после возврата ответа.

Добавьте файл 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 , чтобы проверить его:

демо

Вывод

В этом уроке мы рассмотрели, как:

  • Настройте Flask-Assets, htmx и Tailwind CSS
  • Создайте приложение для поиска в реальном времени, используя Flask, Tailwind CSS и htmx.

htmx может отображать элементы без перезагрузки страницы. Самое главное, вы можете добиться этого без написания JavaScript. Хотя это уменьшает объем работы, необходимой на стороне клиента, данные, отправляемые с сервера, могут быть выше, поскольку он отправляет обработанный HTML.

Подобные частичные HTML-шаблоны были популярны в начале 2000-х годов. htmx предлагает современный подход к этому подходу. В целом, обслуживание частичных шаблонов снова становится популярным из-за сложности таких фреймворков, как React и Vue. Вы также можете добавить WebSockets для внесения изменений в реальном времени. Этот же подход используется в знаменитом Phoenix LiveView . Вы можете узнать больше о HTML поверх WebSockets в статье Будущее веб-программного обеспечения — это HTML поверх WebSockets и HTML поверх WebSockets .

Библиотека еще молода, но будущее у нее очень светлое.

Источник:  https://testdriven.io

#flask #htmx #tailwindcss 

What is GEEK

Buddha Community

Как настроить Flask с помощью htmx и Tailwind CSS

Как настроить Flask с помощью htmx и Tailwind CSS

В этом руководстве вы узнаете, как настроить Flask с помощью htmx и Tailwind CSS . Цель как htmx, так и Tailwind — упростить современную веб-разработку, чтобы вы могли проектировать и обеспечивать интерактивность, не отказываясь от удобства и простоты HTML. Мы также рассмотрим, как использовать Flask-Assets для объединения и минимизации статических ресурсов в приложении Flask.

htmx

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.

Плюсы и минусы

Плюсы :

  1. Продуктивность разработчиков : вы можете создавать современные пользовательские интерфейсы, не затрагивая JavaScript. Чтобы узнать больше об этом, ознакомьтесь с альтернативой SPA .
  2. Упаковывает удар : сама библиотека небольшая (~ 10 000 мин. gz'd), свободная от зависимостей и расширяемая .

Минусы :

  1. Зрелость библиотеки : Поскольку библиотека довольно новая, документация и примеры реализации скудны.
  2. Размер передаваемых данных . Как правило, фреймворки SPA (например, React и Vue) работают, передавая данные между клиентом и сервером в формате JSON. Полученные данные затем обрабатываются клиентом. htmx, с другой стороны, получает отрендеренный HTML-код с сервера и заменяет целевой элемент ответом. HTML-код в отображаемом формате обычно больше по размеру, чем ответ JSON.

Попутный ветер CSS

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. Сравните результаты.

Плюсы и минусы

Плюсы :

  1. Широкие возможности настройки : хотя Tailwind поставляется с готовыми классами, их можно перезаписать с помощью файла tailwind.config.js .
  2. Оптимизация : вы можете настроить Tailwind для оптимизации вывода CSS, загружая только те классы, которые фактически используются.
  3. Темный режим : реализовать темный режим несложно — например, <div class="bg-white dark:bg-black">.

Минусы :

  1. Компоненты : Tailwind не предоставляет каких-либо официальных готовых компонентов, таких как кнопки, карточки, панели навигации и т. д. Компоненты должны быть созданы с нуля. Существует несколько управляемых сообществом ресурсов для таких компонентов, как Tailwind CSS Components и Tailwind Toolbox , и это лишь некоторые из них. Также есть мощная, хотя и платная, библиотека компонентов от создателей Tailwind под названием Tailwind UI .
  2. Встроенный CSS : он объединяет контент и дизайн, что увеличивает размер страницы и загромождает HTML.

Flask-активы

Flask-Assets — это расширение, предназначенное для управления статическими активами в приложении Flask. С его помощью вы создаете простой конвейер активов для:

  1. Компиляция Sass и LESS в таблицы стилей CSS
  2. Объединение и минимизация нескольких файлов CSS и JavaScript в один файл для каждого
  3. Создание пакетов ресурсов для использования в ваших шаблонах

Итак, давайте посмотрим, как работать с каждым из вышеперечисленных инструментов во 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"
>
  1. Вход отправляет запрос POST в /searchконечную точку.
  2. Запрос запускается через событие keyup с задержкой 250 мс. Таким образом, если новое событие нажатия клавиши вводится до истечения 250 мс после последнего нажатия клавиши, запрос не запускается.
  3. Затем HTML-ответ на запрос отображается в #todo-resultsэлементе.
  4. У нас также есть индикатор, элемент загрузки, который появляется после отправки запроса и исчезает после возврата ответа.

Добавьте файл 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 , чтобы проверить его:

демо

Вывод

В этом уроке мы рассмотрели, как:

  • Настройте Flask-Assets, htmx и Tailwind CSS
  • Создайте приложение для поиска в реальном времени, используя Flask, Tailwind CSS и htmx.

htmx может отображать элементы без перезагрузки страницы. Самое главное, вы можете добиться этого без написания JavaScript. Хотя это уменьшает объем работы, необходимой на стороне клиента, данные, отправляемые с сервера, могут быть выше, поскольку он отправляет обработанный HTML.

Подобные частичные HTML-шаблоны были популярны в начале 2000-х годов. htmx предлагает современный подход к этому подходу. В целом, обслуживание частичных шаблонов снова становится популярным из-за сложности таких фреймворков, как React и Vue. Вы также можете добавить WebSockets для внесения изменений в реальном времени. Этот же подход используется в знаменитом Phoenix LiveView . Вы можете узнать больше о HTML поверх WebSockets в статье Будущее веб-программного обеспечения — это HTML поверх WebSockets и HTML поверх WebSockets .

Библиотека еще молода, но будущее у нее очень светлое.

Источник:  https://testdriven.io

#flask #htmx #tailwindcss 

Как настроить Django с помощью htmx и Tailwind CSS

В этом руководстве вы узнаете, как настроить Django с помощью htmx и Tailwind CSS . Цель как htmx, так и Tailwind — упростить современную веб-разработку, чтобы вы могли проектировать и обеспечивать интерактивность, не отказываясь от удобства и простоты HTML. Мы также рассмотрим, как использовать Django Compressor для объединения и минимизации статических ресурсов в приложении Django.

htmx

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.

Плюсы и минусы

Плюсы :

  1. Продуктивность разработчиков : вы можете создавать современные пользовательские интерфейсы, не затрагивая JavaScript. Чтобы узнать больше об этом, ознакомьтесь с альтернативой SPA .
  2. Упаковывает удар : сама библиотека небольшая (~ 10 000 мин. gz'd), свободная от зависимостей и расширяемая .

Минусы :

  1. Зрелость библиотеки : Поскольку библиотека довольно новая, документация и примеры реализации скудны.
  2. Размер передаваемых данных . Как правило, фреймворки SPA (например, React и Vue) работают, передавая данные между клиентом и сервером в формате JSON. Полученные данные затем обрабатываются клиентом. htmx, с другой стороны, получает обработанный HTML-код с сервера и заменяет целевой элемент ответом. HTML-код в отображаемом формате обычно больше по размеру, чем ответ JSON.

Попутный ветер CSS

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. Сравните результаты.

Плюсы и минусы

Плюсы :

  1. Широкие возможности настройки : хотя Tailwind поставляется с готовыми классами, их можно перезаписать с помощью файла tailwind.config.js .
  2. Оптимизация : вы можете настроить Tailwind для оптимизации вывода CSS, загружая только те классы, которые фактически используются.
  3. Темный режим : реализовать темный режим несложно — например, <div class="bg-white dark:bg-black">.

Минусы :

  1. Компоненты : Tailwind не предоставляет каких-либо официальных готовых компонентов, таких как кнопки, карточки, панели навигации и т. д. Компоненты должны быть созданы с нуля. Существует несколько управляемых сообществом ресурсов для таких компонентов, как Tailwind CSS Components и Tailwind Toolbox , и это лишь некоторые из них. Также есть мощная, хотя и платная, библиотека компонентов от создателей Tailwind под названием Tailwind UI .
  2. Встроенный CSS : он объединяет контент и дизайн, что увеличивает размер страницы и загромождает HTML.

Джанго Компрессор

Django Compressor — это расширение, предназначенное для управления (сжатия/кэширования) статическими ресурсами в приложении Django. С его помощью вы создаете простой конвейер активов для:

  1. Компиляция Sass и LESS в таблицы стилей CSS
  2. Объединение и минимизация нескольких файлов CSS и JavaScript в один файл для каждого
  3. Создание пакетов ресурсов для использования в ваших шаблонах

Итак, давайте посмотрим, как работать с каждым из вышеперечисленных инструментов в 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',)

Заметки:

  1. COMPRESS_ROOT определяет абсолютное местоположение, откуда считываются сжимаемые файлы и куда записываются сжатые файлы.
  2. COMPRESS_ENABLED логическое значение, определяющее, будет ли происходить сжатие. По умолчанию используется значение, противоположное DEBUG.
  3. STATICFILES_FINDERS должен включать средство поиска файлов Django Compressor при 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>

Заметки:

  1. {% load compress %}импортирует все необходимые теги для работы с Django Compressor.
  2. {% load static %}загружает статические файлы в шаблон.
  3. {% 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"
>
  1. Вход отправляет запрос POST в /searchконечную точку.
  2. Запрос запускается через событие keyup с задержкой 250 мс. Таким образом, если новое событие нажатия клавиши вводится до истечения 250 мс после последнего нажатия клавиши, запрос не запускается.
  3. Затем HTML-ответ на запрос отображается в #todo-resultsэлементе.
  4. У нас также есть индикатор, элемент загрузки, который появляется после отправки запроса и исчезает после возврата ответа.

Добавьте файл 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 , чтобы проверить его.

демо

Вывод

В этом уроке мы рассмотрели, как:

  • Настройте Django Compressor и Tailwind CSS
  • Создайте приложение для поиска в реальном времени, используя Django, Tailwind CSS и htmx.

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

#django #htmx #tailwindcss 

Hire CSS Developer

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

Tailwind CSS tutorial

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:

  • Introducing Tailwind CSS
  • Adding Tailwind CSS to your project via a package manager
  • Creating the configuration file and process your CSS with Tailwind
  • Building a responsive hero section using the utility-first classes from Tailwind
  • Customize fonts, colors and add extra classes using the configuration file
  • Reduce loading time and file size by purging the unused classes from your CSS
  • Conclusion and summary

Read the full tutorial from Themesberg.

#tailwind #tailwind-css #tailwind-css-tutorial #tutorial #open-source

Popular Tailwind CSS Plugins and Extensions - Themesberg Blog

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