Фронтенд

Этот этап будет разделен на мелкие под этапы:

  1. html
  2. css
  3. javascript

Эти под-этапы в свою очередь будут разделены на теоретические и практические части.

HTML

Теория

html или язык гипертекстовой разметки - надмножество xml.

Во всемирной паутине HTML-страницы, как правило, передаются браузерам от сервера по протоколам HTTP или HTTPS, в виде простого текста или с использованием шифрования.

На данный момент последней версией html является HTML5

HTML — теговый язык разметки документов. Любой документ на языке HTML представляет собой набор элементов, причём начало и конец каждого элемента обозначается специальными пометками — тегами. Элементы могут быть пустыми, то есть не содержащими никакого текста и других данных. В этом случае обычно не указывается закрывающий тег (например, тег переноса строки <br> — одиночный и закрывать его не нужно) . Кроме того, элементы могут иметь атрибуты, определяющие какие-либо их свойства (например, атрибут href=” у ссылки). Атрибуты указываются в открывающем теге. Вот примеры фрагментов HTML-документа:

Регистр, в котором набрано имя элемента и имена атрибутов, в HTML значения не имеет. Элементы могут быть вложенными. Например, следующий код:

<!DOCTYPE html>
<html>
   <head>
      <meta charset="utf-8" />
      <title>HTML Document</title>
   </head>
   <body>
      <p>
         <b>
            Этот текст будет полужирным, <i>а этот — ещё и курсивным</i>.
         </b>
      </p>
   </body>
</html>

Каждый HTML-документ, отвечающий спецификации HTML какой-либо версии, должен начинаться со строки объявления версии HTML <!DOCTYPE …>, которая для современной версии html выглядит так:

<!DOCTYPE html>

Кроме элементов, в HTML-документах есть и сущности (англ. entities) — «специальные символы». Сущности начинаются с символа амперсанда и имеют вид &имя; или &#NNNN;, где NNNN — код символа в Юникоде в десятичной системе счисления.

Например, &copy; — знак авторского права (©). Как правило, сущности используются для представления символов, отсутствующих в кодировке документа, или же для представления «специальных» символов: &amp; — амперсанда (&), &lt; — символа «меньше» (<) и &gt; — символа «больше» (>), которые некорректно записывать «обычным» образом, из-за их особого значения в HTML.

Основные теги:

тег значение
<a href="URL">...</a>
<a name="#идентификатор">...</a>
Ссылка
<body...</body> Хранения содержания веб-страницы (контента), отображаемого в окне браузера.
<div>...</div> Элемент является блочным элементом и предназначен для выделения фрагмента документа с целью изменения вида содержимого. Как правило, вид блока управляется с помощью стилей. Чтобы не описывать каждый раз стиль внутри тега, можно выделить стиль во внешнюю таблицу стилей, а для тега добавить атрибут class или id с именем селектора.
<head> Предназначен для хранения других элементов, цель которых — помочь браузеру в работе с данными.
<input type="..."> Позволяет создавать разные элементы интерфейса и обеспечить взаимодействие с пользователем. Главным образом <input>предназначен для создания текстовых полей, различных кнопок, переключателей и флажков. Хотя элемент <input> не требуется помещать внутрь контейнера <form>, определяющего форму, но если введенные пользователем данные должны быть отправлены на сервер, где их обрабатывает серверная программа, то указывать <form> обязательно. То же самое обстоит и в случае обработки данных с помощью клиентских приложений, например, скриптов на языке JavaScript. Основной атрибут тега, определяющий вид элемента — type.

Более подробно обо всех элементах - http://htmlbook.ru/html

Практика

Для создания html есть два пути:

  1. Серверный рендер
  2. Клиентский рендер

У обоих вариантов есть свои плюсы и минусы. Заостряться на которых пока нет ни сил ни желания (может потом оно появится).

Важно одно оба варианта имеют право на жизнь и пока мы расмотрим серверный рендер на базе html-templates или шаблоны (есть и другие варианты для серверного рендера).

Шаблон — это всего лишь текстовый файл с HTML-кодом и дополнительными элементами разметки, которые обозначают динамический контент. Последний станет известен в момент запроса. Процесс, во время которого динамическая разметка заменяется, и генерируется статическая HTML-страница, называется отрисовкой (или рендерингом) шаблона. Во Flask есть встроенный движок шаблонов Jinja, который и занимается тем, что конвертирует шаблон в статический HTML-файл.

Jinja — один из самых мощных и популярных движков для обработки шаблонов для языка Python. Он должен быть известен пользователям Django. Но стоит понимать, что Flask и Jinja – два разных пакета, и они могут использоваться отдельно.

По умолчанию, Flask ищет шаблоны в подкаталоге templates внутри папки приложения. Это поведение можно изменить, передав аргумент template_folder конструктору Flask во время создания экземпляра приложения.

На базе этого и напишем базовую страницу со всеми паролями.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <main>
        ...
    </main>
</body>

Внутри тега main мы и будем хранить карточки со всеми паролями

Напишем заготовку для карточки. Элементы которые зависят от данных мы будем помечать так [[ account.field_name ]]

Важно!

я использовал квадратные скобки хотя нужно использовать фигурные (либо править настройки Jinja чтобы она распознавала квадратные)

<div class="account_card">
    <div class="account_card_service">[[ account.service ]]</div>
    <div class="account_card_email">[[ account.email ]]</div>
    <div class="account_card_password">[[ account.password ]]</div>
</div>

На самом деле [[ account.field_name ]] это часть синтаксиса Jinja, и мы просто вставляли реальное содержимое какого-то аккаунта. Но ведь аккаунтов много а карточка одна. Да, для этого мы будем использовать цикл for. Ага, он тоже есть в Jinja.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <main>
        [% for account in accounts %]
        <div class="account_card">
            <div class="account_card_service">[[ account.service ]]</div>
            <div class="account_card_email">[[ account.email ]]</div>
            <div class="account_card_password">[[ account.password ]]</div>
        </div>
        [% endfor %]
    </main>
</body>

Все, далее нам нужно будет просто при начале рендера подавать список аакаунтов которые нужно рендерить.

from flask import Flask, render_template
from DataBase import DataBase # Наш класс базы данных

app = Flask()
accounts_db = DataBase(f'data/accounts.json')

@app.route('/')
def page_all_accounts():
    accounts = accounts)db.get_all()
    return render_template('accounts.html', accounts=accounts)


if __name__ == '__main__':
    app.run()

CSS

Теория

CSS (Cascading Style Sheets — каскадные таблицы стилей) — формальный язык описания внешнего вида документа, написанного с использованием языка разметки.

До появления CSS оформление веб-страниц осуществлялось исключительно средствами HTML, непосредственно внутри содержимого документа. Однако с появлением CSS стало возможным принципиальное разделение содержания и представления документа. За счёт этого нововведения стало возможным лёгкое применение единого стиля оформления для массы схожих документов, а также быстрое изменение этого оформления.

Преимущества:

Недостатки:

Базовый синтаксис:

селектор {
    свойство: значение;
    свойство: значение;
    свойство: значение;
}

Виды селекторов

Универсальный селектор

* {
   margin: 0; 
   padding: 0; 
}

Селектор тегов

p {
   font-family: arial, helvetica, sans-serif; 
}

Селектор классов

.note {
   color: red; 
   background-color: yellow; 
   font-weight: bold; 
}

Селектор идентификаторов

#paragraph1 {
    margin: 0; 
}

Практика

Будем вести нашу страницу к красоте. Все равно хуже уже не будет.

Пускай у нас будет такой хтмл

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <!-- Указывается титульник страницы -->
    <title>Title</title>
    <!-- Ссылка браузеру где брать стили -->
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <main>
        <div class="account_card_container">
            <div class="account_card">
                <div class="account_card_service">service name</div>
                <div class="account_card_email">email data</div>
                <div class="account_card_password">very secret password<img class="view-icon icon" /></div>
            </div>
            <!-- Тут еще десятка два таких карточек --->
        <div>
    </main>
</body>

Различие с предыдущим в том что добавился div с классом ..._container. Это важная особенность css, мы создаем контейнеры чтобы манипулировать расположением элементов по горизонтали и вертикали.

Для этого можно использовать Flex или Grid.

Я снова не буду останавливаться на этом подробно тк эта гора текста увеличится еще раза 2. Вам хватит и того что я копипасщу с вики.

only html

В общем как-то так будет выглядеть наш хтмл без стилей. Как по мне очень даже минималистично и функционально.

Но привередливый читатель скажет, что хочется красивостей и негоже проекту за 0,000,000$ быть таким не красивым. А я соглашусь.

В общем не буду вас мучать текстом и покажу как должно стать а потом расскажу как.

html with css

- Как какать?
- Это нужно почувствовать. Если почувствуешь, то просто плыви по течению.

Лан, это было небольшое отступление

Файлики которые нужно скачать: view.svg no-view.svg

Они используются как кнопка скрыть/показать пароль

Создаем переменные для цветов.

:root {
    --background-color: #f6f8fa;
    --card-color: white;
    --card-border-color: #e1e4e8;
}

Задаем основной цвет нашего хтмл

html {
    background-color: var(--background-color);
}

Добавляем стили для карточки с паролем

.account_card {
    border-radius: 10px;
    border-color: var(--card-border-color);
    background-color: var(--card-color);
    border-width: 1px;
    border-style: solid;
    padding: 20px;
    margin: 10px;
}

Конечно, просто список карточек это не топ, поэтому сделаем это в виде таблички. Её особенность в том что она сама выбирает размеры и количество колонок, это очень удобно, особенно, когда нужно делать адаптив под мобилки.

.account_card_container {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));

    align-items: center;
    justify-content: center;
}

Добавляем напротив пароля иконку скрытый/закрытый. (ХТМЛ для иконки есть мы просто меняем его стиль)

.icon {
    width: 20px;
    height: 20px;
}

.view-icon {
    content: url(./view.svg);
}

.no-view-icon {
    content: url(./no-view.svg);
}

Выравниваем текст пароля и иконку.

.account_card_password {
    display: inline-flex;
    justify-content: space-between;
    width: 100%;
}

.secret-text {
    -webkit-text-security:disc;
    /* this code not working on firefox */
}

Хоба, готово

Осталось только добавить css файлик в head тег html

Сохраним наш css файл по такому пути \static\css\style.css

И добавим в head тег link. Должно получиться такое:

<head>
    <title>Python Flask Bucket List App</title>
    <!-- подключаем стили -->
    <link href="[[ url_for('static', filename='css/style.css') ]]" rel="stylesheet">
    <!-- подключаем скрипты -->
    <script src="[[ url_for('static', filename='js/script.js') ]]"></script>
</head>

JavaScript

Практика

Нужно добавить к head подключение скрипта

<head>
    <!-- other tags -->
    <script src="script.js" defer></script>
</head>

Внутри файла пишем код.

// добавляем событие
document.addEventListener('click', event => {
    // создаем неизменяемую переменную с элементом который испустил событие
    const element = event.target;
    // определям кто испустил событие
    const is_icon = element.classList.contains('no-view-icon') ||
                    element.classList.contains('view-icon');
    if (is_icon) {
        // меняем стили у иконки
        element.classList.toggle('no-view-icon');
        element.classList.toggle('view-icon');
        // меняем стили у родителя
        element.parentNode.classList.toggle('secret-text');
    }
});