Структура проекта сайта на Flask. Готовый шаблон HTML + CSS + JS
Во flask-приложениях файлы .css, .js и ряд других принято хранить в каталоге static, который создается на том же уровне, что temlates. В static в случае необходимости вы можете создать свою иерархию подкаталогов, в том числе папку для картинок.
Обращение к этим файлам из html-кода шаблонов может выглядеть так:
<link rel="shortcut icon" href="/static/images/favicon.svg"> <link rel="stylesheet" href="{{ url_for('static', filename= 'css/style.css') }}"> <script src="/static/script.js"></script>
Обращение с помощью url_for
считается предпочтительным. Так как если вы измените в главном файле проекта фактическое местоположение static
и название, не придется менять html-код.
Рассмотрим вариант сайта на Flask без базы данных с адаптивным дизайном веб-страниц, то есть файлами css и js.
Вид сайта на широких экранах:
Структура приложения:
В данном случае изображения для статей хранятся в отдельном каталоге images, который вынесен из static. В html-файлах путь к картинкам будет выглядеть как /images/имя_файла.
Чтобы Flask-приложение находило файлы по какому-либо адресу, мы должны соотнести его с нужным каталогом. Сделать это можно с помощью функции send_from_directory
, которую предварительно импортируют из модуля flask
.
@app.route('/images/<img>') def load_img(img): return send_from_directory('images', img)
Функция send_from_directory()
выдает файл из указанного каталога. Вместо имени файла может быть путь. Так если в images есть подкаталоги, а ссылки на картинки в статьях выглядят подобно /images/section_name/file_name, то декоратор для функции-представления будет таким:
@app.route('/images/<path:img>')
Данный вариант работает и для случая без подкаталогов.
Обратим внимание, что имя каталога не обязательно должно совпадать с указанным в адресе. Так на диске может быть каталог pictures, а в адресе использоваться images:
@app.route('/images/<path:img>') def load_img(img): return send_from_directory('pictures', img)
Для картинок в статьях можно использовать не статический адрес вроде
<img src="/images/tree_bush_grass.jpg" ...
, а функцию url_for
:
<img src="{{ url_for('load_img', img='tree_bush_grass.jpg') }}" ...
Такой способ позволит менять часть адреса (в данном случае images) в декораторе на любое другое слово без необходимости вносить изменения в html-шаблоны. Однако, при рендере готовых html-файлов, адрес картинок в них будет также измененным. Это может плохо сказаться на поиске по картинкам со стороны поисковых систем.
Файлы с инструкциями и информацией для поисковых систем и иных сторонних сервисов, такие как robots.txt, sitemap.xml, должны открываться по пути корневого каталога сайта, то есть сразу через слэш после имени домена. В представленной схеме проекта выше для таких файлов был создан каталог service. В коде проекта для их передачи также используем функцию send_from_directory
:
@app.route('/sitemap.xml') @app.route('/robots.txt') @app.route('/google0123456789.html') # удалите или поменяйте на ваш @app.route('/yandex_0123456789.html') # удалите или поменяйте на ваш def service_files(): return send_from_directory('service', request.path[1:])
Представление service_file()
вызывается, когда идет обращение по любому адресу, который указан в декораторах. Функции send_from_directory()
передается имя каталога, где эти файлы надо искать. Имя файла определяется атрибутом path
объекта request
(импортируется из flask
); path
возвращает в виде строки путь (адрес без домена), переданный из адресной строки браузера. Так как первым символом этой строки является слэш, избавляемся от него с помощью взятия среза.