Перестаньте использовать wp_localize_script для передачи данных
Если вы всё ещё используете wp_localize_script() для передачи данных из PHP в JavaScript, то вы явно делаете что-то не так.
Несмотря на то, что так предлагают делать бесчисленные туториалы, эта функция была создана для перевода JavaScript-строк, а не для передачи данных. WordPress предоставил нам wp_add_inline_script() почти десять лет назад специально для этой цели, и пора нам начать её использовать.
Проблемы с wp_localize_script
wp_localize_script() была изначально разработана для перевода JavaScript-строк. Использование её для передачи данных на JavaScript работает, но это хак с рядом ограничений и нарушение семантики:
- Неправильное использование назначения: Она была создана для переводов, а не для передачи данных, что объясняет, почему в названии функции есть слово «localize»
- Всегда создаёт глобальные переменные: Ваши данные всегда прикрепляются к объекту глобальной области видимости
window - Принудительная структура объекта: Данные должны быть ассоциативным массивом/объектом, вы не можете передавать простые значения, массивы или другие примитивы JavaScript напрямую
- Неэффективный вывод: Генерирует ненужные
var-объявления и оборачивает всё в объект, даже когда вам это не нужно - Ограничена одним скриптом: Вы можете локализировать скрипт только один раз, вызов функции несколько раз для того же
handleпросто перезаписывает предыдущие данные.
Вот что генерирует wp_localize_script():
wp_localize_script( 'my-script', 'myData', [
'apiUrl' => rest_url( 'app/v1' ),
'nonce' => wp_create_nonce( 'wp_rest' )
] );
Вывод:
<script id="my-script-js-extra">
var myData = {"apiUrl":"https://example.com/wp-json/app/v1","nonce":"abc123"};
</script>
Использование wp_add_inline_script
wp_add_inline_script() даёт вам полный контроль над выводимым JavaScript. Вот как передать те же данные:
wp_enqueue_script('my-script', get_template_directory_uri() . '/js/script.js', [], '1.0', true);
$data = [
'apiUrl' => rest_url('app/v1'),
'nonce' => wp_create_nonce('wp_rest')
];
wp_add_inline_script('my-script',
'const myData = ' . wp_json_encode($data) . ';',
'before'
);
Вывод:
<script>
const myData = {"apiUrl":"https://example.com/wp-json/app/v1","nonce":"abc123"};
</script>
<script src="https://example.com/wp-content/themes/my-theme/js/script.js" id="my-script-js"></script>
Почему wp_add_inline_script лучше
- Гибкость: Вы контролируете точный вывод JavaScript: используйте
const,letили даже оборачивайте ваши данные в IIFE, чтобы избежать глобальных переменных - Семантическая ясность: Название функции фактически описывает, что она делает: добавляет встроенный скрипт, а не намекает на то, что это для локализации
- Лучшая область видимости: Вы можете использовать современное JavaScript-scoping (
const,let) и избежать загрязнения глобального пространства имён, если это необходимо - Больше чем просто данные: Передавайте любой допустимый JavaScript, не только объекты данных. Это включает вызовы функций, условные операторы или код инициализации
- Множественные добавления: Вы можете вызывать
wp_add_inline_script()несколько раз для одного handle, и все скрипты будут выведены.
Продвинутые примеры
Добавление встроенных скриптов без зависимостей
Иногда вам нужно добавить глобальные данные конфигурации или код инициализации без прикрепления к определённому файлу скрипта. С WordPress 5.0 вы можете зарегистрировать скрипт с пустым источником и использовать его как handle для встроенных скриптов:
add_action('wp_enqueue_scripts', function() {
// Регистрируем фиктивный handle без исходного файла.
wp_register_script( 'global', '' );
wp_enqueue_script('global');
// Добавляем встроенный скрипт
$config = [
'apiUrl' => rest_url( 'app/v1' ),
'nonce' => wp_create_nonce( 'wp_rest' ),
'userId' => get_current_user_id()
];
wp_add_inline_script( 'global',
'window.APP_CONFIG = ' . wp_json_encode( $config ) . ';'
);
});
Это выводит чистый встроенный JavaScript без загрузки внешнего файла, идеально подходит для данных конфигурации, которые должны быть доступны глобально до запуска остальных скриптов.
Полное избежание глобальной области видимости
wp_add_inline_script( 'my-script',
'(function() {
const config = ' . wp_json_encode( $config ) . ';
window.myApp = window.myApp || {};
window.myApp.config = config;
})();',
'before'
);
Передача нескольких наборов данных
wp_add_inline_script( 'my-script',
'const API_CONFIG = ' . wp_json_encode( $api_config ) . ';',
'before'
);
wp_add_inline_script( 'my-script',
'const USER_DATA = ' . wp_json_encode( $user_data ) . ';',
'before'
);
Условная инициализация
$init_code = 'if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", initMyApp);
} else {
initMyApp();
}';
wp_add_inline_script( 'my-script', $init_code, 'after' );
Когда использовать каждую функцию
wp_add_inline_script: Всегда. Новые проекты, новые функции, каждый раз, когда вам нужно передать данные или код в JavaScript.
wp_localize_script: Только для актуального перевода/i18n JavaScript-строк, или при поддержке устаревшего кода, где рефакторинг не оправдан.
Переход на новый способ
wp_add_inline_script() доступна с WordPress 4.5 (выпущена в 2016 году). Переход несложный:
// Старый способ
wp_localize_script( 'my-script', 'myData', $data );
// Новый способ
wp_add_inline_script( 'my-script',
'const myData = ' . wp_json_encode( $data ) . ';',
'before'
);
Для подробного руководства по обработке скриптов в WordPress обратитесь к документации WordPress по wp_add_inline_script().

