Вопрос или проблема
Я пытаюсь передать переменную из шаблона в js, но безуспешно.
Я пробовал использовать wp_localize_script
, и, похоже, это отлично работает, когда привязано к действию wp_enqueue_scripts
, но не работает, когда вызывается из шаблона. Разве мне остается только использовать HTML и data-
для обработки этого?
Хотя было бы здорово, поскольку я передаю там весь wp_query
.
Моя функция по сути – это обертка над пользовательским WP_Query, которая позволяет реализовать функционал “загрузить больше” на нескольких циклах.
function load_more_scripts() {
wp_register_script( 'loadmore', get_stylesheet_directory_uri() . '/assets/js/myloadmore.js', array( 'jquery' ) );
wp_enqueue_script( 'my_loadmore' );
}
add_action( 'wp_enqueue_scripts', 'load_more_scripts' );
// эта функция позже вызывается в шаблоне
function get_list($query_args) {
if ( is_array( $query_args ) ) {
$the_query = new WP_Query( $query_args );
}
//...еще код
$instance = wp_generate_uuid4();
wp_localize_script( 'loadmore', 'loadmore_params_' . $instance , array(
'ajaxurl' => site_url() . '/wp-admin/admin-ajax.php', // WordPress AJAX
'posts' => json_encode( $the_query->query_vars ), // вся информация о вашем цикле здесь
'current_page' => get_query_var( 'paged' ) ? get_query_var( 'paged' ) : 1,
'max_page' => $the_query->max_num_pages
) );
}
Обновление
Похоже, проблема может заключаться в локализации нескольких скриптов. Если вы регистрируете скрипт для загрузки в подвале, версия без добавления $instance
к load_more_params
вроде бы работает.
Если вы хотите передать весь wp query, вы можете упаковать его в массивы, затем закодировать в json и просто вывести в теге.
<?php my_posts = array();
while ( have_posts() ) : the_post(); ?>
<?php
$properties = array(
'title' => get_the_title(),
'link' => get_the_permalink()
);
$my_posts[] = $properties; ?>
<?php endwhile; wp_reset_query(); ?>
<script>
var posts = <?php echo json_encode($my_posts); ?>;
console.log(posts);
</script>
Конечно, это может быть не лучшая идея с точки зрения безопасности.
Цель wp_localize_script
– напечатать переменную JavaScript там, где загружается конкретный JavaScript файл. Если вы хотите вывести это в шаблоне PHP и потому что это специфическая область, я думаю, вам не нужно использовать wp_localize_script
, просто выведите ее, как
<script>
var posts = <?php echo json_encode($my_posts); ?>;
var current_page = <?php echo get_query_var( 'paged' ) ? get_query_var( 'paged' ) : 1;?>;
var max_page = <?php echo $the_query->max_num_pages;?>
</script>
Нет необходимости выводить ajaxurl, потому что в обновленном WordPress он автоматически выводится.
И, конечно, если вы вызываете зависимый скрипт в конкретном шаблоне, вы можете использовать
function specific_enqueue() {
if ( is_page( 'your template' ) ) {
wp_enqueue_script( 'my_loadmore' );
}
}
add_action( 'wp_enqueue_scripts', 'specific_enqueue' );
Я думаю, что проблемы с безопасностью нет, потому что wp_localize_script
аналогичен echo
, функция выводит переменную в HTML, и каждый может посмотреть это через инспектор.
Ответ или решение
Для передачи переменной из PHP в JavaScript в шаблоне WordPress существует несколько методов, и вы уже на правильном пути, используя wp_localize_script
. Однако, если вы хотите передать переменную непосредственно из шаблона без использования этой функции, это также возможно. Давайте рассмотрим оба подхода.
1. Использование wp_localize_script
Основное предназначение функции wp_localize_script
— передавать данные в JavaScript в контексте конкретного скрипта. Вы можете сделать это более эффективно, если вызовете функцию локализации после регистрации и перед загрузкой скрипта, выпускаемого на экран:
function load_more_scripts() {
// Регистрируем скрипт
wp_register_script('loadmore', get_stylesheet_directory_uri() . '/assets/js/myloadmore.js', array('jquery'));
// Также можно передать данные, если у вас есть информация для передачи
$data = array(
'ajaxurl' => admin_url('admin-ajax.php'), // URL для AJAX
'current_page' => get_query_var('paged') ? get_query_var('paged') : 1,
'max_page' => $the_query->max_num_pages // либо передавайте данные с вашего WP_Query
);
// Локализуем скрипт
wp_localize_script('loadmore', 'loadmore_params', $data);
// Загружаем скрипт
wp_enqueue_script('loadmore');
}
add_action('wp_enqueue_scripts', 'load_more_scripts');
2. Прямое внедрение данных в JavaScript
Если необходимо передать данные непосредственно из шаблона, вы можете сделать это следующим образом:
<?php
$my_posts = array();
while (have_posts()) : the_post();
$properties = array(
'title' => get_the_title(),
'link' => get_the_permalink()
);
$my_posts[] = $properties;
endwhile;
wp_reset_query();
?>
<script>
var posts = <?php echo json_encode($my_posts); ?>;
var current_page = <?php echo get_query_var('paged') ? get_query_var('paged') : 1; ?>;
var max_page = <?php echo $the_query->max_num_pages; ?>; // Передача значения max_num_pages
console.log(posts); // Проверьте результат в консоли
</script>
Примечания по безопасности
При использовании метода внедрения вы должны быть внимательны, особенно если данные, которые вы передаете, включают пользовательский ввод. Всегда старайтесь фильтровать и валидировать данные перед их выводом в JavaScript, чтобы предотвратить XSS-уязвимости. Функция json_encode
в большинстве случаев безопасна, так как она экранирует все специальные символы.
Оптимизация загрузки скриптов в специфических шаблонах
Если вы хотите загружать скрипты только в определенных шаблонах:
function specific_enqueue() {
if (is_page('имя-вашей-страницы') || is_single()) { // Замените условие на свое
wp_enqueue_script('loadmore'); // Обратите внимание, что названия должны совпадать
}
}
add_action('wp_enqueue_scripts', 'specific_enqueue');
Заключение
Пожалуйста, выберите способ, который лучше всего соответствует вашим задачам. Использование wp_localize_script
— это наиболее распространенный метод, тогда как прямой вывод данных в тег <script>
является более простым вариантом, но требует повышенного внимания к безопасности.