Вопрос по wp_ajax()... не используя wp_enqueue_script?

28 мар. 2011 г., 15:05:59
Просмотры: 13.9K
Голосов: 1

Привет, ребята, Странная ситуация... Впервые пытаюсь использовать 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-файле.

Есть идеи, что я делаю не так или, что лучше, что мне нужно сделать, чтобы это заработало?

0
Все ответы на вопрос 2
10
10

Хорошо, сначала давайте разберемся немного, чтобы вы поняли назначение этих функций.

  • wp_enqueue_script()

    Описание:
    Безопасный способ добавления JavaScript-файлов на страницу, сгенерированную WordPress. По сути, функция включает скрипт, если он еще не был подключен, и загружает тот, который поставляется с WordPress.

  • wp_localize_script()

    Описание:
    Локализует скрипт, но только если он уже был добавлен. Также может использоваться для включения произвольных 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) выдаст ошибку.
    */
}

Я оставил код, который публиковал ранее, для других читателей.

28 мар. 2011 г. 15:48:57
Комментарии

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

mathiregister mathiregister
28 мар. 2011 г. 15:57:13

Обновленный ответ смотри выше. :)

t31os t31os
28 мар. 2011 г. 16:09:13

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

mathiregister mathiregister
28 мар. 2011 г. 16:16:24

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

Bainternet Bainternet
28 мар. 2011 г. 16:49:32

@mathiregister - снова обновил ответ для вас.

t31os t31os
28 мар. 2011 г. 16:56:51

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

mathiregister mathiregister
28 мар. 2011 г. 17:32:50

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

mathiregister mathiregister
28 мар. 2011 г. 17:33:30

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

t31os t31os
28 мар. 2011 г. 17:35:54

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

mathiregister mathiregister
28 мар. 2011 г. 19:08:04

Если вы не подключаете скрипт через очередь, прекратите использовать функцию локализации скриптов - вам придется вручную вставлять свои переменные в head документа, по сути просто повторяя то, что делает wp_localize_script.

t31os t31os
29 мар. 2011 г. 00:41:54
Показать остальные 5 комментариев
3

Это руководство в кодексе дает простое описание процесса:

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');
28 мар. 2011 г. 16:55:43
Комментарии

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

t31os t31os
28 мар. 2011 г. 17:32:38

Действительно, добавил уточнение.

scribu scribu
28 мар. 2011 г. 19:48:23

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

Mario Peshev Mario Peshev
7 окт. 2012 г. 17:31:59