Картинки в статье
1. Загрузить файлы
Каждый файл — один запрос. Повтор безопасен: тот же адрес или те же байты вернут существующее вложение (deduped: true), поэтому скрипт можно перезапускать после сбоя.
for src in \
https://onpress.pro/wp-content/uploads/2026/05/ccae29ae_1778004215.png \
https://onpress.pro/wp-content/uploads/2026/05/49a37225_1778003864.png
do
curl -s -X POST "$API/site/$SITE/media" \
-H "Authorization: Bearer $OP_TOKEN" -H 'Content-Type: application/json' \
-d "$(jq -n --arg url "$src" '{url: $url, lang: "ru"}')" \
| jq -c '{id, path, deduped}'
done | tee uploaded.jsonl
{"id":6471,"path":"/wp-content/uploads/sites/233/2026/09/ccae29ae_1778004215.png","deduped":false}
{"id":6472,"path":"/wp-content/uploads/sites/233/2026/09/49a37225_1778003864.png","deduped":false}
Файлы с диска — через data в base64 и filename (до ~7 МБ файла; больше — выложите по адресу и загрузите через url). alt и title можно передать сразу; у уже существующего вложения они не меняются.
2. Вставить в markdown
Берите path, не url:
Страница собирается по шаблону фрейма на каждом запросе.

Статическая копия отдаётся файлом без PHP.

- картинка — отдельной строкой;
- текст в скобках —
alt, в кавычках после пути — подпись под картинкой (<figcaption>): жирный, курсив и код в ней работают, ссылки — нет, квадратных скобок и двойных кавычек внутри подписи не ставьте; - путь от корня сайта работает на любом его домене и переживает смену домена.
При сборке картинка из медиатеки выводится как <picture> с источниками разных размеров, WebP и размерами width/height вложения, с loading="lazy" и decoding="async". Первая картинка страницы идёт без lazy, с fetchpriority="high" и предзагрузкой — она первой появляется на экране. Это работает и на страницах, опубликованных раньше, без переопубликации. Подробно — картинки в markdown.
3. Изображение записи
Картинка карточки и соцсетей — превью страницы. Ставится ключом image во frontmatter: номер вложения из шага 1 или сразу адрес картинки — чужой адрес зальётся в медиатеку сам:
---
name: "Как собирается страница"
slug: "kak-sobiraetsya-stranica"
url: "/blog/kak-sobiraetsya-stranica/"
lang: "ru"
frame: "article"
image: 6471
---
Превью сразу становится og:image страницы. Во фрейме его выводит вставка <!-- onpress/featured-image {"figure":true} /-->, в биндах оно доступно как page.thumbnail_url и page.thumbnail_alt. Выгрузка возвращает image с адресом файла, поэтому круг «выгрузил — поправил — залил» превью не теряет. Поменять или снять превью без публикации — PATCH /pages/{ref} с {"thumbnail": 6471} или {"thumbnail": null}.
4. Опубликовать и проверить
curl -s -X POST "$API/site/$SITE/pages/markdown" \
-H "Authorization: Bearer $OP_TOKEN" -H 'Content-Type: application/json' \
-d "$(jq -n --rawfile md article.md '{markdown: $md}')" | tee pub.json | jq -c '{id, link, warnings}'
curl -s "$(jq -r .link pub.json)" | grep -o '<figure class="wp-block-image[^"]*">.\{0,200\}' | head -3
curl -s "$(jq -r .link pub.json)" | grep -o 'type="image/webp"' | head -1
curl -s "$(jq -r .link pub.json)" | grep -o '<img[^>]*fetchpriority="high"[^>]*>'
Если картинки нет
- В ответе публикации в
blocksнетcore/image— строка картинки не отдельная или пустой адрес. - На странице
<img>без<picture>— адрес не из медиатеки этого сайта (илиurlс другим доменом вместоpath). 422 unsafe_svgпри загрузке SVG — в файле скрипты или обработчики событий;415 unsupported_type— не JPEG, PNG, WebP, GIF или SVG.