🐍🥤 Flask за час. Часть 1: создаем адаптивный сайт для GitHub Pages
Изучаем основные принципы работы фреймворка, разрабатывая личный сайт с резюме, портфолио, блогом и контактной формой.
Flask – микрофреймворк: это означает, что в стандартную поставку входит только самое необходимое, а все остальное при необходимости легко подключается. Поэтому приставка «микро» не должна вводить в заблуждение – при желании на Flask можно реализовать серьезный, масштабируемый проект. А для реализации таких небольших веб-приложений, как наш сайт, Flask подходит как нельзя лучше.
Обзор проекта
Готовый сайт находится здесь. У сайта несколько секций:
- Главная
- Резюме
- Портфолио
- Блог
- Контакты
Переключение между секциями создает иллюзию многостраничности, но в «живой» версии сайт – одностраничный. Бэкенд включает в себя модуль Frozen Flask, который превращает приложение в генератор статических сайтов (SSG): все страницы, необходимые для адекватного представления сайта в статической версии, создаются автоматически.
Фронтенд сделан на Bootstrap с несколькими дополнительными JS скриптами – например, записи в блоге фильтруются (без перезагрузки страницы) по тегам с помощью скрипта isotope.js
, при этом теги для фильтра скрипт получает из расширения Flask – FlatPages. Записи в блоге и карточки в портфолио можно перелистывать свайпом, без перезагрузки страницы. Bootstrap обеспечивает адаптивность: сайт одинаково хорошо смотрится на широкоформатном мониторе и на смартфоне.
Первый этап
На этом этапе мы установим Flask вместе со всеми нужными расширениями и зависимостями, напишем первый вариант кода для блога и сделаем два простейших шаблона.
Установка Flask
Сначала нужно создать папку для проекта и активировать виртуальное окружение:
Папка .venv – служебная: менеджер pipenv автоматически разместит все нужные зависимости там, и они не будут загромождать корневую директорию проекта. Виртуальное окружение активируется командой pipenv shell
, для выхода нужно выполнить exit
.
Установим Flask и все необходимые зависимости. Для этого сохраните этот список в файле requirements.txt:
Поместите файл в директорию проекта и выполните команду:
Для быстрого знакомства с принципами работы Flask мы сначала создадим тестовый блог, а затем перейдем к реализации нашего проекта.
Структура Flask проекта
Начнем с создания структуры проекта:
В папке content/posts будут размещаться Markdown файлы, в templates – шаблоны, в static – CSS стили, изображения и JS-скрипты. Весь код приложения мы напишем в файле mysite.py – сначала импортируем нужные модули, затем определим основные параметры, после пропишем маршруты к шаблонам и запустим сервер. Простейший вариант кода mysite.py выглядит так:
В это трудно поверить, но основной код блога действительно занимает всего 28 строк. Это возможно благодаря модулям FlatPages и Flask Frozen: первый избавляет от необходимости хранить посты в базе данных, проводит рендеринг Markdown-файлов в html, обеспечивает вывод записей и обращение к их свойствам, что будет заметно при создании шаблонов. Flask Frozen в действии мы увидим чуть позже: этот модуль берет на себя создание статической копии сайта – экспортирует html-файлы и все нужные ассеты (скрипты, CSS, изображения) в папку build.
Добавим в папку posts два-три тестовых поста – в YAML части обязательно должны быть метаданные title, date, description, потому что Jinja будет вызывать их в шаблонах. Markdown посты можно писать в любом редакторе – хоть в Блокноте, хоть в Sublime Text; можно обзавестись и специальным редактором – MarkdownPad для Windows, Mou для macOS.
Теперь создадим два простейших шаблона. Это код для index.html:
А это шаблон для вывода записи на отдельной странице post.html:
Оба шаблона мы доработаем на следующем этапе, а пока запустим приложение python mysite.py
и посмотрим на результат.
Весь код и тестовый контент для этого этапа есть здесь.
Второй этап
На этом этапе мы сделаем первые шаблоны и подключим файл с настройками.
Шаблонизатор Jinja2
Flask использует шаблонизатор Jinja2. Синтаксис Jinja2 идентичен шаблонизатору Django и напоминает Python. Если вам еще не приходилось работать с Django, на этом этапе достаточно знать, что логика в Jinja2 заключается в такие фигурные скобки {% %}
, а переменные – в такие {{ }}
.
Шаблон Jinja2 представляет собой обычный html-файл, в котором блоки с логикой и переменными размещаются в уже упомянутых скобках. К шаблону можно подключать любые JS-скрипты, иконки, шрифты. Большое количество переменных можно передать в шаблон в виде словаря:
В шаблоне index.html, в свою очередь, эти переменные можно вставить в нужные теги:
Если же переменных очень много, имеет смысл вынести словарь в отдельный файл – в дальнейшем мы воспользуемся именно этим вариантом.
Jinja2 поддерживает наследование и включение шаблонов – это позволяет разбить шаблон объемной страницы на несколько секций, которые проще редактировать по отдельности. Наш сайт состоит из одной страницы с несколькими разделами, которые целесообразно вынести в отдельные шаблоны:
- base.html
- index.html
- header.html
- resume.html
- counters.html
- skills.html
- interests.html
- portfolio.html
- card.html
- blog.html
- post.html
- contacts.html
Jinja2 не диктует каких-то жестких правил: при желании можно обойтись всего двумя шаблонами – index.html и post.html. И, конечно, можно не выносить переменные в отдельный файл, а вписать весь текст резюме и портфолио прямо в index.html. Но поддерживать сайт проще, если хранить всю потенциально изменяемую информацию в Markdown-файлах и текстовом файле конфигурации – в этом случае для изменения данных нужно будет внести поправки только один раз: переменные в шаблонах обеспечат обновление текста во всех разделах сайта. Кроме того, ненужные разделы сайта очень просто удалить, если они находятся в отдельных шаблонах.
Первый шаблон, который мы создадим – base.html. Он будет получать переменные из бэкенда. Для передачи данных в шаблон создайте файл settings.txt и сохраните в нем словарь:
Теперь добавьте импорт json
и загрузку данных из файла в mysite.py:
Сохраните этот код в templates/base.html:
А этот – в templates/index.html:
Сохраните в папке static все эти ассеты. Теперь можно запускать сервер python mysite.py
– скелет сайта готов:
Перейдем к созданию первого шаблона, расширяющего index.html – header.html. Добавьте переменные в файл settings.txt:
И отредактируйте файл index.html – теперь он будет включать в себя header.html с помощью include
:
Перезагрузите страницу:
Весь код и контент для этого этапа – здесь. Во второй части туториала мы завершим работу над приложением и загрузим статическую копию сайта на GitHub Pages.