Правильная инициализация скриптов в Wordpress или зачем нужен wp_add_inline_script()

Оригинальная статья

Йоу-йоу! С некоторого времени я занимаюсь разработкой сайта для общественной организации защиты животных. Недавно я отослал свой плагин на валидацию и мне прислали ошибку. Суть заключалась в том, что для вставки инлайнового скрипта я использовал примерно такой код:

  • add_action('wp_footer', 'my_print_script');
  • function my_print_script(){
  • ?>
  • <script>
  • /* Код скрипта */
  • </script>
  • <?php
  • }

однако этот код поддержка wordpress’а не одобрила и сказала, чтобы я использовалwp_add_inline_script().

Как работает wp_add_inline_script()

Функция печатает скрипт после какого-то определённого другого скрипта, который был подключен через wp_enqueue_script(). Когда вы используете wp_enqueue_script() то первым параметром передаёте уникальный идентификатор (handler). В wp_add_inline_script() вы первым параметром вводите handler того скрипта после (или перед) которого вы хотите, чтобы был напечатан ваш инлайновый скрипт. Например в статье про построение fancybox-галереи я печатал свой скрипт прямо в html после вывода блоков. Ценой такого исполнения было то, что я оборачивал весь код в window.onload. Код выглядел вот так:

  • wp_enqueue_script( 'application', get_template_directory_uri() . '/js/app.js', array('gjQuery', 'fancybox'), '0.1.0', true );
  • add_action('x_gallery', 'x_gallery');
  • function x_gallery(){
  • $argm = [
  • 'post_type'=>'fgb_fs_gallery',
  • 'orderby'=>'date',
  • 'order'=>'ASC'
  • ];
  • $query = new WP_query($argm);
  • // Сюда в цикле собираем данные о картинках прикреплённых к записям
  • $arr_x = [];
  • $home_url = get_home_url();
  • while ( $query->have_posts() ) : $query->the_post();
  • $postID = get_the_ID();
  • // Для фансибокса
  • $needPostMetaValue = get_post_meta($postID, '_x_id', true);
  • // Кладём в ассоциативнй массив данные о картинках
  • $arr_x[$needPostMetaValue] = get_post_images();
  • ?>
  • <!-- Вёрстка блока который мы выведем -->
  • <!-- data-x-fancy селектор для fancybox -->
  • <div>
  • <a data-x-fancy="<?php echo $needPostMetaValue; ?>" data-src="<?php echo get_the_post_thumbnail_url($postID, 'full');?>" href="javascript:;">
  • <?php echo get_the_post_thumbnail($postID, 'x_face', ['class'=>'w-100']);?>
  • </a>
  • </div>
  • <?php
  • endwhile;
  • // Сюда получаем будем собирать ссылки на картинки
  • $images = [];
  • foreach ($arr_x as $gallery=>$arr){
  • foreach ($arr as $item){
  • $el = wp_get_attachment_image_src( $item['id'], 'full');
  • $images[$gallery][] = $el[0];
  • }
  • }
  • ?>
  • <!-- Печатаем скрипт с вызовам js части -->
  • <script>
  • window.addEventListener('load', function () {
  • <?php foreach ($images as $key=>$value): ?>
  • var <?php echo $key; ?> = new XSLICK({
  • galleryId: '<?php echo $key; ?>',
  • images: [
  • <?php foreach ($value as $item): ?>
  • <?php echo '"' . $item . '",' . PHP_EOL ?>
  • <?php endforeach; ?>
  • ]
  • }, $);
  • <?php endforeach; ?>
  • });
  • </script>
  • <?php
  • }

Сейчас бы код был примерно таким

  • wp_enqueue_script( 'application', get_template_directory_uri() . '/js/app.js', array('gjQuery', 'fancybox'), '0.1.0', true );
  • add_action('x_gallery', 'x_gallery');
  • function x_gallery(){
  • $argm = [
  • 'post_type'=>'fgb_fs_gallery',
  • 'orderby'=>'date',
  • 'order'=>'ASC'
  • ];
  • $query = new WP_query($argm);
  • // Сюда в цикле собираем данные о картинках прикреплённых к записям
  • $arr_x = [];
  • $home_url = get_home_url();
  • while ( $query->have_posts() ) : $query->the_post();
  • $postID = get_the_ID();
  • // Для фансибокса
  • $needPostMetaValue = get_post_meta($postID, '_x_id', true);
  • // Кладём в ассоциативнй массив данные о картинках
  • $arr_x[$needPostMetaValue] = get_post_images();
  • ?>
  • <!-- Вёрстка блока который мы выведем -->
  • <!-- data-x-fancy селектор для fancybox -->
  • <div>
  • <a data-x-fancy="<?php echo $needPostMetaValue; ?>" data-src="<?php echo get_the_post_thumbnail_url($postID, 'full');?>" href="javascript:;">
  • <?php echo get_the_post_thumbnail($postID, 'x_face', ['class'=>'w-100']);?>
  • </a>
  • </div>
  • <?php
  • endwhile;
  • // Сюда получаем будем собирать ссылки на картинки
  • $images = [];
  • foreach ($arr_x as $gallery=>$arr){
  • foreach ($arr as $item){
  • $el = wp_get_attachment_image_src( $item['id'], 'full');
  • $images[$gallery][] = $el[0];
  • }
  • }
  • ob_start(); // Использую для сохранения строки
  • ?>
  • <?php foreach ($images as $key=>$value): ?>
  • var <?php echo $key; ?> = new XSLICK({
  • galleryId: '<?php echo $key; ?>',
  • images: [
  • <?php foreach ($value as $item): ?>
  • <?php echo '"' . $item . '",' . PHP_EOL ?>
  • <?php endforeach; ?>
  • ]
  • }, $);
  • <?php endforeach; ?>
  • <?php
  • $output = ob_get_contents();
  • ob_end_clean();
  • wp_add_inline_script('application', $output, 'after' );
  • }

Самое главное, что я точно знаю, что мой скрипт будет загружен после того в котором лежит код, который я инициализирую. Тоже самое вы можете сделать например с fancybox, slick-slider, datatable, stickjaw и любые скрипты, которые например, зависят от jQuery (иногда это большая боль).

Порядок исполнения wp_add_inline_script()

wp_add_inline_script() может подключатся не только после скрипта, но и перед. Для этого нужно прописть парамерт $position. Вообще у wp_add_inline_script() имеет 3 параметра:

  • $handle (Название (ID) скрипта к которому будут добавлен дополнительный блок скрипта.)
  • $data (Строка содержащая javascript, который нужно добавить. Не нужно указывать открывающий и закрывающий тег script — он добавляется автоматически.)
  • $position (Куда добавить код: до (before) или после (after) указанного в $handle скрипта.)

то есть у $position есть два варианта before и after (по умолчанию). Если before — скрипт подключиться до, если after — после. Это будет полезно если вам, например, нужно объявить глобальные переменные или по каким-то причинам прервать скрипт, который должен выполняться ниже или создать промис или создать элемент.