Создать встраиваемый пакет
const url = 'https://example.com/wp-json/wp2lms-pro/embed-packages/v1/packages?blog_id=1';const options = { method: 'POST', headers: {'X-WP-Nonce': '<X-WP-Nonce>', 'Content-Type': 'application/json'}, body: '{"title":"Интерактивный урок","status":"publish","html":"<!doctype html><html lang=\"ru\"><title>Урок</title><h1>Добро пожаловать</h1></html>"}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url 'https://example.com/wp-json/wp2lms-pro/embed-packages/v1/packages?blog_id=1' \ --header 'Content-Type: application/json' \ --header 'X-WP-Nonce: <X-WP-Nonce>' \ --data '{ "title": "Интерактивный урок", "status": "publish", "html": "<!doctype html><html lang=\"ru\"><title>Урок</title><h1>Добро пожаловать</h1></html>" }'Создаёт запись CPT wp2lms_embed_pkg (wp_insert_post) и по желанию заливает содержимое через ingest_from_request. Это не создание страниц WordPress: материализация — POST …/materialize-pages или POST …/batch.
title необязателен: пустая строка после sanitize_text_field → «Untitled package». status необязателен, по умолчанию publish; допустимы только publish / draft / private (sanitize_key), иное PHP заменяет на publish.
Содержимое можно не передавать — получится пакет без файлов (пустые launch_path/meta). Иначе один из каналов: multipart-файл (file / package_file / package_zip, расширение zip или html/htm), JSON files (дерево путей), JSON html (пишется как index.html). Если есть и files, и непустой html, а в дереве нет index.html — PHP добавит index.html из html. Пустой объект files деревом не считается.
Ошибка ingest после insert — пакет сразу wp_delete_post(..., true) и тот же WP_Error клиенту.
Нужно manage_network (multisite) или edit_pages. Cookie + X-WP-Nonce или Application Password.
Authorizations
Заголовок раздела «Authorizations»Parameters
Заголовок раздела «Parameters»Query Parameters
Заголовок раздела «Query Parameters»ID сайта сети (switch_to_blog). Необязательно: по умолчанию текущий блог запроса. Не ID пакета и не page_id. Минимум 1; на одиночном сайте должен совпадать с текущим — иначе 400 embed_packages_invalid_blog. В сети неизвестный сайт или сайт другой сети — 404 embed_packages_unknown_blog.
Example
1Request Body
Заголовок раздела «Request Body»object
Заголовок новой записи CPT. Необязательно. Пусто после sanitize → «Untitled package». После ingest может быть перезаписан из HTML/манифеста.
Post_status новой записи. Необязательно, по умолчанию publish. Иное значение PHP заменяет на publish.
Сырой HTML одного launch-файла. Необязательно. Пишется как index.html, если нет multipart и (при наличии files) в дереве ещё нет index.html.
Карта относительных путей к содержимому. Ключ — безопасный относительный путь (PackageFilePolicy). Пустой объект PHP не считает деревом. Небезопасный путь — unsafe_path; чужое расширение — disallowed_extension.
Example
{ "title": "Интерактивный урок", "status": "publish", "html": "<!doctype html><html lang=\"ru\"><title>Урок</title><h1>Добро пожаловать</h1></html>"}object
Первое из полей multipart, которое смотрит PHP (file, затем package_file, затем package_zip). Расширение .zip — ZipExtractor; .html/.htm — один HTML. Иное — 400 embed_packages_bad_file.
Example
lesson.zipАльтернативное имя файла пакета (то же, что file).
Example
lesson.zipТретье возможное имя multipart-поля с ZIP/HTML.
Example
lesson.zipЗаголовок CPT из form-fields (если JSON-тела нет). Пусто → «Untitled package».
Example
Интерактивный урокPost_status из form-fields. Не publish/draft/private → publish.
Example
publishResponses
Заголовок раздела «Responses»Пакет создан. Тело — package_payload (id, title, status, launch_*, meta).
Ответ package_payload — запись CPT плюс плоские поля из meta и полный объект meta.
object
ID записи CPT wp2lms_embed_pkg. Совпадает с {id} в path GET/PATCH/DELETE/content/materialize-pages.
post_title пакета. После ingest PHP может заменить его на <title> launch-файла.
post_status пакета. REST принимает publish/draft/private; в ответе то, что лежит в БД.
Копия meta.content_type (web / scorm1.2 / scorm2004 / xapi или пусто).
Копия meta.content_tool (детектор автора или пустая строка).
Копия meta.launch_path — относительный HTML запуска, не URL.
Абсолютный URL запуска (uploads baseurl + storage_rel + launch_path). Пусто, если содержимого нет.
Копия meta.activity_id.
Копия meta.storage_rel — каталог в uploads, не URL.
Копия meta.is_multipage (true только для web без tool и ≥2 HTML).
Копия meta.pages — индекс HTML внутри пакета, не страницы WordPress.
object
Относительный путь HTML внутри каталога пакета (posix, без ведущего /). Из PackagePagesIndex::scan.
Заголовок из <title> файла или имя без расширения, если тега нет.
Полный массив post meta _wp2lms_embed_package (PackageMeta::get). У пакета без ingest — пустой объект.
object
Тип после ManifestPipeline — web, scorm1.2, scorm2004 или xapi. Пусто, пока содержимое не залито.
Версия из манифеста (для SCORM часто совпадает с content_type). Для web обычно пустая строка.
XAPI activity id. Если парсер не дал — {home}wp2lms-embed-package/{id}.
Относительный HTML запуска внутри storage (из манифеста или fallback index.html).
Заголовок из launch HTML / манифеста; PHP может перезаписать post_title пакета этим значением.
Mastery score из imsmanifest (SCORM), иначе null.
Детектор автора: ispring, articulate_rise, articulate_storyline, articulate_presenter, captivate, elucidat или пустая строка.
Путь от uploads basedir, wp2lms-embed-packages/{id}/.
Unix-время последней успешной записи содержимого (time() в finalize).
True только для content_type=web без content_tool и ≥2 HTML в индексе.
Индекс HTML (path+title), если пакет multipage; иначе [].
object
Относительный путь HTML внутри каталога пакета (posix, без ведущего /). Из PackagePagesIndex::scan.
Заголовок из <title> файла или имя без расширения, если тега нет.
Example
{ "id": 42, "title": "Интерактивный урок", "status": "publish", "content_type": "web", "content_tool": "", "launch_path": "index.html", "launch_url": "https://lms.example.com/wp-content/uploads/wp2lms-embed-packages/42/index.html", "activity_id": "https://lms.example.com/wp2lms-embed-package/42", "storage_rel": "wp2lms-embed-packages/42/", "is_multipage": false, "pages": [], "meta": { "content_type": "web", "version": "", "activity_id": "https://lms.example.com/wp2lms-embed-package/42", "launch_path": "index.html", "title": "Интерактивный урок", "mastery_score": null, "content_tool": "", "storage_rel": "wp2lms-embed-packages/42/", "uploaded_at": 1726252800, "pages": [], "is_multipage": false }}Embed_packages_bad_file — multipart не ZIP и не HTML/HTM; embed_packages_invalid_blog — некорректный blog_id.
object
Код WP_Error (get_error_code()), например embed_packages_not_found.
Текст WP_Error (get_error_message()).
Data WP_Error. Обычно { "status": 404 }. Ошибки ingest/materialize без status WordPress REST отдаёт как 500.
object
Example
{ "code": "embed_packages_not_found", "message": "Package not found.", "data": { "status": 404 }}Не аутентифицирован. WordPress REST: rest_forbidden (status 401), если нет cookie-сессии. Cookie + X-WP-Nonce или Application Password.
object
Код WP_Error (get_error_code()), например embed_packages_not_found.
Текст WP_Error (get_error_message()).
Data WP_Error. Обычно { "status": 404 }. Ошибки ingest/materialize без status WordPress REST отдаёт как 500.
object
Example
{ "code": "embed_packages_not_found", "message": "Package not found.", "data": { "status": 404 }}Нет права manage_network (multisite) или edit_pages (одиночный сайт), либо невалидный REST nonce (rest_cookie_invalid_nonce).
object
Код WP_Error (get_error_code()), например embed_packages_not_found.
Текст WP_Error (get_error_message()).
Data WP_Error. Обычно { "status": 404 }. Ошибки ingest/materialize без status WordPress REST отдаёт как 500.
object
Example
{ "code": "embed_packages_not_found", "message": "Package not found.", "data": { "status": 404 }}Embed_packages_unknown_blog — в сети нет такого сайта или сайт принадлежит другой сети.
object
Код WP_Error (get_error_code()), например embed_packages_not_found.
Текст WP_Error (get_error_message()).
Data WP_Error. Обычно { "status": 404 }. Ошибки ingest/materialize без status WordPress REST отдаёт как 500.
object
Example
{ "code": "embed_packages_not_found", "message": "Package not found.", "data": { "status": 404 }}WP_Error без HTTP-status в data — сбой wp_insert_post или ingest (empty_tree, unsafe_path, disallowed_extension, zip_open, unzip_failed, process_failed, mkdir_failed, write_failed, invalid_file_value, unsafe_zip, missing_zip и др.). WordPress REST отдаёт такие ошибки как 500. Пакет при ошибке ingest удаляется.
object
Код WP_Error (get_error_code()), например embed_packages_not_found.
Текст WP_Error (get_error_message()).
Data WP_Error. Обычно { "status": 404 }. Ошибки ingest/materialize без status WordPress REST отдаёт как 500.
object
Example
{ "code": "embed_packages_not_found", "message": "Package not found.", "data": { "status": 404 }}