RUEN
Обсудить проект

Клиентский проект

Baya & Grand Kennel

Сайт питомника кавалер-кинг-чарльз-спаниелей из Минска: две локали, редактор прямо на живом сайте и заявки в Telegram.

внешних зависимостей
0
локали
2
разделов
9

Открыть сайт — bayagrand.by ↗

Первый экран сайта Baya & Grand Kennel

Питомник кавалер-кинг-чарльз-спаниелей в Минске. Заказчик — владелец питомника, не разработчик: у него есть собаки, помёты, титулы и выставки, и всё это меняется каждый месяц.

Что на самом деле нужно было решить

Сайт-визитку сделать несложно. Сложность в другом: владелец должен наполнять сайт сам, не открывая ни репозиторий, ни сервер, ни админ-панель в отдельном домене. Иначе через полгода на сайте висят прошлогодние помёты, а каждая правка запятой идёт через разработчика.

Второе условие — две полноценные версии, русская и английская: покупатели щенков пишут из-за границы, и питомник ездит на выставки в Европу.

Редактор живёт на самом сайте

Владелец открывает свой сайт с ?edit=1, вводит пароль — и правит страницу там же, где её видят посетители. Никакого второго интерфейса, который нужно отдельно осваивать.

Редактируется почти всё: тексты, фотографии, фоны секций, галереи карточек, декоративные линии и пять списков — статьи о породе, собаки, текущие помёты, титулы и история помётов. Добавить нового щенка — значит нажать «добавить» прямо в разделе «Щенки».

Правки не лежат в файлах сайта. Они уходят на сервер в отдельное хранилище и накладываются поверх исходного содержимого при загрузке страницы. Поэтому выкладка новой версии сайта не затирает то, что владелец успел написать — это главное требование к такой схеме, и без него редактор был бы ловушкой.

Две локали без перезагрузки

Переводимые места размечены прямо в разметке — 159 узлов на девять разделов. Словарь обеих локалей лежит одним файлом, переключение мгновенное, без похода на сервер.

Вместе с языком меняются и мета-теги: title, description, Open Graph. Язык при первом заходе определяется по цепочке «параметр в адресе → выбор прошлого визита → язык браузера», причём родственные локали получают русскую версию, остальные — английскую.

Отдельная деталь для владельца: он пишет правку только на одном языке. Второй язык бэкенд переводит сам и сохраняет обе версии сразу. Перевод потом можно поправить руками — но пустой английской страницы не появляется никогда.

Бэкенд на стандартной библиотеке

761 строка на Python без единой внешней зависимости. Он делает три вещи:

  • принимает заявки с формы и отправляет их в Telegram;
  • отдаёт правки владельца публичным запросом, который забирает страница при загрузке;
  • обслуживает редактор: вход, сохранение текста, загрузка изображений, автоперевод, операции над списками.

Вход в редактор — пароль, который нигде не хранится в открытом виде: только scrypt-хеш, сверка через сравнение с постоянным временем. Токен сессии живёт 12 часов. После восьми неудачных попыток адрес блокируется.

Форма защищена ловушкой для ботов, ограничением длины полей, лимитом тела запроса и пятью отправками с адреса за десять минут. Загрузка изображений — белый список типов, лимит размера, случайный суффикс в имени файла. Правки пишутся атомарно, поэтому обрыв посреди сохранения не оставляет испорченный файл.

Сервер

nginx со строгим CSP, ограничением методов, кешем статики и двумя зонами лимитов — отдельно на сайт, отдельно на API. Сервис бэкенда поднят systemd в песочнице: без повышения привилегий, с доступом на запись только в свой каталог. fail2ban с готовыми джейлами и собственным фильтром на сканеры, которые ищут .env, .git и PHP-админки.

Ни сборки, ни зависимостей

Ни package.json, ни requirements.txt в проекте нет — ни на фронтенде, ни на бэкенде. Нет шага сборки, нет бандлера, нет node_modules. Сайт — это HTML, три файла скриптов и один файл стилей.

Это не аскеза ради аскезы. У проекта горизонт в годы, а владелец не будет обновлять зависимости. Через три года такой сайт откроется и соберётся ровно так же, как сегодня, — потому что собирать нечего, а обновлять нечему.

HTML · CSS · JavaScript (ES6) · Python (стандартная библиотека) · Telegram Bot API · nginx · systemd · fail2ban