Верх страницы
Обложка к записи Перестаньте использовать wp_localize_script для передачи данных
Время для прочтения: 1 мин. 41 сек.

Перестаньте использовать 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().

Комментарии
Подписаться
Уведомить о
guest

0 комментариев
Межтекстовые Отзывы
Посмотреть все комментарии
Предыдущая запись
Следующая запись

Давайте дружить
в Telegram

Авторский блог вашего покорного слуги в Telegram про web, программирование, алгоритмы, инструменты разработчика, WordPress, Joomla, Opencart, Symfony, Laravel, Moonshine, фильмы и сериалы