nuckty
EN
Все разделы →

Внешние репозитории

Контент сайта не обязан лежать в одном репозитории с блоками и конфигами. Тексты и изображения могут храниться в отдельных репозиториях контента, а движок собирает сайт из них. Это удобно, когда один контент обслуживает несколько сайтов или когда над текстами работает отдельная команда.

Здесь важно чёткое разделение: ядро читает контент из каталога на диске, а наполняет этот каталог расширение. Клонирование репозиториев Git в ядро не входит — это необязательный инструмент, как и всё остальное в экосистеме (см. семейство репозиториев).

Ядро: корень контента

Движок читает .md-файлы из корня контента — первого уровня в levels.json, по умолчанию content/:

["content", "blocks"]

Строка карты сайта [models, free/models.md] разрешается в content/free/models.md. Каталог может быть локальным или указывать на клон внешнего репозитория — движку всё равно, как файлы там оказались. Он лишь читает то, что уже лежит на диске: ни клонирования, ни обновления ядро не делает.

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

Расширение: наполнение каталога

Для подготовки репозиториев нужен git в PATH, а для обновлений также нужен Git LFS; см. команду подготовки.

Команда подготовки читает общий файл config/external.json — массив адресов Git. Аргумента таргета у неё нет; при отсутствии файла или пустом массиве она ничего не подготавливает:

[
    "git@github.com:acme/acme-content.git",
    "git@github.com:acme/acme-assets.git"
]

Наполнение — это command-расширение: команда nuckty content-external читает external.json, клонирует каждый репозиторий в external/<repo>/ (имя каталога — имя репозитория без .git) и обновляет рабочую копию. Затем укажите клон первым уровнем в levels.json, и движок читает контент оттуда:

["external/acme-content", "content", "blocks"]

Это отдельный шаг, как и подготовка изображений. Сборка не запускает команду автоматически. Для работы без сети нужны готовые входные файлы и расширения, не обращающиеся к сети. Воспроизводимость требует фиксированных версий и метаданных. Git также может использоваться ядром для времени изменения исходников; без него оно равно null.

external/
  acme-content/     ← клон, первый уровень levels.json
  acme-assets/      ← общие ассеты

Исключите external/ из репозитория Git сайта, добавив его в .gitignore. Команда подготовки не создаёт это правило и не меняет levels.json за вас.

Роли репозиториев в site.json

В config/site.json можно описать роли репозиториев:

ПолеНазначение
contentRepoОсновной репозиторий контента — обычно тот, что стоит первым уровнем в levels.json.
assetReposДополнительные репозитории с ассетами (изображения, файлы для скачивания).
githubRawBaseБаза для переписывания ссылок на сырые файлы GitHub. null — не переписывать.

contentRepo и assetRepos — описательные поля: они не выбирают корень Markdown и не фильтруют сканирование ассетов. Корень задаёт первый уровень levels.json, а внешние источники стадий — external.json в configDir текущего таргета. При отдельных каталогах конфигурации согласуйте эти списки с общим config/external.json, который читает команда подготовки.

Зачем это нужно

  • Разделение ролей. Над текстами работает одна команда, над движком и вёрсткой — другая. Контент живёт своей жизнью, сборка — своей.
  • Один контент — несколько сайтов. Один репозиторий контента может обслуживать несколько таргетов или разных сайтов.
  • Чистые исходники. В репозитории сайта нет копии чужого контента — только ссылка в external.json и путь в levels.json.

Чего это не заменяет

Внешние репозитории — про источники контента, а не про публикацию: готовый артефакт по-прежнему собирается в outDir и публикуется целиком (см. публикацию по FTP). И это не замена расширениям: расширения подключаются через ext[], а external.json лишь перечисляет источники контента.