Вопрос по wp_ajax()... не используя wp_enqueue_script?
Привет, ребята, Странная ситуация... Впервые пытаюсь использовать wp_ajax(). Обычно я делаю обычные jQuery AJAX-запросы, но в текущем случае получаю много ошибок, поэтому решил попробовать wp_ajax().
Но не могу разобраться!
Вот этот кусок кода...
// подключаем javascript-файл, который делает AJAX-запрос
wp_enqueue_script( 'my-ajax-request', plugin_dir_url( __FILE__ ) . 'js/ajax.js' );
// объявляем URL файла, обрабатывающего AJAX-запрос (wp-admin/admin-ajax.php)
wp_localize_script( 'my-ajax-request', 'MyAjax', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) );
превращается в...
<script type="text/javascript" src="http://example.com/wordpress/wp-content/plugins/myajax/js/ajax.js"></script>
<script type="text/javascript">
/* <![CDATA[ */
var MyAjax = {
ajaxurl: "http://example.com/wordpress/wp-admin/admin-ajax.php"
};
/* ]]> */
Но у меня нет плагина или чего-то, что должно это использовать, просто вся страница должна делать этот AJAX-запрос. Поэтому первая строка с wp_enqueue_script()
не имеет смысла. Мне не нужно загружать специальный js-файл, так как у меня уже есть мой основной script.js
, вручную подключенный в секции <head>
. Именно оттуда должен отправляться AJAX-запрос. Но если я убираю эту строку (//wp_enqueue_script()...
), то вторая часть не работает.
То есть не выводится:
<script type="text/javascript">
/* <![CDATA[ */
var MyAjax = {
ajaxurl: "http://example.com/wordpress/wp-admin/admin-ajax.php"
};
/* ]]> */
в секции
моей страницы. Что я упускаю? Мне действительно нужно отправлять AJAX-запрос из моего обычного script.js файла.Есть идеи?
Обновление: Мой script.js файл (вручную подключенный в
) должен отправлять AJAX-запрос:var response;
$.post(
// см. совет #1 о том, как мы объявляем глобальные javascript-переменные
MyAjax.ajaxurl,
{
// здесь объявляем параметры для отправки с запросом
// это означает, что будут вызваны следующие хуки:
// wp_ajax_nopriv_myajax-submit и wp_ajax_myajax-submit
action : 'wp_ajax_nopriv_searchmap',
},
function( response ) {
$sr.html(response);
Функция в моем functions.php, которую я хочу вызвать, выглядит так:
// подключаем javascript-файл для AJAX-запроса
wp_enqueue_script( 'my-ajax-request', plugin_dir_url( __FILE__ ) . 'js/ajax.js' );
// объявляем URL файла, обрабатывающего AJAX-запрос
wp_localize_script( 'my-ajax-request', 'MyAjax', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) );
// этот хук срабатывает, если пользователь не авторизован
if (isset($_GET['action'])) {
do_action( 'wp_ajax_nopriv_' . $_GET['action'] );
}
// если авторизован:
if (isset($_POST['action'])) {
do_action( 'wp_ajax_' . $_POST['action'] );
}
if(is_admin()) {
add_action( 'wp_ajax_searchmap', 'my_searchmap_function' );
} else {
add_action( 'wp_ajax_nopriv_searchmap', 'my_searchmap_function' );
}
function my_searchmap_function() {
// Начинаем буферизацию вывода
ob_start();
?>
div>
<h3>Страницы</h3>
<ul>
<?php wp_list_pages('title_li=&depth=0&exclude='); ?>
</ul>
<h3>Записи</h3>
<?php $first = 0;?>
<ul>
<?php
$myposts = get_posts('numberposts=-1&offset=$first');
foreach($myposts as $post) :
?>
<li><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>
<?php endforeach; ?>
</ul>
<h3>Рубрики</h3>
<ul>
<?php wp_list_categories('title_li=&orderby=name'); ?>
</ul>
</div>
<?php
$output = ob_get_contents();
// Завершаем буферизацию
ob_end_clean();
$response = json_encode($output);
// вывод ответа
header( "Content-Type: application/json" );
echo $response;
// ВАЖНО: не забудьте "exit"
exit;
}
Что я не понимаю? Мне просто нужно получать данные через AJAX из моего обычного javascript-файла. Мне нужно обработать HTML, который возвращается в javascript-файле.
Есть идеи, что я делаю не так или, что лучше, что мне нужно сделать, чтобы это заработало?

Хорошо, сначала давайте разберемся немного, чтобы вы поняли назначение этих функций.
-
Описание:
Безопасный способ добавления JavaScript-файлов на страницу, сгенерированную WordPress. По сути, функция включает скрипт, если он еще не был подключен, и загружает тот, который поставляется с WordPress. -
Описание:
Локализует скрипт, но только если он уже был добавлен. Также может использоваться для включения произвольных JavaScript-данных на страницу.
Когда вы локализуете скрипт, вы просто настраиваете действие, которое выводит JavaScript-переменные на страницу, но эти переменные привязаны к скрипту, который вы регистрируете. Это первый параметр, который вы передаете в wp_localize_script
, и он также известен как handle скрипта.
wp_enqueue_script
используется для постановки JavaScript-файла в очередь, а wp_localize_script
предназначен для работы со скриптами, загруженными через систему очередей. Вы не можете локализовать ничего, поэтому, если вы не используете очередь, wp_localize_script
вам здесь не пригодится.
Обычно вы используете эти две функции примерно так:
$myvars = array(
'ajaxurl' => admin_url( 'admin-ajax.php' ),
'somevar1' => $somevar_from_somewhere,
'somevar2' => $somevar_from_elsewhere
);
wp_enqueue_script( 'my-ajax-request', plugins_url( '/path/to/somefile.js', __FILE__ ) );
wp_localize_script( 'my-ajax-request', 'MyAjax', $myvars );
Что затем приводит к следующему выводу на вашей странице:
<script type="text/javascript" src="path/to/somefile.js"></script>
<script type="text/javascript">
/* <![CDATA[ */
var MyAjax = {
ajaxurl: "http://example.com/wordpress/wp-admin/admin-ajax.php",
somevar1: "somevalue",
somevar2: "someothervalue"
};
/* ]]> */
</script>
Который вы можете затем использовать в своем скрипте, например:
jQuery(document).ready( function($) {
alert( MyAjax.somevar1 ); // Выводит somevalue
alert( MyAjax.somevar2 ); // Выводит someothervalue
});
Собрав все вместе, ваш код может выглядеть примерно так:
// Настройка AJAX-обработчика для действия "searchmap"
add_action( 'wp_ajax_searchmap', 'my_searchmap_function' );
add_action( 'wp_ajax_nopriv_searchmap', 'my_searchmap_function' );
// Функция-обработчик для действия "searchmap"
function my_searchmap_function() {
$myposts = get_posts('numberposts=-1&offset=$first');
?>
<div>
<h3>Страницы</h3>
<ul>
<?php wp_list_pages('title_li=&depth=0&exclude='); ?>
</ul>
<h3>Записи</h3>
<ul>
<?php foreach( $myposts as $post ) : setup_postdata( $post ); ?>
<li><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>
<?php endforeach; ?>
<?php wp_reset_postdata(); ?>
</ul>
<h3>Категории</h3>
<ul>
<?php wp_list_categories('title_li=&orderby=name'); ?>
</ul>
</div>
<?php
die;
}
JavaScript (предполагая, что он был добавлен в очередь и локализован):
jQuery(document).ready(function($) {
$('a.myajax').click(function(){
var data = {
action: 'searchmap' // <--- это правильное имя действия
};
$.post( MyAjax.ajaxurl, data, function(response) {
$('#myresult').html(response);
});
return false;
});
});
И затем HTML, необходимый на странице для запуска действия:
<a class="myajax" href="#">Нажмите меня, чтобы получить AJAX-контент</a>
<div id="myresult"></div>
Конкретный ответ
Что касается необходимости выполнить свои собственные действия и вывести переменные для вашего скрипта, я бы предложил сделать что-то вроде этого:
add_action( 'wp_head', 'my_js_vars', 1000 );
function my_js_vars() {
// Если это не нужная страница, останавливаем выполнение
if( !is_page( 'my-page-with-ajax' ) )
return;
?>
<script type="text/javascript">
/* <![CDATA[ */
var MyAjax = {
ajaxurl: '<?php admin_url('admin-ajax.php'); ?>',
somevar: 'somevalue',
someothervar: 'someothervalue'
};
/* ]]> */
</script>
<?php
/*
ПРИМЕЧАНИЕ:
Убедитесь, что после последнего элемента
в JS-массиве нет запятой, иначе IE (Internet Explorer) выдаст ошибку.
*/
}
Я оставил код, который публиковал ранее, для других читателей.

спасибо. Итак, как я могу вызвать функцию внутри моего function.php через ajax? Я обновил свой вопрос. Буду очень благодарен за помощь с этим!

спасибо, а как насчет строк wp_enqueue_script();
и wp_localize_script()
? Нужно ли их оставлять? Должен ли wp_enqueue_script() указывать на ту же директорию, что и мой обычный js-файл (откуда я хочу вызывать ajax)? Потому что иначе я не смогу использовать MyAjax.ajaxurl, { action : 'wp_ajax_nopriv_searchmap', }
для вызова скрипта - ведь MyAjax не существует, если я не использую localize_script? Как будет выглядеть мой javascript для вызова этой функции?

@mathiregister: верно, их нужно оставить. Если вы не используете wp_enqueue_script();
для подключения скрипта в соответствии с правилами WordPress, то не сможете использовать wp_localize_script()
, так как WordPress не будет знать об этом скрипте. Вы можете вывести скрипт и определить URL для AJAX прямо в PHP, но это будет плохой практикой. И последнее: ваш action : 'wp_ajax_nopriv_searchmap'
должен быть action : 'searchmap'
, префикс хука добавляется автоматически.

спасибо, у меня почти получилось сделать так, как я хочу. Последний вопрос: я до сих пор не совсем понимаю, как работает localize_script()? Без него у меня не задается переменная MyAjax в head. Однако, чтобы wp_localize_script() работал, мне нужно использовать wp_enqueue_script(), иначе переменная тоже не будет задана!

Кроме того, я получаю эту ошибку в консоли при каждом 4-м или 5-м вызове POST http://oberperfuss.at/wp-admin/admin-ajax.php undefined (undefined)
. Есть идеи, что может быть причиной?

Возьмите JS-код, который я опубликовал, поместите его в ваш JS-файл, подключите через enqueue и избавьтесь от JS, который вы вставляете напрямую в head. Добавьте это на страницу, загружающую JS-файл.. <a href="#" class="myajax">Click me</a><div id="myresult"></div>
а затем загрузите страницу и кликните по ссылке (сообщите, что произойдет).

Оно уже работает! Мне просто нужно понять, почему нужно использовать enqueue, потому что я не хочу его использовать. Я использую проект head.js для загрузки всех моих скриптов, чтобы моя страница загружалась быстро. Мне просто нужно найти способ подключить admin-ajax.js без использования wp_enqueue_script(). Потому что с wp_enqueue_scritp() строка wp_localize_script() не создает переменную MyAjax.

Это руководство в кодексе дает простое описание процесса:
http://codex.wordpress.org/AJAX_in_Plugins
Обратите внимание, что переменная ajaxurl
уже определена ядром WordPress, но только в административной части. Чтобы добавить ее на фронт-енде, используйте:
<?php
function pluginname_ajaxurl() {
?>
<script type="text/javascript">
var ajaxurl = '<?php echo admin_url('admin-ajax.php'); ?>';
</script>
<?php
}
add_action('wp_head','pluginname_ajaxurl');

Ах, но есть загвоздка - она не всегда определена, я попался на этом, когда попытался использовать... По крайней мере, в моих тестах она была не всегда доступна, особенно для гостевых пользователей.

Отто с примером кода, как определить переменную во фронтенде - http://wordpress.org/support/topic/ajaxurl-is-not-defined?replies=4#post-1989445
