Перейти к содержанию

Выпуск многоязычной библиотеки

В «Параллели» уже есть реестр языковых версий, словари, форматирование, переключатель, поисковые метаданные и редакционный учёт ревизий. Осталось описать выпуск как целостный набор файлов. Если обновить только статьи, но оставить старый переключатель или sitemap, библиотека получит противоречивое состояние.

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

Состав исходников

В архиве серии находится итоговый проект. Это один полный набор файлов, а не десять автоматически проверенных снимков. Уроки показывают последовательное появление механизмов и указывают, какие фрагменты относятся к полному сборщику.

Файл или каталог Назначение
site.json Origin, основной язык, локали и направление
articles.json ID статей, версии, адреса и ревизии
content/ru/, content/en/ Тексты Markdown
web/ Сообщения, форматирование и стили
build.py Генерация только опубликованных вариантов
translation_report.py Редакционный отчёт об отставании
requirements.txt Закреплённая зависимость Markdown

В готовый статический выпуск не входят исходный Python, виртуальная среда и редакционные черновики. Посетитель получает HTML и необходимые ресурсы. Это упрощает хостинг, но не означает, что файлы на сервере обновятся после сохранения Markdown: требуется новая сборка и отдельная передача её результата.

Готовый перевод и режим просмотра

Внутри реестра статус published означает, что версия включена в учебный выпуск. Статус Markdown-урока ProfessorWeb draft: true относится к другому уровню: сама эта учебная серия пока является локальным редакционным материалом. Не смешивайте эти два состояния при переносе примера в собственный проект.

Для предпросмотра можно использовать отдельную сборку, закрытую от индексирования. Она не должна случайно попасть на публичный хостинг вместо производственного набора. Не записывайте localhost в canonical только ради локального чтения. Основной origin остаётся настройкой будущего выпуска, а ограничения предпросмотра задаются отдельным режимом.

В полном сборщике параметр --preview добавляет noindex,follow и закрывающий robots.txt, а sitemap не содержит публичных адресов. В обычном режиме формируется производственное описание на указанном origin. Это лишь поведение исходника: при подготовке данной серии обе команды не выполнялись.

Отдельный каталог результата

Сборщик создаёт новый каталог результата и записывает туда все текущие страницы. Он не удаляет исходный content и не делает массовое переименование старых URL. В учебном архиве используется каталог out; перед повторной сборкой старый результат заменяется через временную соседнюю папку.

Ключевая последовательность внутри build.py выглядит так:

temporary = ROOT / ".out-building"
target = ROOT / "out"
if temporary.exists():
    shutil.rmtree(temporary)
temporary.mkdir()

render_all(site, articles, temporary, preview=args.preview)

if target.exists():
    shutil.rmtree(target)
temporary.rename(target)

Пути заданы сборщиком и принадлежат учебному проекту. Не заменяйте их на произвольный пользовательский аргумент без проверки: удаление каталога является реальным действием, даже если приложение статическое. В примере не производится запись в ProfessorWeb или в текущий каталог хостинга.

Такая замена не обещает полностью атомарное обновление публичного сайта. Между удалением старого каталога и переименованием существует промежуток. Для локального учебного результата он допустим; производственный механизм может использовать версии выпусков и переключение ссылки. Важно не называть простую замену папки готовой системой непрерывной публикации.

Что сравниваем перед передачей

Адреса нужно сравнивать по реестру, а не по впечатлению от главной страницы. Для «Параллели» русский stable-urls сохранил /articles/stable-urls.html, английский получил /en/articles/stable-urls.html, а reading-list пока существует только по русскому адресу. Именно этот набор должен присутствовать в выпуске.

Рассмотрите HTML первой статьи: язык документа соответствует телу, canonical указывает на собственный URL, альтернативы взаимны, переключатель ведёт к той же статье. Затем рассмотрите вторую: неготовый перевод не попал в ссылки и sitemap. Это конкретные ожидаемые результаты, а не утверждение, что мы уже просмотрели собранную библиотеку.

На хостинге дополнительно потребуется проверить HTTP-ответы, доступность ресурсов и поведение неизвестного пути. Статический файл 404.html сам по себе не заставляет сервер вернуть статус 404. Правила выдачи являются частью конфигурации площадки. Редиректы со старых адресов тоже не возникают от одного упоминания в реестре.

Обновление без потери истории

При следующей правке редактор изменит оригинал, при необходимости увеличит ревизию и передаст задачу переводчику. Готовый перевод получает новую translated_from, а опубликованные адреса остаются прежними. Выпуск должен содержать согласованный набор реестра и текстов, чтобы откат возвращал их вместе.

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

Полезно отдельно записать известные ограничения. Библиотека не принимает чужой Markdown через публичную форму, не определяет качество перевода автоматически и не выполняет серверные перенаправления. Пример показывает модель локализации и статическую генерацию; дополнительные возможности требуют самостоятельного проекта и проверки.

Ресурсы должны соответствовать страницам

Новый выпуск содержит не только HTML: словари и стили тоже должны совпадать с шаблонами. Если страница вызывает удалённый ключ, а браузер получил старый JavaScript из кэша, интерфейс может сломаться при первом действии. Поэтому версии ресурсов передают согласованно с документами и учитывают правила кэширования.

Чистый каталог сборки также помогает убрать страницы переводов, которые перестали входить в выпуск. Простое копирование новых файлов поверх старых сохранило бы лишний английский документ, хотя переключатель и sitemap его уже не показывают. Однако решение о судьбе ранее опубликованного адреса всё равно оформляется отдельно: удаление файла не заменяет редакционную политику и правильный HTTP-ответ хостинга.

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

Оглавление серии