ScriptData


ScriptData — статический класс для передачи данных из PHP в JavaScript. Он автоматически доступен в файлах темы.

Поддерживает

  • передачу данных отдельными именованными блоками
  • замену и удаление зарегистрированных блоков
  • автоматический вывод данных через CurrentTheme::getJS()
  • получение данных в JavaScript без создания собственных глобальных переменных

Быстрый старт

В PHP-коде темы зарегистрируйте блок до существующего вызова CurrentTheme::getJS():

php
ScriptData::add('catalog', ['page-size' => 12]);

При выводе JavaScript через CurrentTheme::getJS() CMS автоматически включит зарегистрированные данные и подключит средства их чтения.

В JavaScript-модуле темы получите блок по имени:

js
const catalog = window.wsScriptData.read('catalog', {});
console.log(catalog['page-size']); // 12

Второй аргумент read() задаёт резервное значение на случай отсутствия блока.

Пользовательские блоки не добавляются в window.wsSite. Для них используется отдельный объект window.wsScriptData.

Методы

Имя блока должно быть непустой строкой в UTF-8 без управляющих символов. Недопустимое имя вызывает InvalidArgumentException.

Имя site-lang используется CMS для передачи переводов. Для собственных данных выбирайте другие имена.

add(string $name, mixed $data): void

Регистрирует именованный блок данных:

php
ScriptData::add('catalog', ['page-size' => 24]);

Повторный вызов с тем же именем заменяет ранее зарегистрированное значение, если блок ещё ожидает вывода.

Данные преобразуются в JSON при вызове add(). Последующие изменения исходной переменной не изменяют зарегистрированный блок.

Значение должно поддерживать преобразование в JSON. Если преобразование невозможно, возникает JsonException.

render(?string $name = null): string

Возвращает HTML для передачи зарегистрированных данных в браузер. Сам метод ничего не выводит.

Для отдельного блока передайте имя:

php
echo ScriptData::render('catalog');

Без аргумента метод включает все ожидающие вывода блоки:

php
echo ScriptData::render();

Включённые блоки удаляются из списка ожидающих сразу при вызове метода, даже если возвращённый HTML ещё не выведен. Если подходящих блоков нет, возвращается пустая строка.

Обычно вызывать render() самостоятельно не требуется: зарегистрированные блоки автоматически включаются в результат CurrentTheme::getJS().

Сам render() не подключает средства чтения данных в JavaScript. Их подключение обеспечивает CurrentTheme::getJS().

remove(string $name): bool

Удаляет зарегистрированный блок, который ещё ожидает вывода:

php
$removed = ScriptData::remove('catalog');

Возвращает true, если блок был удалён, иначе false.

Метод не изменяет уже сформированный HTML и не удаляет данные, ранее переданные в браузер.

Данные в JavaScript

Объект window.wsScriptData автоматически доступен в скриптах темы при использовании CurrentTheme::getJS().

read(name, fallback = null, root = document)

Возвращает данные блока по имени:

js
const catalog = window.wsScriptData.read('catalog', {});

Если доступного значения нет, возвращается fallback. По умолчанию это null.

Переданные значения null, false и 0 считаются полноценными данными и не заменяются резервным значением.

После чтения HTML-блок удаляется из DOM, но полученные данные сохраняются для повторных обращений. Повторное чтение не расходует значение.

По умолчанию поиск выполняется во всём документе. Если блок выведен внутри отдельного контейнера, можно ограничить область:

js
const container = document.querySelector('[data-catalog]');

if (container) {
    const catalog = window.wsScriptData.read('catalog', {}, container);
}

Для каждой области данные сохраняются отдельно. При повторных обращениях используйте ту же область: HTML-блок, уже прочитанный через другую область, больше не находится в DOM.

remove(name, root = document)

Удаляет сохранённые данные блока и его ещё не прочитанные HTML-блоки в выбранной области:

js
const removed = window.wsScriptData.remove('catalog');

Возвращает true, если что-либо было удалено, иначе false.

Для удаления внутри контейнера передайте его вторым аргументом:

js
window.wsScriptData.remove('catalog', container);

Уже полученные значения в JavaScript-переменных не изменяются. Удаление также не затрагивает данные, сохранённые при чтении в другой области.