Постраничная навигация с асинхронной подгрузкой постов в WordPress. Бесконечная прокрутка постов.

Если на моём сайте вы перейдёте на страницу Блог или в какую-нибудь рубрику, то в самом низу страницы, наряду с обычной постраничной навигацией, вы увидите кнопку Загрузить ещё, которая позволяет подгружать следующие посты без обновления страницы.

Скажу прямо, на моём сайте используется в некоторой степени шаманский способ навигации по страницам — эту навигацию я разрабатывал давно и возможно в те времена ещё не был так хорош в PHP и jQuery. Теперь же я вам покажу более правильный и эффективный способ реализации постраничной навигации с возможностью асинхронной загрузки новых постов. То есть в код моего сайта можете не смотреть, а если у вас появятся вопросы, тогда поищите ответы на них в комментариях к этому посту или посмотрите виде.

Работать будем со стандартной темой TwentySeventeen, во-первых, эта тема довольно простая и будет нетрудно разобраться в коде, во-вторых, вы всегда можете установить её прямо из админки из репозитория тем WordPress.

Что мы попробуем сделать в этом посту?

  • Загрузку постов при нажатии на кнопку Загрузить ещё.
  • Бесконечную загрузку, т е посты и комментарии будут подгружаться автоматически при прокрутке страницы (да, как во вконтакте).
  • Сделаем так, чтобы подгрузка постов работала для любых архивов таксономий.

Шаг 1. Добавление кнопки «Загрузить ещё»

Для начала нам надо найти файл, в котором добавляется постраничная навигация. В TwentySeventeen этот файл — прямо index.php. Если вы не понимаете, в каком файле надо искать в вашей теме, рекомендую взглянуть на этот туториал.

Если же вы решили использовать какую-то из стандартных тем (как я), то напоминаю, что для изменений желательно использовать дочерние темы (подробнее на видео в самом низу поста).

Найдите соответствующее место в шаблоне за пределами цикла while, то есть после того, как заканчивается вывод постов (в TwentySeventeen это место практически сразу после endwhile) и вставляем туда код:

<?php if (  $wp_query->max_num_pages > 1 ) : ?>
	<script>
	var ajaxurl = '<?php echo site_url() ?>/wp-admin/admin-ajax.php';
	var true_posts = '<?php echo serialize($wp_query->query_vars); ?>';
	var current_page = <?php echo (get_query_var('paged')) ? get_query_var('paged') : 1; ?>;
	var max_pages = '<?php echo $wp_query->max_num_pages; ?>';
	</script>
	<div id="true_loadmore">Загрузить ещё</div>
<?php endif; ?>
ajaxurl
Это обработчик AJAX-запросов в WordPress.
true_posts
Сериализованный массив, содержащий все необходимые параметры запроса, является свойством класса WP_Query.
current_page
Номер текущей страницы.

А теперь немного стилей, которые мы добавим на нашу кнопку, чтобы она круто выглядела (стили можно вставить в стандартный style.css в папке с темой).

#true_loadmore{
	background-color: #ddd; /* сервый фон */
    	border-radius: 2px; /* закругление углов */
    	display: block; /* блочный элемент, на случай, если захотите использовать <a> */
    	text-align: center; /* выравнивание текста по центру */
    	font-size: 14px; font-size: 0.875rem; /* размер шрифта */
    	font-weight: 800; /* начертание */
    	letter-spacing: 1px; /* межбуквенный интервал */
    	cursor: pointer; /* курсор мыши при наведении такой же, как при наведении на ссылку */
    	text-transform: uppercase;
    	padding: 10px 0; /* внутренние отступы сверху и снизу у кнопки */
    	transition: background-color 0.2s ease-in-out, border-color 0.2s ease-in-out, color 0.3s ease-in-out; /* CSS-анимация*/
}
#true_loadmore:hover{
	background-color: #767676;
	color: #fff;
}

Успешным выполнением первого шага будет считаться вот такая кнопка, которая должна будет появиться на странице всех ваших записей, но имейте ввиду, что если записей недостаточно для двух страниц, то кнопки не будет, для этого либо создайте больше записей, либо перейдите в Настройки > Чтение и измените количество отображаемых на странице записей там.

Кнопка асинхронной бесконечной загрузки постов

Самый легкий шаг позади.

Шаг 2. Подключение скриптов jQuery

Документация функций wp_enqueue_script() и get_stylesheet_directory_uri() в помощь. Про подключение скриптов я писал часто и подробно, поэтому сейчас на этом останавливаться не будем, если есть проблемы — смотрите документацию. А этот код — в functions.php.

function true_loadmore_scripts() {
	wp_enqueue_script('jquery'); // скорее всего он уже будет подключен, это на всякий случай
 	wp_enqueue_script( 'true_loadmore', get_stylesheet_directory_uri() . '/loadmore.js', array('jquery') );
}
 
add_action( 'wp_enqueue_scripts', 'true_loadmore_scripts' );

Шаг 3. Скрипт асинхронной загрузки

Вы ещё не создали файл loadmore.js в папке с темой? Давайте создадим его и добавим туда следующий код:

jQuery(function($){
	$('#true_loadmore').click(function(){
		$(this).text('Загружаю...'); // изменяем текст кнопки, вы также можете добавить прелоадер
		var data = {
			'action': 'loadmore',
			'query': true_posts,
			'page' : current_page
		};
		$.ajax({
			url:ajaxurl, // обработчик
			data:data, // данные
			type:'POST', // тип запроса
			success:function(data){
				if( data ) { 
					$('#true_loadmore').text('Загрузить ещё').before(data); // вставляем новые посты
					current_page++; // увеличиваем номер страницы на единицу
					if (current_page == max_pages) $("#true_loadmore").remove(); // если последняя страница, удаляем кнопку
				} else {
					$('#true_loadmore').remove(); // если мы дошли до последней страницы постов, скроем кнопку
				}
			}
		});
	});
});

Я постарался сделать этот код максимально простым, дополнительными переменными усложнять его не стал. Если вы хотя бы немного разбираетесь в jQuery, то у вас не возникнет с ним никаких проблем. Даже если не разбираетесь, но сделаете всё по инструкции, то всё тоже будет ок.

Шаг 4. Обработчик PHP, вывод постов

Этот код также отправляется в файл functions.php. Если он вам непонятен, читайте подробнее про WP_Query и query_posts().

<?php
function true_load_posts(){
 
	$args = unserialize( stripslashes( $_POST['query'] ) );
	$args['paged'] = $_POST['page'] + 1; // следующая страница
	$args['post_status'] = 'publish';
 
	// обычно лучше использовать WP_Query, но не здесь
	query_posts( $args );
	// если посты есть
	if( have_posts() ) :
 
		// запускаем цикл
		while( have_posts() ): the_post();
 
			get_template_part( 'template-parts/post/content', get_post_format() );
 
		endwhile;
 
	endif;
	die();
}
 
 
add_action('wp_ajax_loadmore', 'true_load_posts');
add_action('wp_ajax_nopriv_loadmore', 'true_load_posts');

Бесконечная загрузка постов при прокрутке страницы.

Суть в том, что вы просто скроллите страницу вниз, а новые посты подгружаются по мере её прокрутки. Насколько я помню, впервые такая штука появилась у твиттера (могу ошибаться, поправьте, если я не прав), а потом уже все стянули её оттуда.

Скажу честно — заразная вещь. Те, кто сидят на сайте вконтакте, понимают это прекрасно. Так что, если у вас новостной сайт, тогда этот способ загрузки постов просто «must have».

Если вы сделали все предыдущие шаги из поста и дошли до этого момента — тогда отлично, добавим некоторые изменения для шагов 1 и 3.

Во-первых, кнопка Загрузить ещё нам больше не понадобится, поэтому немного изменим HTML-код:

<?php if (  $wp_query->max_num_pages > 1 ) : ?>
	<script id="true_loadmore">
	var ajaxurl = '<?php echo site_url() ?>/wp-admin/admin-ajax.php';
	var true_posts = '<?php echo serialize($wp_query->query_vars); ?>';
	var current_page = <?php echo (get_query_var('paged')) ? get_query_var('paged') : 1; ?>;
	</script>
<?php endif; ?>

Во-вторых, стили CSS нам тоже больше не нужны, если вы их добавляли, можете напрочь удалить.

В-третьих, содержимое файла loadmore.js изменится и будет следующим:

jQuery(function($){
	$(window).scroll(function(){
		var bottomOffset = 2000; // отступ от нижней границы сайта, до которого должен доскроллить пользователь, чтобы подгрузились новые посты
		var data = {
			'action': 'loadmore',
			'query': true_posts,
			'page' : current_page
		};
		if( $(document).scrollTop() > ($(document).height() - bottomOffset) && !$('body').hasClass('loading')){
			$.ajax({
				url:ajaxurl,
				data:data,
				type:'POST',
				beforeSend: function( xhr){
					$('body').addClass('loading');
				},
				success:function(data){
					if( data ) { 
						$('#true_loadmore').before(data);
						$('body').removeClass('loading');
						current_page++;
					}
				}
			});
		}
	});
});

Файл functions.php (это шаги 2 и 4) мы оставляем без изменений.

Надеюсь, что не запутал вас. Если возникнут трудности или какие-то вопросы, вот вам видео:

А чуть ниже можете почитать комментарии.

Миша

В последние годы я долго не знал, что мне делать с сайтом misha.blog, ведь он практически не приносит никакого профита, но недавно я осознал, что моя миссия – способствовать распространению WordPress. Ведь WordPress – это лучший движок для разработки сайтов – как для тех, кто готов использовать заложенную структуру этой CMS, так и для тех, кто предпочитает headless решения.

Сам же я впервые познакомился с WordPress в 2009 году. Организатор WordCamp. Преподаватель в школах Epic Skills и LoftSchool.

Если вам нужна помощь с вашим сайтом или может даже разработка с нуля на WordPress / WooCommerce — пишите. Я и моя команда сделаем вам всё на лучшем уровне.

Комментарии — 323

Комментирование этого поста более не доступно.
  • Эльдар 18 июля 2014 #

    Спасибо!! Очень ждал этого поста)))

    А этим способом можно сделать подгрузку сразу для 3 циклов на одной странице?

    • Миша 18 июля 2014 #

      да, конечно) немного доработав. Тут главное учесть, что элементов с одинаковыми HTML-атрибутами id не должно быть на странице.

    • Алексей 4 февраля 2016 #

      Люди, кто уже пытался реализовать несколько циклов на одной странице? Подскажите как это сделать?

      • Миша 5 февраля 2016 #

        Изменить название переменных, ID кнопки поменять на класс.. 🙂

        • Алексей 5 февраля 2016 #

          Изменил, теперь циклы работают одновременно и выводятся одинаковые посты с категории последнего цикла 🙁

          • Миша 8 февраля 2016 #

            Ну смотрите, на самом деле тут больших сложностей быть не должно, поэтому я постараюсь объяснить.

            Когда у нас была только одна подгрузка на странице, то всё было просто, было несколько переменных и кнопка с определенным ID, код к ним обращался и всё ок.

            Если же нужно сделать несколько подгрузок, то тут два варианта, либо скопировать полностью весь код и заменить названия всех переменных и ID кнопок сменить. Это простой способ. Он плох тем, что если нужно будет третью подгрузку сделать, то по новой всё копировать.

            Хороший же вариант, сделать всё по классам и по относительным обращениям к элементам (слова русские, смысл непонятен 🙂

            В шаге 1 например перменную ajaxurl не трогаем, она остается одинаковой, зато другие перменные лучше попробовать затолкать в атрибуты кнопки, например data-posts, data-current-page — в итоге мы будем обращаться к ним через $(this), а значит относительно.

            В третьем же шаге, нужно сделать так, чтобы можно было нажать любую кнопку и получить один результат, для этого мы добавляем кнопкам одинаковый класс и обращаемся по нему. Затем в функции надо сделать замены вот такого типа, например меняем:

            'page' : current_page

            на

            'page' : $(this).attr('data-current-page')
      • Миша 27 февраля 2016 #

        Как реализовать несколько кнопок «Загрузить ещё» на одной странице

        Прежде всего, давайте условимся следующим:

        1. Дополнительные циклы на странице мы будем задавать при помощи WP_Query.
        2. Подгрузка постов будет начинаться только с 1-й страницы — конечно все эти моменты вы сами сможете потом доработать, но давайте начнём с простого?

        Допустим вы уже поставили одну кнопку подгрузки постов и она у вас заработала — отлично! Остальные изменения будут касаться только Шагов 1 и 3.

        Изменения в шаге 1

        Для начала вынесем эту переменную куда-нибудь отдельно, например в <head> сайта:

        <script>
        	var ajaxurl = '<?php echo site_url() ?>/wp-admin/admin-ajax.php';
        </script>

        Как я уже говорил, посты будут начинаться всегда с первой страницы, поэтому изменённый код будет выглядеть следующим образом:

        <?php if (  $wp_query->max_num_pages > 1 ) : ?>
        	<div class='true_loadmore' data-current="1" data-true-posts='<?php echo serialize( $wp_query->query_vars ); ?>' data-max-pages='<?php echo $wp_query->max_num_pages; ?>'>Загрузить ещё</div>
        <?php endif; ?>

        Этот код кнопки нужно добавить после каждого цикла! Предпочтительно перед endif;. Конечно, если дело касается дополнительных циклов, вам следует заменить $wp_query на название соответствующего объекта WP_Query.

        Изменение в шаге 3

        Тут всё просто — всё, что вам нужно, это заменить код в .js-файле на следующий:

        jQuery(function($){
        	$('.true_loadmore').click(function(){
        		var loadmore = $(this),
        		    current_page = loadmore.data( 'current' );
        		loadmore.text('Загружаю...'); // изменяем текст кнопки, вы также можете добавить прелоадер
        		var data = {
        			'action': 'loadmore',
        			'query': loadmore.data('true-posts'),
        			'page' : current_page
        		};
        		$.ajax({
        			url:ajaxurl, // обработчик
        			data:data, // данные
        			type:'POST', // тип запроса
        			success:function(data){
        				if( data ) { 
        					loadmore.text('Загрузить ещё').before(data); // вставляем новые посты
        					current_page++; // увеличиваем номер страницы на единицу
        					loadmore.attr( 'data-current', current_page );
        					if (current_page == loadmore.data('max-pages') ) loadmore.remove(); // если последняя страница, удаляем кнопку
        				} else {
        					loadmore.remove(); // если мы дошли до последней страницы постов, скроем кнопку
        				}
        			}
        		});
        	});
        });
        • Александр 21 февраля 2020 #

          current_page++; // увеличиваем номер страницы на единицу
          она здесь присваивается каждому из циклов
          и клик по 'Загрузить ещё' другого цикла перескакивает одну страницу

          • Миша 21 февраля 2020 #

            Спасибо большое за вашу внимательность! Поправил код.

  • Андрей 26 июля 2014 #

    Хорошая статья, только я передавал у себя не запрос, а конкретные данные к запросу, когда писал шаблоны)

    Еще, для чего использовать эту конструкцию?

    $q->post->ID

    Функия the_post() автоматом строит переменную $post или я ошибаюсь?

    • Миша 26 июля 2014 #

      Потому что у нас не the_post(), а $q->the_post().

      • Андрей 26 июля 2014 #

        А это не имеет значение, вызов данная функция для того и предназначена, чтобы установить переменную $post. В функциях же остальных не используется ваша конструкция, а только эта переменная...

        • Миша 26 июля 2014 #

          Похоже, что я не совсем понимаю, о чем вы говорите — так какой в итоге способ получения ID поста вы предлагаете?

          Что может быть проще, чем вытащить ID прямо из объекта поста, который мы уже имеем?

          • Андрей 26 июля 2014 #

            Писать не $q->post->ID, а $post->ID (:

            • Миша 26 июля 2014 #

              Так тоже будет работать, на мой взгляд $q->post->ID будет нагляднее прост при дальнейшей работе с кодом 🙂

              • Андрей 26 июля 2014 #

                Хозяин-барин (:

                PS Наверное думаете, что ему нужно от меня )))

                • Дима 19 марта 2015 #

                  Как оказалось (внезапно), на кастомных запросах $post может и не работать сам по себе. Т.е., чтобы заработало через $post, похоже, надо ещё ему сделать setup_postdata.

                  А вот $q->post прекрасно себе работает без дополнительных телодвижений.

  • Александр 6 августа 2014 #

    Все это круто, но я отказался от бесконечного скроллинга в силу того, что большинство юзеров открывают пост на этой же странице и, возвращаясь назад, попадают в начало. Здесь та же тема. Например, я нажал на 4 страницу, а потом подгрузил еще три, открыл пост на седьмой и по кнопке "назад" меня перекинуло опять на четвертую.

    • Андрей 7 августа 2014 #

      Так это все реализуемо, нужно лишь чуть поработать с JS для изменения текущего URL.

      • Александр 7 августа 2014 #

        Это ж надо поработать 😀

        • Андрей 7 августа 2014 #

          Ну так, не всегда же халявить (:

  • Jason 7 августа 2014 #

    Спасибо, забрал себе) Смущает только то, что с индексацией такого контента будут траблы.
    А как это дело немного припрятать от посторонних глаз? Пробовал во внешний файл, но тогда не работает..

    • Миша 7 августа 2014 #

      Ну ajax это всегда проблемы с индексацией.
      Можете попробовать добавить еще и обычную постраничную навигацию, а потом просто скрывать ее через jQuery.

  • Иван 11 августа 2014 #

    Здравствуйте, я использую в цикле the_loop для вставки миниатюр в background такой код:
    if (have_posts()) : while (have_posts()) : the_post();
    $id = get_post_thumbnail_id( );
    $background_url = wp_get_attachment_image_src( $id );?>
    ....
    <div style="background-image: url('');">
    Но когда я вставил его в 4 пунк:
    ....
    $q = new WP_Query($args);
    if( $q->have_posts() ): while($q->have_posts()): $q->the_post();
    $id = get_post_thumbnail_id( );
    $background_url = wp_get_attachment_image_src( $id );?>
    ....
    <div style="background-image: url('');">

    То он перестал работать. Посты выводятся, а background'а нет. Как решить эту проблему?

  • Иван 11 августа 2014 #

    В url('') находится .
    Не напечаталось почему то.

  • Иван 11 августа 2014 #

    Извиняюсь. Код внезапно заработал.

  • Илья 25 августа 2014 #

    Зачем так путать? У меня проблемы начались на моменте когда второй раз добавляю код в functions.php . Тупо белый экран.

    • Миша 25 августа 2014 #

      А вы убрали первую строку с <?php ?

  • Илья 25 августа 2014 #

    не убрал

  • Илья 25 августа 2014 #

    Вообщем, скрипт настроил пашет, но не так как нужно. У меня на страницах миниатюры записей идут но когда пролистываешь, внизу появляются полные записи а нужно чтобы так же выводились анонсы.
    Подгруженные посты появляются сразу, у поользователя нет выбора и шанса увидеть подвал сайта. Как можно исправить? Заранее большое человеческое благодарю.

    • Миша 25 августа 2014 #

      1) Для решения первой проблемы вот код, который нужно добавить в обработчик PHP:

      global $more;
      $more=0;

      2) Уберите автоматическую подгрузку, пусть посты подгружаются при нажатии на кнопку.

      • Роман 26 сентября 2014 #

        Миша, добрый день! А куда именно нужно добавить код "global $more; ... и т.д." у меня та же проблема.

        • Миша 26 сентября 2014 #

          Добрый день!
          Попробуйте добавить либо непосредственно перед либо непосредственно после 5-й строчки.

          • Роман 26 сентября 2014 #

            Не помогло к сожалению, выводятся посты целиком. Но всё равно спасибо за оперативный ответ! Буду искать.

            • Миша 26 сентября 2014 #

              ещё попробуйте:

              $more=1;
              • Роман 26 сентября 2014 #

                Тоже не решает 🙁

                • Виталий 2 октября 2014 #

                  а если такой функцией попробовать

                • Виталий 2 октября 2014 #

                  the_content_limit(700);

                  • Миша 3 октября 2014 #

                    Лучше бы конечно вам разобраться с оригинальным выводом через the_content(), если вооще никакие способы не срабатывают, экспериментируйте. Я бы вам посоветовал поискать в интернете функцию truncate_post() — она не стандартная, но оч хорошо обрезает контент.

  • laki 20 октября 2014 #

    а сортировка, опубликованные и не опубликованные посты разве не нужна?)

    • Миша 21 октября 2014 #

      эти параметры по идее уже включены 🙂
      или что вы имеете ввиду?

      • lakispy 21 октября 2014 #

        где же они включены?

        имею ввиду вот это:

        $post_status = get_post_status( $post_id );
        if($post_status == 'publish')
        echo

  • lakispy 21 октября 2014 #

    Просто в конкретно моем случае, за отображение и скрытие постов в категориях, архивах и на главной отвечает плагин Advanced Category Excluder, а он никак не связан с дальнейшей подгрузкой постов на странице.

  • lakispy 21 октября 2014 #

    или не в нем проблема, в общем:
    1) подгружаются черновики
    2) при первом нажатии подгрузки выводятся новые записи+3 старые, то есть на странице 10 записей, а он подгружает 7 новых и 3 старых. В последующем цикле подгрузки все ок.

    • Миша 22 октября 2014 #

      Ваши обе проблемы связаны с подгрузкой черновиков. По идее все параметры уже должны были быть включены в переменную true_posts.

      Также вы можете попробовать обновить участок кода:

      <?php
      function true_load_posts(){
      	$args = unserialize(stripslashes($_POST['query']));
      	$args['paged'] = $_POST['page'] + 1; // следующая страница
      	$args['post_status'] = 'publish';
      • lakispy 5 ноября 2014 #

        Извиняюсь, не ответил. Проблему черновиков это конечно решило, но главная проблема в подгружаемых старых записях. Честно говоря, надоело искать решения и решил пойти методом тыка по плагинам. И наткнулся на "лекарство от головной боли", плагин Infinite Scroll, он привязывается к css, подменяя пагинацию на сайте. То есть двойной плюс, на сайте сохраняется постраничная навигация, что в принципе полезно для SEO и у него есть любой вариант подгрузки включая и кнопкой (manual trigger), НО именно вариант с кнопкой адаптировали только для стандартных шаблонов. На github разжевывают настройку, которой естественно нет в русифицированном виде. Не желаете ли русифицированное FAQ сделать, думаю это актуально?)

        • Миша 6 ноября 2014 #

          но главная проблема в подгружаемых старых записях.

          Расскажите пожалуйста про эту проблему, это важно.

          плагин Infinite Scroll

          Возможно когда-нибудь я напишу обзор этого плагина... 🙂

          • lakispy 6 ноября 2014 #

            Изначально я код удалил, после нескольких попыток не увенчавшихся успехом. Сейчас поставил по новой и все работает. Может кому пригодится, вот код разделения в две колонки:

            Ниже новый код, вместо ранее добавленного в functions.php

            function true_load_posts(){
            	$args = unserialize(stripslashes($_POST['query']));
            	$args['paged'] = $_POST['page'] + 1;
            	$args['post_status'] = 'publish';
            	$q = new WP_Query($args);
            	if( $q->have_posts() ): $first = true;  ?>
             
            		<ul class="post-list">
             
            		<?php while($q->have_posts()): $q->the_post();
            			if($first) $class = "post first-in-row";
            			else $class="post";
            			$first = !$first;
            		?>
            			<!-- Start: Post -->
             
            		<li id="post-<?php echo $q->post->ID ?>" <?php post_class($class); ?>>
            <!-- Тут блок одного поста -->
            </li>
            <!-- End: Post -->
            			<?php
            		endwhile; ?>
            <div class="clear"></div></ul>
            <?php endif;
            	wp_reset_postdata();
            	die();
            }

            Это в CSS:

            .post-list {overflow: hidden;list-style: none;width: 650px;display: inline;}
            .post-list li.post {overflow: hidden;margin: 0 40px 16pt 0;width: 300px;float: left;}
            .post-list li.first-in-row {clear: left;}
            .clear {height: 0;margin: 0;padding: 0;clear: both;float: none;overflow: hidden;border: none;}

            Чтобы все адекватно выглядело, естественно нужно переделать и основной шаблон под отображение в две колонки.

            Кстати, Михаил у вас подписка на сообщения с ошибкой в ссылке: "Anchor/comment-2760truemisha.ru/blog/wordpress/ajax-pagination.html"

            • Миша 6 ноября 2014 #

              Окей, спасибо!

            • Миша 8 ноября 2014 #

              подписка на сообщения с ошибкой в ссылке

              А можно подробнее? Действительно нашёл баг, связанный с подпиской на комментарии, но не тот, который вы описывали.

              • laki 10 ноября 2014 #

                Письмо:

                Появился новый комментарий к посту:
                Постраничная навигация с асинхронной подгрузкой постов в WordPress. Бесконечная прокрутка постов..
                 
                Если вы хотите отписаться от уведомлений, перейдите по ссылке.

                Ссылка на анкор "Постраничная на... ...прокрутка постов..":

                http://anchor/comment-2780truemisha.ru/blog/wordpress/ajax-pagination.html

                Ссылка генерится с приставкой в начале (anchor/comment-2780), которая по идее должна быть в конце через диез.

                (В идеале должно быть так: truemisha.ru/blog/wordpress/ajax-pagination.html#comment-2780)

                • Миша 10 ноября 2014 #

                  Давайте тогда вместе протестируем 🙂 Сейчас я подпишусь на эту ленту, а вы оставите комментарий.

                  Просто дело в том, что я буквально недавно смотрел письма по подпискам - всё было ок, все ссылки рабочие.

                  • laki 11 ноября 2014 #

                    Тестируем)

                    • Миша 11 ноября 2014 #

                      У меня всё ок 🙂 ссылки рабочие. У вас по-прежнему http://anchor?

                    • laki 11 ноября 2014 #

                      Все так же

                      /Anchor/comment-2819truemisha.ru/blog/wordpress/ajax-pagination.html

                    • Миша 11 ноября 2014 #

                      Блин, даже не знаю, проверю ещё раз код.

  • Леонид 21 октября 2014 #

    Мне непонравился момент, где на страничку добавляется стиль, который скрывает кнопку для загрузки дальнейшего контента. Я сделал немного по-другому:

    В скрипте, где мы получаем ajax url и другие параметры можно добавить переменную "maxPages", с которой мы в дальнейшем сравним "currentPage" и удлим кнопку, если страницы совпадают.

    var ajaxurl = '<?php echo site_url() ?>/wp-admin/admin-ajax.php';
    var true_posts = '<?php echo serialize($wp_query->query_vars); ?>';
    var current_page = <?php echo (get_query_var('paged')) ? get_query_var('paged') : 1; ?>;
     var max_pages = '<?php echo $wp_query->max_num_pages; ?>';
    $.ajax({
        url: ajaxurl, 
        data: data,
        type: "POST", 
        success: function(data){
          if( data ) { 
            $("#true_loadmore").before(data); 
            currentPage++; 
            if (currentPage == maxPages) { $("#true_loadmore").remove();  }
          } else {
            $("#true_loadmore").remove(); 
          }
        }
      });
    • Миша 22 октября 2014 #

      Согласен, что такой вариант более оптимален, на днях обновлю код в статье.

  • Юра 4 ноября 2014 #

    А как задать количество подгружаемых постов в этом примере?

    • Миша 4 ноября 2014 #

      В админке в Настройки > Чтение по идее.

      • Дима 18 марта 2015 #

        Ну или через
        $args['posts_per_page'] = нужное число постов;
        перед запросом
        new WP_Query($args).

        P.S.: Спасибо за статью, Миша. Наконец-то я вкурил в AJAX )))

        • Миша 18 марта 2015 #

          Пожалуйста! Рад помочь)

  • bvv 4 ноября 2014 #

    Поставил и настроил скрипт - все работает.
    Была та же проблема, что и у lakispy - выводились повторные записи.
    Применил предложенное решение - помогло.

    Теперь то ли в конце загруженной страницы (начиная со второй), то ли в начале (начиная с третьей) откуда-то стал выводиться 0.
    Причем если прокрутить до конца (записей больше нет), то эти нули в последней строке начинают плодиться.

    • Миша 4 ноября 2014 #

      Функция die() точно есть в конце функции-обработчика?

      • bvv 4 ноября 2014 #

        Спасибо!
        Удалил, когда экспериментировал с фразой "можно удалить строки с 31 по 35".
        Наверное просчитался... 🙂

  • Роман Яковлев 7 января 2015 #

    Спасибо за пост.
    В файле functions после

    while($q->have_posts()): $q->the_post();

    необходимо прописать

    global $post; $cvalue =get_post_meta($post->ID, $page_value, true);

    .
    После этого внутри можно разместить любые пользовательские функции . Без этого пользовательские функции не отображаются.

  • Алексей 10 января 2015 #

    Доброго времени суток! Статья очень помогла, но есть проблема. У меня подгружаются дополнительные данные из плагина, эти данные я вставляю при помощи shortcode:

    К сожалению, вместо того чтобы вывести результат обработки shortcode, мне выводится сам шорткод [site_show_price] . Помогите пожалуйста разобраться с этой проблемой.

    • Миша 10 января 2015 #

      Добрый день!
      Думаю, что это решение вашей проблемы.

  • Ильдар Хакимов 11 января 2015 #

    Бесит такая штука в контакте, когда хочешь в подвал, чтобы перейти по ссылке "Разработчика", а тебя все не пускает и не пускает, приходиться заходить в "Документы", а оттуда в подвал. Хотя для задержания крутая тема, жаль по нажатию на ESC функция не отключается.

    • Миша 12 января 2015 #

      Хороший пример — facebook.com

    • Миша 12 января 2015 #

      Там конечно на ESC не отключается подгрузка, но футер оч хорошо продуманю

  • Ильдар Хакимов 11 января 2015 #

    И мне хотелось бы такую функцию к странице, которая разбита на 200 подстраниц, а не к категориям.

  • deSiter 16 января 2015 #

    Чувак, спасибо! Пол дня сладить пытался, а по твоей инструкции за 20 минут заработало!

    • Миша 17 января 2015 #

      Пожалуйста! Рад, что смог помочь)

  • Витя mateas 18 января 2015 #

    А как сделать чтобы и постраничная навигация оставалась и кнопка загрузить еще работала, как у вас в блоге?

    • Миша 19 января 2015 #

      Делаете кнопку «загрузить ещё», а потом рядом добавляете функцию постраничной навигации.

      Также надо сделать, чтобы кнопка понимала, на какой странице сейчас находимся.

      • Евгений 29 января 2015 #

        А не подскажите код?

        Пользуюсь Вашим решением, нажимаю "показать еще" -- добавляются блоки, а навигация в свою очередь обновляет страницу, на которой находится... (яркий пример --- pobeda-design.ru/news/ ) Очень помогли бы... с ajax не дружу =((...

        • Евгений 29 января 2015 #

          Или как у вас на сайте.. это бы просто спасло меня, весь день промучался сегодня..

          • Миша 30 января 2015 #

            Боюсь, что мой код вам не подойдёт — слишком уж там я всего наколдовал. Если хотите, могу написать скрипт непосредственно для вашего сайта — тогда просто свяжитесь со мной по email или vk.

            • Евгений 30 января 2015 #

              Мне бы Ваш ajaх запрос, а дальше я бы под себя подогнал уже, и остальное дописал... =)

              • Миша 30 января 2015 #

                В двух словах — функция, которая выводит список страниц, находящаяся в PHP-обработчике, имеет параметр текущей страницы. А этот параметр в любом случае передаётся через ajax (в данном посту current_page).

  • Рома 31 января 2015 #

    Привет, у меня ничего не работает. Использовал в теме Twenty Twelve, но никаких действий нет. Если нужно изменить html код в php обработчике на код шаблона из Twenty Twelve, то какой?

    • Миша 1 февраля 2015 #

      Привет!
      а что конкретно не работает?

  • Рома 1 февраля 2015 #

    кнопка не работает. никаких действий не происходит. сделал все по уроку, кнопка есть, но погрузки постов нет.

    • Миша 1 февраля 2015 #

      jquery.js и loadmore.js подключились? в HTML они присутствуют?

      • Рома 1 февраля 2015 #

        да, loadmore.js подключил, как в уроке, jquery.js подключено по ссылке

  • Рома 1 февраля 2015 #

    и вдруг всё чудесным образом заработало)

    • Миша 1 февраля 2015 #

      отлично! )

      • Рома 1 февраля 2015 #

        возникла еще одна проблема. при нажатии на кнопку подгрузки вместо текста "загрузка" на кнопке, какие-то иероглифы, и так далее вместо надписи "загрузить ещё" тоже иероглифы. Что-то с кодировкой. Не подскажешь, как в скрипте loadmore.js, изменить кодировку? Или где-то ещё..
        Спасибо

        • Миша 1 февраля 2015 #

          подскажу »

          • Миша 1 февраля 2015 #

            Если не поможет - пишите прямо в комментариях к той статье, разберемся по ходу.

  • Дмитрий 4 февраля 2015 #

    Пожалуйста, помогите решить проблему: после того как добавляю код с подключением jquery и loadmore.js - при обновлении страницы весь текст на странице превращается в иероглифы, картинки растягиваются на аномально большую высоту. Как исправить?

    • Миша 5 февраля 2015 #

      Хм.. а ваш сайт есть в сети? Можно глянуть?

      • Дмитрий 5 февраля 2015 #

        Нет в сети, нету. А какая информация может помочь выявить проблему?

      • Дмитрий 5 февраля 2015 #

        Вот все исправил, проблема была в малом опыте с PHP. Теперь все работает но кое-что не нравится: новые посты выводятся поверх других. Вообще для вывода записей использую Masonry, не знаю как исправить...

        • Миша 6 февраля 2015 #

          Попробуйте инициализировать Masonry после каждой подгрузки постов. Просто предположение.

          • Дмитрий 6 февраля 2015 #

            Знал бы как...

            • Миша 6 февраля 2015 #

              Ну оно же у вас инициализируется при загрузке страницы, там где параметры указываете ещё. Вот просто скопируйте эту строку в конец функции success у ajax-запроса. Как-то так 🙂

              • Дмитрий 8 февраля 2015 #

                Masonry инициализируется скриптом в и этот скрипт я скопировал в конец функции succes но результата не дало...

  • Дмитрий 10 февраля 2015 #

    Не подскажите, как сделать чтобы подгружались посты только из определенной категории?

    • Миша 11 февраля 2015 #

      В обработчике PHP из 4-го шага добавить строку в начале:

      $args['cat'] = 5'; // ID категории
      • Дмитрий 11 февраля 2015 #

        Вывожу вот так и при нажатии на кнопку ничего не происходит...

        <div id="latest-news-container">
         
         
                        <?php if(have_posts()) : query_posts($query_string.'&cat=(),2&posts_per_page=2'); ?>
                        <?php while(have_posts()) : the_post(); ?>
         
         
                        <div id="latest-news-block">
                            <h2><a class="news-name" href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>
                            <a href="<?php the_permalink(); ?>">
                                <?php the_post_thumbnail(); ?>
                            </a>
                            <p><?php the_excerpt(); ?></p>
                            <a href="<?php the_permalink(); ?>" class="news-date"><i class="fa fa-clock-o fa-1x"></i> <?php the_time('j M Y') ?></a>
                            <a href="<?php the_permalink(); ?>" class="news-more-link">Читать далее <i class="fa fa-arrow-right fa-1x"></i></a>
                        </div>
         
         
         
         
                        <?php endwhile; ?>
         
                        <!--<div>
                            <?php posts_nav_link(); ?>
                        </div>-->
         
         
         
                        <?php if (  $wp_query->max_num_pages > 1 ) : ?>
        	<script>
        	var ajaxurl = '<?php echo site_url() ?>/wp-admin/admin-ajax.php';
        	var true_posts = '<?php echo serialize($wp_query->query_vars); ?>';
        	var current_page = <?php echo (get_query_var('paged')) ? get_query_var('paged') : 1; ?>;
        	var max_pages = '<?php echo $wp_query->max_num_pages; ?>';
        	</script>
        	<div id="true_loadmore">Загрузить ещё</div>
        <?php endif; ?>
         
         
         
         
         
                        <?php endif; ?>
                        <?php wp_reset_query(); ?>
         
         
                    </div>
        • Миша 11 февраля 2015 #

          Ну во-первых, условие have_posts() должно быть после функции query_posts().

          Во-вторых, рекомендую смотреть код через Ctrl + U, чтобы видеть, что происходит.

          В-третьих, у вас в коде: &cat=(),2. Это что?

          В-четвертых, всегда проверяйте, работает ли у вас jQuery-код, например так:

          <script>
          jQuery(function(){
          alert('OK!');
          });
          </script>
          • Дмитрий 11 февраля 2015 #

            Большое спасибо, все заработало как только выполнил пункт "Во-первых".

            • Миша 12 февраля 2015 #

              Отлично!

              • Дмитрий 12 февраля 2015 #

                А подскажите, как вставить вместо текста блок, параграф или что-то еще - конструкцию.

                • Миша 13 февраля 2015 #

                  Вместо какого текста?)

                  • Дмитрий 13 февраля 2015 #

                    Вместо текста "загружаю", извиняюсь что не написал...

                    • Миша 14 февраля 2015 #

                      Тогда замените:

                      $(this).text('Загружаю...');

                      на:

                      $(this).html('Загружаю...');
  • Radnk 18 февраля 2015 #

    При быстром многократном нажатии загружается одна страница много раз, как исправить?

    И как убрать вот это (script): http://ssmaker.ru/c02ea7d7.png

    у вас например в исходном коде такого нет

    • Миша 19 февраля 2015 #

      1) Можно в самом начале AJAX-запроса добавлять класс (к body или к кнопке), после выполнения запроса удалять его. Соответственно перед нажатием кнопки будет проверять наличие класса. Если класс есть (т.е. предыдущий запрос не выполнен до конца), то ничего не делаем.

      2) Имеете ввиду скрипт с параметрами? Можете просунуть их в атрибуты кнопки.

      • Radnk 19 февраля 2015 #

        А не поможете кодом?

        я уже как только не крутил: http://ssmaker.ru/054036d2.png

      • Radnk 19 февраля 2015 #

        Все работает:

        jQuery(function($) {
        	$('#true_loadmore').click(function(){
         
            	var $el = $(this),
                	$preloader = $('.preloader');
        		var data = {
        			'action': 'loadmore',
        			'query': true_posts,
        			'page' : current_page
        		};
         
        		$.ajax({
        			url:ajaxurl, // обработчик
        			type: 'POST',   
        			data:data, // данные
        			cache: false,
        			beforeSend: function( ) {
        				$el.hide(); 
        				$preloader.show();
        			},
        			success: function(data){
        				if( data ) { 
        					$('#true_loadmore').text('Загрузить ещё').before(data); // вставляем новые посты
        					current_page++; // увеличиваем номер страницы на единицу
        				} else {
        					$('#true_loadmore').remove(); // если мы дошли до последней страницы постов, скроем кнопку
        				}
        			}           
        		})
         
        		.complete(function() {
        			$preloader.hide();
        			$el.show();           
        		});   
        	});
        });

        Но правильно ли это?

        • Radnk 19 февраля 2015 #

          Вот:

          jQuery(function($) {
          	$('#true_loadmore').click(function(){
           
              	var $el = $(this),
                  	$preloader = $('.preloader');
          		var data = {
          			'action': 'loadmore',
          			'query': true_posts,
          			'page': current_page
          		};
           
          		$.ajax({
          			url: 'http://pro100-minecraft.ru/wp-admin/admin-ajax.php', // Обработчик
          			type: 'POST', // Тип запроса
          			data: data, // Данные
          			cache: false, // Кэширование
          			beforeSend: function( ) { // Действия, которые будут выполнены перед выполнением ajax-запроса
          				$el.hide(); 
          				$preloader.show();
          			},
          			success: function(data){
          				if( data ) { 
          					$el.before(data); // Вставляем новые посты
          					current_page++; // Увеличиваем номер страницы на единицу
          					if (current_page == max_pages) {
          						$el.remove();
          					}
          				} else {
          					$el.remove(); // Если мы дошли до последней страницы постов, скроем кнопку
          				}
          			}           
          		})
           
          		.complete(function() { // Действия, которые будут выполнены после завершения ajax-запроса
          			$preloader.hide();
          			$el.show();
          		});
          	});
          });

          И не работал:

          if (currentPage == maxPages) { $el.remove(); }

          Поменял на:

          if (current_page == max_pages) { $el.remove(); }

          Правильно как?

          • Миша 20 февраля 2015 #

            Правильно так, как работает. Если бы что-то было неправильно, код jQuery просто отказался бы выполняться.

            • Radnk 20 февраля 2015 #

              Так все таки:

              if (currentPage == maxPages) { $el.remove(); }

              У вас не правильно было?

              P.S. Работать то может даже когда и не правильно сделано. например, можно сделать правильно намудрив чего либо или оптимально сделать.

              • Миша 21 февраля 2015 #

                Да я просто перепутал названия переменных — наверн о чем-то задумался, когда писал код 🙂

                Спасибо, что указали на ошибку. Исправил.

                • Александр 1 марта 2015 #

                  Кстати, а как насчет вмонтировать прелоадер?
                  Вижу, что в коде товарища он присутствует, но мои познания не уходят дальше html, и я за минимализм.

                  Сделаю на css, подскажите, как можно сюда кроме текста вставить html теги?

                  $(this).text('Загружаю...');
  • Александр 24 февраля 2015 #

    После кнопки у меня идет самодельная пагинация. Все работает, только после подгрузки не обновляется номер текущей страницы. Помогите связать ее с Вашим кодом.

    	function paginator() {  
    	global $wp_query;  
    	$pages = '';  
    	$max = $wp_query->max_num_pages;  
    	if (!$current_page = get_query_var('paged')) $current_page = 1;  
    	$a['base'] = str_replace(999999999, '%#%', get_pagenum_link(999999999));  
    	$a['total'] = $max;  
    	$a['current_page'] = $current_page;  
     
    	$a['mid_size'] = 3; //сколько ссылок показывать слева и справа от текущей  
    	$a['end_size'] = 1; //сколько ссылок показывать в начале и в конце  
     
    	if ($max > 1) echo '<div class="b-pager">';  
    	echo $pages . paginate_links($a);  
    	if ($max > 1) echo '</div>';  
    	}
    • Radnk 25 февраля 2015 #

      Я так сделал:

      var currentUrl = window.location.href.replace(/\/+$/,'');

      и

      history.pushState('', '', currentUrl + '/page/' + current_page); // Добавляем в url увеличенный на единицу номер страницы
      • Александр 26 февраля 2015 #

        Я не совсем ясно выразился, у меня проблема в том, что:
        - при нажатии "показать еще" не меняется активная страница в ссылках пагинации.
        - не пропадает кнопка на последней странице если на нее перейти по прямой ссылке, а не нажимая "показать еще".

        • Миша 26 февраля 2015 #

          В этом посту рассмотрен упрощенный вариант скрипта — текущая страница и не должна меняться.

          Тут сделан упор на то, чтобы у каждого получилось сделать кнопку «Загрузиь ещё», ну а потом уже каждый бы дорабатывал её под себя.

          Не знаю, возожно в скором времени напишу плагин, в котором будет реализован максимальный функционал кнопки.

          • Александр 26 февраля 2015 #

            А ведь у Вас в блоге это работает )

          • Александр 26 февраля 2015 #

            • Миша 26 февраля 2015 #

              У меня работает 🙂 но у меня там вообще мега-шаманский код)

              • Александр 26 февраля 2015 #

                Вообще, совмещение кнопки и пагинации - это очень популярная история близкая к идеалу (взять тот же d3.ru), поэтому реализовать этот вариант в наиболее простом исполнении, чтобы легко монтировалось и пошло в массы, было бы крайне полезным для вселенной делом 🙂 Так что, если надумаете, буду рад, если маякнете тут комментом )

                P.S. слышал, если где-то можно обойтись без плагина, то лучше так и делать.

                • Миша 27 февраля 2015 #

                  Хорошо)

  • Лев 1 марта 2015 #

    Все отлично, но есть проблема. У меня многие шорткоды созданы по инструкции http://scribu.net/wordpress/optimal-script-loading.html . Суть состоит в том, что для многих шорткодов нужны js скрипты, они подгружаются в футере только один раз на страницу и только на тех страницах, на которых это действительно надо. При использовании ajax пагинации сами шорткоды исполняются, а вот js коды в футере не исполняются. Что можно сделать?

    • Миша 2 марта 2015 #

      Подгружайте скрипты шорткодов через функцию wp_enqueue_sript().

      • Лев 2 марта 2015 #

        я так и делаю

  • Max 4 марта 2015 #

    Спасибо все работает но есть проблемка после нажатия выводит всю статью
    подскажите как исправить что бы выводил только анонс с миниатюрой ( вот пример http://tehnew.ts9.ru/ )

    • Миша 5 марта 2015 #

      Это надо вставить внутри обработчика PHP:

      global $more;
      $more = 1; // или 0, точно не помню
  • Павел 25 марта 2015 #

    У меня стоит ограничение на вывод не больше 5 постов, нужно что бы при нажатии загрузить еще подгружались не 5, а 20 постов. Я так понял сколько стоит ограничение по столько и будет подгружать, можно это изменить?

    • Дима 25 марта 2015 #

      Пропишите в functions.php, между 3 и 4й строкой:

      $args['posts_per_page'] = 20;

      и будет вам счастье.

  • boris_ 26 марта 2015 #

    Никак не могу победить проблему с выводом нулей в конце страницы. Die() в конце functions.php есть, но проблему это не решает.

    • Миша 27 марта 2015 #

      die(); должен быть не в конце functions.php а именно в конце самой функции. То есть фигурная скобка } должна идти после die();.

      Но сама функция работает ведь? Просто в конце 0 ставится?

      • boris_ 27 марта 2015 #

        Разобрался. Причиной вывода 0 была другая функция в functions.php.

      • boris_ 27 марта 2015 #

        Спасибо

  • Роман 23 апреля 2015 #

    Миша привет, спасибо за пост, очень помог,но всё атки не получается нормально выводить несколько постов, меняю кол-во выводимых постов и они выводятся но некорректно, в коде отображается один, а остальне просто друг на друге появляются и в коде их нет, куда капать? Подскажи пожалуйста!

    • Миша 24 апреля 2015 #

      Привет!
      А что значит друг на друге? Наезжают как бы?

      Через исходный код Ctrl + U не отображаются результаты AJAX-запросов.

      • Роман 24 апреля 2015 #

        Спасибо за ответ! Разобрался, как бы то было не странно, проблема была там где ее меньше всего ждешь) Незакрытый div)

        • Миша 25 апреля 2015 #

          Бывает)

  • Константин 25 апреля 2015 #

    Михаил, приветствую!!!! А как можно сделать ajax подгрузку постов по клику, например на cтрелки вперед-назад , из определенной категории типа такой https://yadi.sk/i/7Tyq2Lm9gEkYQ ? Благодарю за ответ

    • Миша 26 апреля 2015 #

      Приветствую!
      Так же, как и обычную AJAX-подгрузку постов. Что еще могу ответить на ваш комментарий)

  • Стас 28 апреля 2015 #

    Привет! Спасибо большое за материал. Давно хотел реализовать что-то подобное. В целом, удалось реализовать и автоматическую подгрузку и подгрузку через нажатие кнопки. Однако не могу разобраться с оформлением выводимых постов - по ходу его просто нет (см. пожалуйста скриншот http://joxi.ru/jKM-VYwyTJDLMYpkOZI). Подозреваю, что проблема в этом get_template_part( 'content', 'excerpt' ); - т.е. часть кода подгружается с других файлов. Возможно ошибаюсь, поскольку не силен во всем этом. Надеюсь подскажите, как придать постам нормальный (стандартный) вид.

    • Миша 28 апреля 2015 #

      Привет!
      А можно глянуть на сайт?

      • Стас 28 апреля 2015 #

        Блин, этот сайт на локалке, подготавливаю только... Шаблон взял из сети http://wt_falcon.theme.morestyle.ru/ (не рекламирую, ссылку можно удалить) . Сейчас мелкие доработки вношу - ничего особенного. Поэтому, если шаблон поможет сориентироваться, то буду очень благодарен.

        • Миша 29 апреля 2015 #

          Я рекомендую проверить и сравнить HTML код который используется для вывода обычных и подгружаемых постов.

  • Aleksander 30 апреля 2015 #

    Добрый день.
    У меня к вам вопрос: получилось сделать динамическую подгрузку данных на страницу, но раньше была миниатюра записи, когда ты её открывал, открывался и пост полностью, а сейчас, когда прогружаются новости, открывается и новость полностью, подскажите пожалуйста, как я могу сделать так, что бы подгружались только миниатюры, а не пост целиком?
    Надеюсь, я все понятно объяснил)
    Спасибо большое!!!

    • Миша 2 мая 2015 #

      Добрый день!
      Попробуйте это.

      • Aleksander 5 мая 2015 #

        Извините за глупый вопрос: куда именно вставить эту функцию?
        Спасибо большое!

        • Миша 6 мая 2015 #

          Ответил вам по емайл)

  • andrew 20 мая 2015 #

    Добрый день.
    Интересует вопрос безопасности.
    Пользователь, изменяя переменную true_posts, изменит wp_query?

    • Миша 20 мая 2015 #

      Добрый день!
      Разумеется, если изменить true_posts, то изменится WP_Query, только в чем тут опасность, то, что он посты из другой рубрики сможет подгрузить?)

  • andrew 20 мая 2015 #

    Пользователь сможет выполнять любые нужные ему (но совсем не нужные вам) запросы к БД.

    • Миша 20 мая 2015 #

      Не сможет. Каким образом по-вашему он это сделает через WP_Query?

  • Игорь 23 мая 2015 #

    Здравствуйте! спасибо за код очень помог! но есть пару нюансов:
    1. Если всего 1 запись то почему то он ее не выводит , делаю подгружение без кнопки. ( подскажите в чем может быть проблема ?)

    2. Если прописать в functions $args['posts_per_page'] = '1'; скрипт перестает работать и не вводит посты , в консоле пишет - http://prntscr.com/7896o2 , но если в админке выставить чтение 1 запись , то все отлично , если выставить 2 записи то снова пустота , помогите пожалуйста))

  • Миша 23 мая 2015 #

    Здравствуйте!
    У вас просто не выполняется условие if ( $wp_query->max_num_pages > 1 ) :, это значит, что в настройках чтениях либо где-то еще определено такое количество постов, которое помещается на одной странице.

    • Игорь 23 мая 2015 #

      Странно почему он не выполняется 🙁

      делаю так :

       
      		<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
       
      <?php endwhile; ?>
      <?php if (  $wp_query->max_num_pages > 1 ) : ?>
      			<script id="true_loadmore">
      			var ajaxurl = '<?php echo site_url() ?>/wp-admin/admin-ajax.php';
      			var true_posts = '<?php echo serialize($wp_query->query_vars); ?>';
      			var current_page = <?php echo (get_query_var('paged')) ? get_query_var('paged') : 1; ?>;
      			 var max_pages = '<?php echo $wp_query->max_num_pages; ?>';
      			</script>
      		<?php endif; ?>
      <?php endif; ?>

      он выводит даже , стр ,новости , и собственнный тип записей ,что такое не могу понять.

      • Миша 23 мая 2015 #
        echo $wp_query->max_num_pages;

        Чему равно?

        • Игорь 23 мая 2015 #

          2 равно ,я уже смотрел)

          • Игорь 23 мая 2015 #

            вообщем сделал так :

            $args['paged'] = $_POST['page'];

            и все заработало))

  • Александр 29 мая 2015 #

    Привет, Михаил!
    Использую Ваш метод "бесконечная загрузка постов при прокрутке страницы"
    Есть один нюанс...
    У меня также установлен плагин "Pods" для WP и он в своем шаблоне категории произ.типов постов выводит дополнительные поля с помощью конструкции:

    <?php echo get_post_meta( $post->ID, 'client_name', true ); ?>

    Вставляю данный код в кусок шаблона в functions.php (там где необходимо привести код моего шаблона поста) и на сайте вижу, что на вновь загруженных постах, вместо данного доп поля из PODS пусто. Привожу кусок кода шаблона поста:

    <?php // ВЫВОД ПРОЕКТА ИЗ ПОРТФОЛИО ?>
    	<div class="col-lg-3 col-md-3 col-sm-6 col-xs-12">
    		<div class="one-block">
    				<a href="<?php the_permalink(); ?>" class="company"><?php echo get_post_meta( $post->ID, 'client_name', true ); ?><span class="arr_ico"></span></a>
     
    				<div class="date"><?php the_time('j F Y'); ?></div>
     
    				<a href="<?php the_permalink(); ?>" class="title"><?php the_title(); ?></a>
     
    				<a href="<?php the_permalink(); ?>" class="prev_img">
    					<div><?php if ( has_post_thumbnail() ) the_post_thumbnail(); // выводим миниатюру поста, если есть ?></div>
    				</a>
     
    				<ul>
    					<li title="Комментарии"><a href="<?php the_permalink(); ?>#comments" class="comments_link"><i class="fa fa-comments"></i>  <?php echo get_comments_number(); ?></a></li>
    					<li><?php if( function_exists('zilla_likes') ) zilla_likes(); ?></li>
    				</ul>
    		</div>
    	</div>
      <?php // ВЫВОД ПРОЕКТА ИЗ ПОРТФОЛИО ?>

    Натолкните на мысль, что и где нужно добавить, чтобы доп. поля отрабатывали для вновь загруженных аяксом постов. Обращаю внимание, что лайки из дополнительного плагина "zilla_likes" для подгружаемых постов работают и отображаются на странице верно. Заранее спасибо!

    • Миша 29 мая 2015 #

      Привет!
      Вам нужно изменить первый параметр функции get_post_meta() — с $post->ID на $q->post->ID.

      • Александр 2 июня 2015 #

        Бесконечно благодарен, а анимацию как-нибудь без кнопки, но все же всплывающую при подгрузке реально плавно реально допилить? Как я понял для этого в loadmore.js и добавляется класс ".loading" ?
        А что касается сеошного вопроса, что если просто добавить пагинацию обычную вордпрессовскую и скрыть на css "display:none;"? тогда индексироваться будут корректно все записи?

        • Миша 3 июня 2015 #

          Да, конечно можно. Вы правы.

          Пагинцию добавить можно, но насколько я знаю, поисковики display:none определяют и не любят.

  • Aleksander 4 июня 2015 #

    Добрый день.
    Столкнулся со следующей проблемой: поставил бесконечную подгрузку постов, все работает на компьютере замечательно, захожу с телефона, и оно не работает, вместо того, чтобы загружать посты, оно в конце страницы, открывает последнюю новость, если допустим в самом низу новость 7, то оно не будет подгружать новость 6 и т.д., оно откроет новость 7.
    Как можно решить данную проблему?
    Спасибо большое!!!

    • Миша 5 июня 2015 #

      Добрый день!
      А кэш очищали, да?

      • Aleksander 5 июня 2015 #

        Добрый день!
        На телефоне? Нет, не очищал, а нужно?:)

        • Миша 5 июня 2015 #

          На телефоне достаточно страницу перезагрузить 🙂 Хотя зависит от телефона)

          • Aleksander 8 июня 2015 #

            Дело в том, что даже когда посты прогружаются, последний пост все равно открывается внизу страницы)
            Может кто сталкивался с такой проблемой на мобильных устройствах?
            Спасибо!

          • Aleksander 8 июня 2015 #

            Пока решил данную проблему путем не автоматической подгрузки страницы, а после нажатия на кнопку "Загрузить еще":)
            Скажите пожалуйста, а как сделать, что бы при нажатии на кнопку загрузки, появлялась какая-то динамика, крутилось загрузка, что бы было видно, что оно думает, как это правильно реализовать? Путем добавления гиф или это неправильно?
            Спасибо!

            • Миша 10 июня 2015 #

              Ну как вариант можно добавлять гифку через CSS background-image 🙂

  • Александр 22 июня 2015 #

    Миша, а вы не покажете способ, как допилить код, чтобы при первом нажатии "Загрузить еще" пагинатор скрывался. Как сделано здесь http://siliconrus.com/ Очень удачное решение.

    • Миша 23 июня 2015 #

      А, да просто допишите к событию click:

      $('#paginator').remove(); // или $('#paginator').hide();
      • Александр 23 июня 2015 #

        Красота, спасибо!

  • Aleksander 30 июня 2015 #

    Добрый день.
    Скажите пожалуйста, как вывести бесконечную загрузку на главную страницу? я вывел новости на главную и теперь не могу добавить загрузку.
    Большое спасибо!

  • Александр 8 июля 2015 #

    Добрый день.
    Подскажите пожалуйста, я поставил на сайте бесконечную загрузку, когда захожу на сайт через UC Browser сталкиваюсь со следующей проблемой: когда дохожу до конца страницы оно пишет "Preloading" и открывает последний пост внизу, то есть, появляется под страницей новостей еще одна страница, в которой открыта последняя новость, смотрится это мягко говоря, не очень хорошо. На других браузерах с таким не встречался. Может кто знает решение проблемы?
    Заранее большое спасибо!

    • Миша 9 июля 2015 #

      Добрый день!
      Если такая серьезная проблема и на других браузерах её нет, то, извините за банальный совет, но вы кэш чистили?

      • Александр 10 июля 2015 #

        Добрый день.
        В том то и дело, что все чистил, не помогает, даже не знаю, что делать. Скажите пожалуйста, а вы проверяли этот код в этом браузере? Скорее всего глупая мысль, но может браузер как-то неправильно воспринимает этот код?)

        • Миша 10 июля 2015 #

          Добрый день!
          Не проверял к сожалению) Бывает конечно, что браузеры по-разному воспринимают код, но в данном случае это довольно серьёзная проблема.

  • Александр 14 июля 2015 #

    На обычных постах работает, а как сделать аjax пагинацию для произвольных типов записей? Где нужно скорректировать код, подскажите пожалуйста.

    • Миша 14 июля 2015 #

      По идее добавить в PHP-обработчик параметр $args['post_type']. Вы на какой странице это делаете? Архивы типов записей?

      • Александр 14 июля 2015 #

        Я сделал страницу шаблон - галерея. Где вывожу все произвольные записи 'gallery'. И к этой же странице шаблону, хочу подгрузить вашу ajax-пагинацию.

        Проблема еще в том, что я уже использую вашу ajax-пагинацию для обычных постов. )) Если я начну изменять код $args['post_type'], то пагинация для обычных постов перестанет работать. Прошу вашего совета)

      • Александр 14 июля 2015 #

        Миша подскажите пожалуйста, как вывести это на странице шаблона? Я только что смог вывести пагинацию в категории, для своих произвольных записей. Но на странице шаблона не выводит ни в какую, хотя код одинаков, что там, что там.

        • Миша 15 июля 2015 #

          В первую очередь проанализируйте содержимое переменной: $wp_query->query_vars); (есть в самом первом шаге). И потом уже от этого надо плясать 🙂

  • Олег 14 июля 2015 #

    Миша подскажите пожалуйста как сделать вывод постов по средствам masonry.js ?

  • Олег 14 июля 2015 #

    Как то нжуно использовать метод append http://desandro.github.io/masonry/docs/methods.html но что-то у меня не получается может подскажете. Посты выводятся поверх.

    • Миша 15 июля 2015 #

      Во-первых, у вас должен быть отдельный контейнер для блоков, например #posts.
      Во-вторых, вам нужно в этот контейнер вставлять результат ajax через append (а не как у меня через before перед кнопкой).
      В-третьих, кнопку нужно вынести за пределы контейнера.

      $('#posts').append( data ).masonry( 'appended', data );

      Ну в общем вам надо капитально над структурой поработать.

      • Олег 15 июля 2015 #

        Я использую вариант без кнопки а с бесконечных скроллом.

      • Олег 15 июля 2015 #

        Вот примерно как коряво получается вывод. Выводится все поверх. Помогите пожалуйста. В решении проблемы.
        http://codepen.io/anon/pen/yNExbz

  • Александр 15 июля 2015 #

    Миша подскажите, пожалуйста. Я сделал загрузку аjax постов для новостей через кнопку. И я также сделал загрузку аjax постов для произвольного типа записи без кнопки, но при прокрутке. По отдельности они работают, если будет только ajax загрузка для новстей или если только будет ajax загрузка для произвольного типа записи. Но чтобы было и то и то не получается, работает криво. По сути он берет только один обработчик первый, а второй как бы не видит.

    Наведите на мысль в чем может быть проблема. У меня получилось два обработчика событий и два скрипта, имена заменил, так что ничто нигде не совпадает...

    add_action('wp_ajax_loadmore', 'true_load_posts');
    add_action('wp_ajax_nopriv_loadmore', 'true_load_posts');
     
    add_action('wp_ajax_loadmore', 'true_load_posts_scroll');
    add_action('wp_ajax_nopriv_loadmore', 'true_load_posts_scroll');

    Вот внутренности двух скриптов

    jQuery(function($){
    	$(window).scroll(function(){
    		var bottomOffset = 4000; // отступ от нижней границы сайта, до которого должен доскроллить пользователь, чтобы подгрузились новые посты
    		var data = {
    			'action': 'loadmore',
    			'query': true_posts,
    			'page' : current_page
    		};
    		if( $(document).scrollTop() > ($(document).height() - bottomOffset) && !$('body').hasClass('loading')){
    			$.ajax({
    				url:ajaxurl,
    				data:data,
    				type:'POST',
    				beforeSend: function( xhr){
    					$('body').addClass('loading');
    				},
    				success:function(data){
    					if( data ) { 
    						$('#true_loadmore_1').before(data);
    						$('body').removeClass('loading');
    						current_page++;
    					}
    				}
    			});
    		}
    	});
    });
    jQuery(function($){
    	$('#true_loadmore').click(function(){
    		$(this).text('Загружаю...'); // изменяем текст кнопки, вы также можете добавить прелоадер
    		var data = {
    			'action': 'loadmore',
    			'query': true_posts,
    			'page' : current_page
    		};
    		$.ajax({
    			url:ajaxurl, // обработчик
    			data:data, // данные
    			type:'POST', // тип запроса
    			success:function(data){
    				if( data ) { 
    					$('#true_loadmore').text('Ещё').append('<span></span>').before(data); // вставляем новые посты
    					current_page++; // увеличиваем номер страницы на единицу
    					if (current_page == max_pages) $("#true_loadmore").remove(); // если последняя страница, удаляем кнопку
    				} else {
    					$('#true_loadmore').remove(); // если мы дошли до последней страницы постов, скроем кнопку
    				}
    			}
    		});
    	});
    });

    может быть здесь должно быть отличие?

    		var data = {
    			'action': 'loadmore',
    			'query': true_posts,
    			'page' : current_page
    		};
    • Миша 15 июля 2015 #

      Да, отличие должно быть в параметре action.

      var data = {
      			'action': 'loadmore', // и для второго скрипта например loadmore2

      Тогда:

      add_action('wp_ajax_loadmore', 'true_load_posts');
      add_action('wp_ajax_nopriv_loadmore', 'true_load_posts');
       
      add_action('wp_ajax_loadmore2', 'true_load_posts_scroll'); // тут тоже меняем
      add_action('wp_ajax_nopriv_loadmore2', 'true_load_posts_scroll'); // тут тоже

      Вот тут больше инфы об этом.

  • Александр 15 июля 2015 #

    Добрый день.
    Подскажите пожалуйста, как бесконечную загрузку сделать на главной странице?
    Спасибо большое!

    • Олег 15 июля 2015 #

      Вместе с masonry

  • Александр 26 июля 2015 #

    Спасибо за отличный пост!
    Не подскажете, как изменить код, чтобы при нажатии на кнопку новые посты отображались не внизу, а на месте старых. То есть чтобы уже отображенные посты просто заменялись новыми. Заранее спасибо!

    • Миша 27 июля 2015 #
      $('#блок_со_старыми_постами').html( data );
      • Александр 11 августа 2015 #

        Спасибо за ответ. На одном сайте все работает, а на втором, почему-то, после нажатия на кнопку "Загрузить еще", каждый пост выводится 2 раза. Может есть идеи, в чем может быть причина? Спасибо!

        • Миша 12 августа 2015 #

          Возможно черновики?

      • Mariel 29 ноября 2015 #

        МИша не знаю где поставить этот код... Я тоже хочу, что бы новые посты отображались на месте старых

        • Миша 29 ноября 2015 #

          Ну что я могу сказать.. Чтобы вам помочь, мне нужны более конкретные вопросы.

          • Mariel 30 ноября 2015 #

            При нажатии на кнопку новые посты отображались не внизу, а на месте старых. То есть чтобы уже отображенные посты просто заменялись новыми.

            --Как сделать именно этого

            • Миша 2 декабря 2015 #

              Тремя комментами выше, вот ссылка.

  • alex 5 октября 2015 #

    Попробовал всё сделать как вы описали, но у меня не срабатывает бесконечная подгрузка постов.
    первый вариант с кнопкой работает, но если заменяю на

    <?php if (  $wp_query->max_num_pages > 1 ) : ?>
    	<script id="true_loadmore">
    	var ajaxurl = '<?php echo site_url() ?>/wp-admin/admin-ajax.php';
    	var true_posts = '<?php echo serialize($wp_query->query_vars); ?>';
    	var current_page = <?php echo (get_query_var('paged')) ? get_query_var('paged') : 1; ?>;
    	</script>
    <?php endif; ?>

    бусконечная подгрузка не срабатывает.
    если же оставить

    <div id="true_loadmore">Загрузить ещё</div>

    тогда бесконечная подгрузка работает но + еще кнопка всегда присутствует.

    Возможно проблема в

    <script id="true_loadmore">

    ??

    Также есть еще нюанс, при загрузке страницы список постов не появляется, а только после нажатия на кнопку "Загрузить еще" подгружаются первые 5 постов. Подскажите как сделать по умолчанию загрузку первой партиии постов?

    • Миша 6 октября 2015 #

      Ну вы оставьте кнопку, только текст можете убрать или скрыть её вовсе через CSS:

      <div id="true_loadmore"></div>

      Этот код расчитан, что только новые посты подгружаются асинхронно. Если вам нужно, чтобы он срабатывал для всех постов, даже тех, которые показываюстя при загрузке страницы, запускайте код сразу же, тогда переменная current_page будет равна 0 получается.

  • most_wanted 6 октября 2015 #

    Если я вывожу кастомный тип поста

     $property_types = array('property','land', 'commercial', 'business', 'commercial_land' , 'location_profile','rural');
    	$args = unserialize(stripslashes($_POST['query']));
    	$args['paged'] = $_POST['page'] + 1; // следующая страница
    	$args['post_status'] = 'publish';
     
            $args['post_type'] = $property_types;

    то кнопка "загрузить еще" не пропадает при загрузке последней страницы с записями, на неё нужно еще раз нажать и тогда она пропадает, хотя посты уже больше не загружаются.
    если же снова ставлю post_type="page", то работает как положено - с последнейзагрузкой постов кнопка пропадает. Почему так?

    • Миша 6 октября 2015 #

      Ну у вас просто где-то ошибка с количеством страниц / постов на странице, раз скрипт считает, что их на одну больше.

  • Сергей 16 октября 2015 #

    Добрый день!
    Сделал все как описано у вас в статье.
    Отладчик браузера выдает ошибку
    Uncaught ReferenceError: true_posts is not defined

    • Миша 16 октября 2015 #

      Добрый день!
      Попробуйте где-нибудь в начале файла global $wp_query; добавить.

  • most_wanted 22 октября 2015 #

    скажите зачем мы передаём сериализованные данные а потом снова их извлекаем?

    var true_posts = '<?php echo serialize($wp_query->query_vars); ?>';

    и потом:

    $args = unserialize(stripslashes($_POST['query']));
    • Миша 22 октября 2015 #

      А какой вариант предлагаете вы?

  • Mariel 5 ноября 2015 #

    Миша привет. Спс за статью. Скажите пожалуйста... как вместе текста "Загружаю", как поставить картинку GIF...

    • Миша 6 ноября 2015 #

      Привет! Рад помочь)
      Как-то так:

      $(this).html('<img src="ссылка на гифку, желательно полная" />');
      • Mariel 8 ноября 2015 #

        wow спс большое

  • Игорь Фёдоров 8 ноября 2015 #

    Миша, привет! Можешь помочь? Как обновлять текущий элемент в стандартной пагинации ВП, если она используется вместе с Ajax подгрузкой?

    • Миша 9 ноября 2015 #

      Привет!

      Функция постраничной навигации тогда должна быть прямо в обработчике PHP.

  • WebNatrix 16 ноября 2015 #

    Нашел баг, вы все через админку проверяете скрипт, но попробуйте под гостем зайти или простым пользователем, у вас admin-ajax.php не даст подгрузить. Что делать?

    • Миша 17 ноября 2015 #

      Оба использовали?

      add_action('wp_ajax_loadmore', 'true_load_posts');
      add_action('wp_ajax_nopriv_loadmore', 'true_load_posts');
      • WebNatrix 17 ноября 2015 #

        ага, прям как у вас там.

        • Миша 18 ноября 2015 #

          Проблема, решена, заключалась в конфликте с другим плагином пользователя.

          • Иван 23 апреля 2016 #

            А как решена, Миша? У меня такая же проблема - работает только когда я залогинен на сайте!!! то есть конфликт? а как определить с чем конфликтует дайте пожалуйста наметки! Спасибо!

            • Миша 23 апреля 2016 #

              Да без понятия, это было давно 🙂

              Окей, алгоритм:

              • Убедиться, что используются оба хука
              • Убедиться, что файл /wp-admin/admin-ajax.php не заблокирован через .htaccess
              • Если не помогло — отключаем все текущие плагины и смотрим, не изменилось, ли что.
              • Иван 23 апреля 2016 #

                Я не могу отключить некоторые плагины (easy vk connekt и true instagram), там настройки я настраивал долго! как обойти вариант с отключением плагинов? htaccess проверил - чисто, только в папках wp-admin стоят вот такие записи:

                <IfModule mod_rewrite.c>
                RewriteEngine On
                RewriteBase /exactly/
                RewriteRule ^index\.php$ - [L]
                RewriteCond %{REQUEST_FILENAME} !-f
                RewriteCond %{REQUEST_FILENAME} !-d
                RewriteRule . /exactly/index.php [L]
                </IfModule>

                Оба хука используются

                • Иван 23 апреля 2016 #

                  Короче наверно не судьба? я много намутил с защитой блога, теперь уже не помню где что защищал, вот видимо эта защита и работает)) Миша, а можно ли вывести этот ajax как то в отдельный файл что-ли в обход авторизации чтобы работал он?

                  • Миша 23 апреля 2016 #

                    А вы попробуйте удалить временно .htaccess из админки и быстро проверить, а потом сразу Ctrl+Z 🙂

                    Можно создать прямо в папке сайта файл ajax.php (например) и в него вставить:

                    require_once( dirname(__FILE__) . '/wp-admin/admin-ajax.php' );

                    Только в AJAX запросах не забудьте URL сменить.

                    • Иван 13 мая 2016 #

                      Миша в общем я нашел решение проблемы..
                      Я же говорил, что безопасность)) В общем у меня была функция которая блокирует доступ к области администратора. То есть в панель администрирования могут только админы заходить. И если пользователь не админ, то происходит редирект на главную
                      Вот сама ф-ция

                      function restrict_admin()
                      {
                      	if ( ! current_user_can( 'manage_options' ) && '/wp-admin/admin-ajax.php' != $_SERVER['PHP_SELF'] ) {
                                      wp_redirect( site_url() );
                      	}
                      }
                      add_action( 'admin_init', 'restrict_admin', 1 );

                      А теперь вопрос к Вам Миша, есть ли аналог этой функции но чтобы не блочил ajax? Спасибо!

                    • Миша 14 мая 2016 #

                      Есть условие проверки, что выполняется AJAX:

                      if( defined( 'DOING_AJAX' ) && DOING_AJAX )
  • Александр 16 ноября 2015 #

    Добры день, Коллеги, кто может дать совет как в подгрузке постов задать разные шаблоны использования. Я хочу реализовать подкрузку постов на разных страницах. На каждой странице разный шаблон отображения. как можно задать условие, что бы автоматически подгружались шаблоны нужной страницы. Не преписывать же все скрипты отдельно для каждой страницы?

    • Миша 17 ноября 2015 #

      Добрый день!
      Просто в запросе указывайте дополнительный параметр, например template=1, а потом уже в обработчике, в зависимости от его значения, подключайте нужные шаблоны.

      • Александр 17 ноября 2015 #

        а как теперь его

        template=1

        передать в обработчик?

        • Миша 18 ноября 2015 #
          var data = {
          	'action': 'loadmore',
          	'query': true_posts,
          	'page' : current_page,
          	'template' : 1
          };
          • Александр 18 ноября 2015 #

            Спасибо !!

  • Олег 1 декабря 2015 #

    Уважаемый люди, помогите реализовать, не получается у меня почему-то,
    Запутался во всем уже, смотрите первое что я сделал это установил кнопку в место где мне это необходимо в моем случае это index.php следующее добавил стили но это мелочи по сути это я понял, вот дальше functions.php вставил данный код, потом создал файл loadmore.js закинул туда код и залил в папку с темой, вот тут с Обработчик PHP я чет не очень понял как его и куда конкретно вставлять вставил в в самый верх, и все ровно кнопка бездействует ( вот я еще не совсем понял какую конкретно часть кода надо вставить в admin-ajax.php так как он подключен к функционалу кнопки. помогите пожалуйста реализовать, голова уже дымится не знаю что уже делать.

    • Олег 1 декабря 2015 #

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

      • Миша 2 декабря 2015 #

        какую конкретно часть кода надо вставить в admin-ajax.php

        В admin-ajax.php ничего вставлять не нужно. Обработчик — в functions.php.

        у меня нету файла ни content.php ни loop.php

        А можно глянуть на сайт?

        • Олег 2 декабря 2015 #

          Проблемы устранены, со всем разобрался, большое спасибо.

  • Сергей 7 декабря 2015 #

    Здравствуйте, Михаил!
    Только начинаю использовать WordPress и не могу "заставить" работать AJAX.
    Взял пример из Вашей статьи для решения своей задачи.

    У меня задача - разработать страницу соревнований. У каждого соревнования несколько вкладок с информацией. Мне бы хотелось, чтобы информация из каждой вкладки погружалась с помощью AJAX по клику на нее.

    Как я понял реализация этой идеи должна происходить таким образом:

    1. Создаю функцию в файле functions.php, которая будет возвращать мне данные о соревновании, предположим, что это будет контент поста;

    <?php function my_function(){?>
                <p>Контент: <?php the_content(); ?></p>
      <?php die();
    }
    add_action('wp_ajax_myaction', 'my_function'); 
    add_action('wp_ajax_nopriv_myaction', 'my_function'); 
    ?>

    2. Создаю скрипт который при нажатии на кнопку с классом .btn делает запрос на обработку и возвращает ответ в результате работы функции, прикрепленной на хук myaction в контейнер c id #container.

    jQuery(function($){
        $('.btn').click(function(){
          $.ajax({
            type:'POST',
            url:'<?php echo site_url() ?>/wp-admin/admin-ajax.php', // обработчик
            data:{ action: 'myaction'}, 
            success:function(response){
                $('#container').html(response);
            }
          });
        });
      });

    3. Как я понял - все должно выглядеть примерно так, но при нажатии на кнопку .btn я получаю только текст: "Контент:" .

    При этом цикл вывода статьи уже заранее помещен на страницу соревнования и если я вызываю эту же функцию с помощью

    <?php if(function_exists('my_function')) {
              my_function();
          } ?>

    то содержимое поста выводится.
    Никак не пойму в чем ошибка. Уже несколько дней пытаюсь разобраться и без результатов. Буду рад Вашей помощи!

    • Миша 8 декабря 2015 #

      Здравствуйте!
      У вас всё правильно, за исключением одной мелочи — функция the_content() не получает значение ID/объекта поста.

      Я предлагаю в параметры AJAX-запроса добавить ID поста, а в самом обработчике также получить объект его при помощи get_post().

      Если непонятно объяснил, пожалуйста, переспрашивайте.

      • Сергей 8 декабря 2015 #

        Спасибо за ответ! Как только появилось время, стал разбираться:

        1. Переделал функцию так, чтобы она использовала id поста, передаваемого через JavaScript.

        <?php 
            function my_function(){
            $my_post = get_post($_REQUEST['postID']); ?> //передал значение id поста
         
           <h1>Заголовок:<?php echo $my_post->post_title; ?></h1> // Вывел заголовок поста
           <p>Контент поста:<?php echo $my_post->post_content; ?></p> //Вывел контент поста
         
           /* У меня получилось вывести стандартные данные поста. После этого у меня возникла новая задача - мне необходимо вывести содержимое кастомных полей, созданных с помощью плагина ACF... сначала немного запаниковал, но документация плагина в помощь и я с легкостью вывожу содержимое кастомного поля, добавляя в качестве второго аргумента id своего поста! (пример ниже); */
         
           <p>Содержимое кастомного поля: <?php the_field('custom_article_text_field',$_REQUEST['postID']); ?></p>
         
        <?php 
            die();
        }
        add_action('wp_ajax_myaction', 'my_function'); 
        add_action('wp_ajax_nopriv_myaction', 'my_function'); 
        ?>

        2. Немного переделал скрипт таким образом, чтобы он брал id выводимого поста и отправлял его с AJAX-запросом:

        jQuery(function($){
            $('.btn').click(function(){
              $.ajax({
                type:'POST',
                url:'<?php echo site_url() ?>/wp-admin/admin-ajax.php', // задаю путь к обработчику
                data:{ 
                  action: 'myaction', 
                 'postID': '<?php the_ID(); ?>'}, // прикрепляю к ключу 'postID' значение id текущего поста
                success:function(response) {
                    $('#container').html(response);
                }
              });
            });
          });

        И... все работает! Получилось достать все данные поста!

        Спасибо огромное за помощь! Даже не знаю, как долго я бы еще пытался найти решение своей задачи без Вашей помощи!

        P.S. Если, вдруг, есть какие-то ошибки, которые я допустил или советы по оптимизации, то буду рад услышать!

        • Миша 9 декабря 2015 #

          Отлично, рад что у вас всё получилось 🙂

  • Egor 23 декабря 2015 #

    Функция с бесконечной прокруткой страницы перестала работать на wordpress 4.4

    Перестала работать на основном сайте после обновления. Я собрал заново все решение на тестовом сайте с wp 4.3 - все работает, обновляю сайт - ошибка.

    Ошибка - При бесконечной прокрутке посты начинают грузится сначала. Т.е., например, на странице есть посты с 100-ого по 90-ый. При прокрутке появляются опять опять те же посты с 100-ого по 90-ый, а не с 90-ого по 80-ый и т.д.

    Не знаете, как бы можно было исправить?

    • Миша 25 декабря 2015 #

      Постараюсь завтра глянуть.

    • Миша 26 декабря 2015 #

      Поставил этот код с нуля на WP 4.4 - всё работает 🙂

      • Egor 29 декабря 2015 #

        Спасибо за быстрый фидбек)

        У меня так и не получилось настроить прокрутку на 4.4 даже отключив все плагины. Но, ваше решение важнее обновления, поэтому откатил сайт до 4.3.1 - все сразу заработало. Потом поищу решение проблемы.

        • Миша 30 декабря 2015 #

          Вы можете мне просто доступ к сайту по email скинуть и я попробую вам помочь)

  • Иван 27 декабря 2015 #

    Вечер добрый! Все работает прекрасно, но столкнулся с одним моментом. На главной всё подгружается прекрасно, но когда выбираешь отдельную рубрику, подгружаемые посты игнорируют фильтрацию по рубрике, т.е. подгружается все подряд. Как это исправить? Т.е. чтобы на главной подгружались все посты, а в разных категориях только определенные.

    • Миша 28 декабря 2015 #

      Здравствуйте!
      По идее так не должно быть — можете мне скинуть содержимое тега script перед кнопкой «Загрузить еще»?

  • Иван 28 декабря 2015 #
    <script>
    			var ajaxurl = '<?php echo site_url() ?>/wp-admin/admin-ajax.php';
    			var true_posts = '<?php echo serialize($wp_query->query_vars); ?>';
    			var current_page = <?php echo (get_query_var('paged')) ? get_query_var('paged') : 1; ?>;
    			var max_pages = '<?php echo $wp_query->max_num_pages; ?>';
    </script>
    • Миша 29 декабря 2015 #

      Вы не поняли, мне нужно то, что в HTML.

  • Valeriy 31 декабря 2015 #

    Если у меня задается сортировка в цикле WP_Query, да еще не простая, а по значению произвольного поля.. подгружаемые посты уже получаются не отсортированные. Возможно что то придумать в таком случае ?

    • Миша 1 января 2016 #

      Как называется переменная-объект WP_Query?

      Просто в первом шаге заменяете $wp_query на название переменной-объекта.

  • Дмитрий 9 января 2016 #

    добрый день, хочу спросить. А реально реализвать так, при кнопке далее, навые посты подгружаются за мест страрых. Чтобы посты не вниз уходили, а просто заменялись новыми, но асинхронно

    • Миша 10 января 2016 #

      Добрый день, да, можно. Помещаете посты в какой-нибудь div, например #allposts и после выполнения ajax-запроса выполняете:

      $('#allposts').html( data );
  • Михаил 16 января 2016 #

    Доброй ночи, возникла задачи выводить контент динамически, нашел ваш пост, работает. У меня возник вопрос, можно ли как-то поставить проверку в php обработчике, имеется две рубрики которые выводятся на разные шаблоны и визуально у них разные стили, когда идет загрузка новостей в эти рубрики структура загрузившихся постов и стили одинаковые, возможно ли поставить проверку в обработчике в файле functions.php :

    <?php if ( in_category(array('6','4','5','7'))){}?>

    , что бы для разных рубрик была разная структура и соответсвенно стили, не понимаю как это сделать, возможно подтолкнете на мысль и поделитесь соображениями.

    • Миша 17 января 2016 #

      Здравствуйте!
      Вообще тут два варианта:

      1. Добавлять CSS-класс в виде ярлыка рубрики (так как рубрики разные, то и стилизовать можно по-разному будет). Чаще всего используется именно этот способ.
      2. Предложенная вами функция in_category(), только не забывайте про второй параметр, в данном случае я считаю он необходим.
  • Amira 27 января 2016 #

    Добрый вечер. Отличная статья, очень помогла, но у меня проблема, дублируются посты.

    Этот код в index.php

                    <div class="row">
                      <?php query_posts(array('orderby'=> 'rand','paged' => get_query_var('paged'))); ?>
                      <?php if (have_posts()) : while (have_posts()) : the_post(); ?> 
                      <div id="block-<?php echo $post->ID ?>" class="col-md-3 sell-<?php echo $post->ID ?>">
                            <a href="<?php the_permalink(); ?>" class="href">
                            <div class="sell">
                            <?php $sale = get_post_meta($post->ID, 'sale_number', true); if ($sale) { ?>
                                <div class="discount ic"><span class="num">-<?php the_field('sale_number'); ?>%</span></div>
                                <div class="discount ln s"><img src="http://skidka.kg/assets/css/images/skidka.png" alt="" class="src"></div>
                            <?php } else { ?>
                                <div class="discount line"><span class="num"><?php the_field('price_number'); ?></span></div>
                                <div class="discount ln s"><img src="http://skidka.kg/assets/css/images/ac.png" alt="" class="src"></div><?php } ?>
                                <div class="thumb">
                                    <img src="<?php the_field('slide_1'); ?>"  title="<?php the_title(); ?> изображение" alt="<?php the_title(); ?> в Бишкеке" class="src sale">
                                    <?php $sale = get_post_meta($post->ID, 'sale_number', true); if ($sale) { ?>
                                        <?php $price = get_post_meta($post->ID, 'price_old', true); if ($price) { ?>
                                        <div class="price"><span class="old"><?php the_field('price_old'); ?></span> - <span class="new"><?php the_field('price_new'); ?></span></div>
                                        <?php } else { ?><?php } ?>
                                    <?php } else { ?><?php } ?>
                                </div>
                                <h5><?php the_title(); ?></h5>
                            </div>
                            </a>
                        </div>
                        <?php endwhile; endif; ?>
                        <?php if (  $wp_query->max_num_pages > 1 ) : ?>
    	<script>
    	var ajaxurl = '<?php echo site_url() ?>/wp-admin/admin-ajax.php';
    	var true_posts = '<?php echo serialize($wp_query->query_vars); ?>';
    	var current_page = <?php echo (get_query_var('paged')) ? get_query_var('paged') : 1; ?>;
    	var max_pages = '<?php echo $wp_query->max_num_pages; ?>';
    	</script>
    	<div id="load">Загрузить ещё</div>
    <?php endif; ?>
                    </div>
  • Amira 27 января 2016 #

    Это из function.php

    <?php
    function true_load_posts(){
    	$args = unserialize(stripslashes($_POST['query']));
    	$args['paged'] = $_POST['page'] + 1; // следующая страница
    	$args['post_status'] = 'publish';
    	$q = new WP_Query($args);
    	if( $q->have_posts() ):
    		while($q->have_posts()): $q->the_post();
    			/*
    			 * Со строчки 13 по 27 идет HTML шаблон поста, максимально приближенный к теме TwentyTen.
    			 * Для своей темы вы конечно же можете использовать другой код HTML.
    			 */
    			?>
    			<div id="block-<?php echo $q->post->ID ?>" class="col-md-3 sell-<?php echo $q->post->ID ?>">
                            <a href="<?php the_permalink(); ?>" class="href">
                            <div class="sell">
                            <?php $sale = get_post_meta($q->post->ID, 'sale_number', true); if ($sale) { ?>
                                <div class="discount ic"><span class="num">-<?php the_field('sale_number'); ?>%</span></div>
                                <div class="discount ln s"><img src="http://skidka.kg/assets/css/images/skidka.png" alt="" class="src"></div>
                            <?php } else { ?>
                                <div class="discount line"><span class="num"><?php the_field('price_number'); ?></span></div>
                                <div class="discount ln s"><img src="http://skidka.kg/assets/css/images/ac.png" alt="" class="src"></div><?php } ?>
                                <div class="thumb">
                                    <img src="<?php the_field('slide_1'); ?>"  title="<?php the_title(); ?> изображение" alt="<?php the_title(); ?> в Бишкеке" class="src sale">
                                    <?php $sale = get_post_meta($q->post->ID, 'sale_number', true); if ($sale) { ?>
                                        <?php $price = get_post_meta($q->post->ID, 'price_old', true); if ($price) { ?>
                                        <div class="price"><span class="old"><?php the_field('price_old'); ?></span> - <span class="new"><?php the_field('price_new'); ?></span></div>
                                        <?php } else { ?><?php } ?>
                                    <?php } else { ?><?php } ?>
                                </div>
                                <h5><?php the_title(); ?></h5>
                            </div>
                            </a>
                        </div>
    			<?php
    		endwhile;
    	endif;
    	wp_reset_postdata();
    	die();
    }
    add_action('wp_ajax_loadmore', 'true_load_posts');
    add_action('wp_ajax_nopriv_loadmore', 'true_load_posts');
    ?>
  • Amira 27 января 2016 #

    Это из браузера, всего около 29 постов есть, по умолчанию отображается 12 постов.

    <div id="block-88" class="col-md-3 sell-88">Контент вырезан</div>
    <div id="block-479" class="col-md-3 sell-479">Контент вырезан</div>
    <div id="block-69" class="col-md-3 sell-69">Контент вырезан</div>
    <div id="block-341" class="col-md-3 sell-341">Контент вырезан</div>
    <div id="block-302" class="col-md-3 sell-302">Контент вырезан</div>
    <div id="block-318" class="col-md-3 sell-318">Контент вырезан</div>
    <div id="block-327" class="col-md-3 sell-327">Контент вырезан</div>
    <div id="block-258" class="col-md-3 sell-258">Контент вырезан</div>
    <div id="block-167" class="col-md-3 sell-167">Контент вырезан</div>
    <div id="block-35" class="col-md-3 sell-35">Контент вырезан</div>
    <div id="block-334" class="col-md-3 sell-334">Контент вырезан</div>
    <div id="block-406" class="col-md-3 sell-406">Контент вырезан</div>
    <script>Тут ваш сприпт</script>
    <div id="block-35" class="col-md-3 sell-35">Контент вырезан</div>
    <div id="block-206" class="col-md-3 sell-206">Контент вырезан</div>
    <div id="block-479" class="col-md-3 sell-479">Контент вырезан</div>
    <div id="block-143" class="col-md-3 sell-143">Контент вырезан</div>
    <div id="block-69" class="col-md-3 sell-69">Контент вырезан</div>
    <div id="block-189" class="col-md-3 sell-189">Контент вырезан</div>
    <div id="block-88" class="col-md-3 sell-88">Контент вырезан</div>
    <div id="block-293" class="col-md-3 sell-293">Контент вырезан</div>
    <div id="block-167" class="col-md-3 sell-167">Контент вырезан</div>
    <div id="block-318" class="col-md-3 sell-318">Контент вырезан</div>
    <div id="block-51" class="col-md-3 sell-51">Контент вырезан</div>
    <div id="block-235" class="col-md-3 sell-235">Контент вырезан</div>
    <div id="block-88" class="col-md-3 sell-88">Контент вырезан</div>
    <div id="block-258" class="col-md-3 sell-258">Контент вырезан</div>
    <div id="block-302" class="col-md-3 sell-302">Контент вырезан</div>
    <div id="block-35" class="col-md-3 sell-35">Контент вырезан</div>
    <div id="block-341" class="col-md-3 sell-341">Контент вырезан</div>

    Помогите пожалуйста чтобы посты не дублировались.

  • Amira 27 января 2016 #

    К примеру в коде выше пост под ID 35; вывелся 3 раза.. И так не только данный пост.

    <div id="block-35" class="col-md-3 sell-35">Контент вырезан</div>
    • Миша 27 января 2016 #

      Здравствуйте, мне бы конечно намного больше дала бы ссылка на ваш сайт, чем код, вырванный из контекста 🙂

  • Олександр 28 января 2016 #

    Огромное спасибо прекрасный материал!

  • Александр 31 января 2016 #

    Добрый день Михаил!
    Очень помогла ваша статья !
    Но есть проблема ... не могу доделать что бы подгруженный контент отображался нормально. Помогите
    http://delaem-podarki.ru/portfolio/

    И еще может тоже поможете... у меня на главной выводиться все сразу ... но в связи с тем что я использую кастомную категорию, то пагинация не применяется ... не встречались с такой проблемой?
    Использую такой запрос

    $args = array( 'post_type' => 'portfolio', 'posts_per_page' => -1, 'orderby' => 'menu_order', 'order' => 'ASC' );
    • Миша 2 февраля 2016 #

      Добрый день! Что-то и вовсе кода из статьи у вас не видно.

  • Слава 1 февраля 2016 #

    Миша, спасибо! Слов нет!
    Изначально что-то ни понял ничего, как оказалось просто ленился прочитать по человечески.
    Пошел в google искать способ ctrl + c ctrl + v В итоге нашел боль головную и всякие не рабочие плагины (Infinite Scroll)
    Вернулся, прочитал, все сделал, все работает - благодарю тебя. Добра тебе и твоему дому!!!!

    • Миша 2 февраля 2016 #

      Пожалуйста! Рад, что всё получилось 🙂

  • Виталий 4 февраля 2016 #

    Миша, добрый день!
    У меня проблема с этой функцией, есть плагин Advanced Post Types Order, с помощью которого я фиксирую, например, 10 постов в верхней части категории. Но функция true_load_posts этого не учитывает и выводит повторно эти посты на второй странице, а некоторые посты, получается, вообще не выводятся в разделе. Можно здесь посмотреть http://mos-holidays.ru/ekskursii-po-moskve/ Т.е. получается так, что true_load_posts работает с лентой постов, которая должна быть по-умолчанию и часть постов, которые должны быть на первой странице вообще не выводятся, т.к. вместо них на первой странице те, которые зафиксированы плагином Advanced Post Types Order.
    Например, вот эту экскурсию в разделе вообще не получится найти http://mos-holidays.ru/peshexodnaya-ekskursiya-eta-xitraya-xitrovka-ot-kompanii-shag-za-shagom/ , а эта http://mos-holidays.ru/avtobusnaya-ekskursiya-legendy-i-mify-stalinskix-vysotok/ дублируется.
    Можно как-то доработать функцию true_load_posts, чтобы она в моем случае работала корректно ?

  • Виталий 4 февраля 2016 #

    Пока сделал там обычную пагинацию(

  • Иван 16 мая 2016 #

    Михаил, подскажите пожалуйста мне нужно выводить после нажатия кнопки другое количество постов (установлено в настройках - 10) как прописать в обработчике нужный параметр, чтоб выводил например фиксированно только 2 поста?
    То есть после загрузки страницы выводится 10 постов, нажимаю на кнопку - еще два поста подгружается - вот так мне надо, спасибо!

    • Миша 17 мая 2016 #

      Перед тем, как выводится кнопка, изменяйте значение posts_per_page в $wp_query на 2 и значение paged судя по всему тоже, с 1 на 5.

  • Евгений Кириллов 28 июня 2016 #

    Очень добрый день.
    Сделал подгрузку через кнопку со стилями.

    Данные передаю через

    data-true-posts='<?php echo serialize($query->query_vars); ?>'

    Возвращаю

    $args = unserialize(stripslashes($_POST['query']));

    Но у меня в цикле массив рубрик, которые надо вывести

    $args = array( 
    							'post_type' => 'post',
    							'publish' => true,
    							'posts_per_page' => 4,
    							'category__in' => array(173,154,124,189,44,49,47,84,8,50,7,10,203,5,14,52,164,9,24,26,188,162,132,6)
    						);
    						$query = new WP_Query( $args );

    А подгружает только посты из первой рубрике в массиве.
    Как вывести посты со всех рубрик, указанных в массиве?

    • Миша 29 июня 2016 #

      Добрый день!

      Я не совсем понял последний кусок кода. Там задаётся переменная $args с нуля. Где этот код находится?

      • Евгений Кириллов 29 июня 2016 #

        Последний кусок кода перед циклом вывода записей на странице, условно news.php

        Соответственно,

        data-true-posts='<?php

        в кнопке в том же файле.

        И

        $args = unserialize(stripslashes($_POST['query']));

        в function.php

        • Миша 30 июня 2016 #

          А вы посмотрите, совпадают ли параметры $query->query_vars с параметрами из последнего куска кода 🙂

  • Евгений Кириллов 30 июня 2016 #

    Проверил.
    В обработчике php...

    function true_load_posts(){
    	$templ = $_POST['template'];
    	$args = unserialize(stripslashes($_POST['query']));
    	$args['paged'] = $_POST['page'] + 1; // следующая страница
    	$args['post_status'] = 'publish';
    	$args['posts_per_page'] = $_POST['ppp'];
     
    	foreach ($args['category__in'] as $value) {
    		echo $value.'<br>';
    	}
     
    	/* Здесь все ок. Выводится весь массив категорий */
     
    	$q = new WP_Query($args);
    	if( $q->have_posts() ):
    		while($q->have_posts()): $q->the_post();
     
    			foreach( get_the_category() as $category ){ 
    				echo $category->cat_ID;
    			}
    			/* А вот здесь уже только первая категория осталась */
     
    ...
    • Миша 30 июня 2016 #

      А, ну так в функцию get_the_category() нужно ID поста подсунуть, то есть заменить на:

      foreach( get_the_category( $q->post->ID ) as $category ){
      • Евгений Кириллов 30 июня 2016 #

        get_the_category() только проверки касается.

        Убрал из кнопки

        data-true-posts='<?php echo serialize($query->query_vars); ?>'

        и задал через

        var true_posts = '<?php echo serialize($query->query_vars); ?>';

        до кнопки. Проблема с категориями решилась.

  • Valeriy 23 августа 2016 #

    Здравствуйте, подскажите как в дополнение к постраничной подгрузке, сделать дополнительную кнопку "Показать все". Что бы по нажатию на нее подгружались все страницы за один раз, возможно с небольшой задержкой, дабы уменьшить нагрузку...

    • Миша 23 августа 2016 #

      Здравствуйте!

      То есть давайте предположим, что в данный момент мы подгрузили две страницы (на каждой странице по умолчанию - 10 постов) и находимся на третьей, и теперь хотим нажать кнопку "Показать всё".

      Алгоритм:

      1. Прежде всего для обработки я рекомендую использовать отдельную PHP функцию.
      2. Добавьте кнопку показа всего, привяжите её к функции, потестируйте что всё работает и тестовое сообщение (любое, например "привет") выводится.
      3. После этого вам нужно на стороне jQuery определить количество подгруженных постов, их можно вычислить непосредственно во время подгрузки постов, то есть выделить на них отдельную переменную, но также при нажатии на кнопку показа всех постов вы можете и определять их моментально, зная лишь CSS-класс блока поста.
        $('.entry-post').length;
      4. Со стороны PHP всё, что вам требуется, это передать в WP_Query два основных параметра — posts_per_page и offset следующим образом:
        $args = array(
        	'posts_per_page' => -1, // все посты
        	'offset' => $_POST['offset'] // начать с n-ного поста, в нашем случае с 31
        );
  • Леонид 23 августа 2016 #

    За статью Вам спасибо. Но меня приучали к тому что JS-код не должен находиться в файлах шаблонов, и поэтому предлагаю поправить:

    <?php if (  $wp_query->max_num_pages > 1 ) : ?>
    	<script>
    	var ajaxurl = '<?php echo site_url() ?>/wp-admin/admin-ajax.php';
    	var true_posts = '<?php echo serialize($wp_query->query_vars); ?>';
    	var current_page = <?php echo (get_query_var('paged')) ? get_query_var('paged') : 1; ?>;
    	var max_pages = '<?php echo $wp_query->max_num_pages; ?>';
    	</script>
    	<div id="true_loadmore">Загрузить ещё</div>
    <?php endif; ?>

    на

    <?php if( $wp_query->max_num_pages > 1 ): ?>					
    	<a href="#" class="show-more-articles">Загрузить еще</a>
    <?php endif; ?>

    а переменные передавать с функцией wp_localize_script:

    wp_localize_script('ajax-load-articles', 'Object', [
    																'url' => get_site_url().'/wp-admin/admin-ajax.php',
    																'true_posts' => serialize($wp_query->query_vars),
    																'current_page' => (get_query_var('paged')) ? get_query_var('paged') : 1,
    																'max_pages' => $wp_query->max_num_pages,
    			]);

    В обработчике ajax соответственно имена переменных изменятся так true_posts - Object.true_posts и т.д.

  • Леонид 23 августа 2016 #

    Только в функцию подключающую скрипты нужно будет передать из глобальной области видимости объект $wp_query, и забыл поправить первый параметр функции wp_localize_script под Ваш пример.

    • Миша 23 августа 2016 #

      Леонид, спасибо большое за полезное дополнение к статье!

      Я в первую очередь делал упор на то, чтобы сделать код в статье максимально доступным для максимального числа пользователей 🙂 В том числе я не стал усложнять код функцией wp_localize_script() — у некоторых с ней возникают трудности.

      • Леонид 24 августа 2016 #

        Понимаю) У меня она тоже вызывает взрыв мозга, но по сути она незатейливая - первым параметром просто пишется имя скрипта, перед которым будут вставляться переменные, а дальше просто описываются эти данные.

  • Леонид 25 октября 2016 #

    Столкнулся с такой проблемой - у меня выводятся записи на двух страницах - новости и блог, соответственно в каждом из шаблонов передается в запрос параметр для фильтрации категорий - как мне передать этот параметр в данную функцию подгрузки контента, чтобы при расчете параметра max_pages подставлялись верные данные (Кнопка "Показать еще" показывается пока цикл не пройдет по всем постам)?

    • Леонид 25 октября 2016 #

      Единственный вариант - если я вставляю Ваш код перед сбросом своего собственного запроса - до вызова функции wp_reset_query()

      • Миша 26 октября 2016 #

        Но в этом случае вы получаете неверные данные?

        Вообще вам нужно просто добавить пораметр к другим параметрам true_posts.

        • Леонид 26 октября 2016 #

          В этом случае я проблем не вижу - выводятся только статьи, новости фильтруются, кнопка исчезает когда и должна.

  • Иван 27 октября 2016 #

    Приветствую!
    Спасибо за код, все работает, стандартные посты выводит.
    Есть еще на сайте кастомные записи, у которых отличается внешний вид превью поста.
    Получается надо в function.php дублировать код и менять переменные? Или возможно там прописать условие типа если пост типа post то выводить так, а если кастомный то так?

    • Миша 27 октября 2016 #

      Добрый день, Иван,

      да, конечно ничего дублировать не нужно, вообще всё зависит от того, каким способом меняется внешний вид поста (иногда бывает через CSS-класс, иногда же полностью HTML может меняться).

      После того, как вы это определите, в любом случае вам понадобится использовать переменную $q->post->post_type в functions.php внутри цикла.

      • Иван 28 октября 2016 #

        У меня именно html в цикле другой совсем)

  • Иван 28 октября 2016 #

    Попробовал сделать вот так и не выводит по нажатию на кнопку.
    Сам цикл кастомных записей вывожу вот так:

       <?php
    	$args = array (
    	'post_type' => 'present',
    	'posts_per_page' => 6,
    	'orderby' => 'date',
    	'paged'=>get_query_var('paged')
    	 );
     
    	$present = new WP_Query($args); ?>
     
    	<?php while ( $present->have_posts() ) : $present->the_post(); ?>
     
    	HTML код вывода превью кастомных постов
     
    	<?php endwhile; ?>
     
    	<?php wp_reset_postdata(); ?>
     
        <?php if (  $wp_query->max_num_pages > 1 ) : ?>
            <script>
            var ajaxurl = '<?php echo site_url() ?>/wp-admin/admin-ajax.php';
            var true_posts = '<?php echo serialize($wp_query->query_vars); ?>';
            var current_page = <?php echo (get_query_var('paged')) ? get_query_var('paged') : 1; ?>;
            var max_pages = '<?php echo $wp_query->max_num_pages; ?>';
            </script>
     
        <?php endif; ?>
     
        <div id="true_loadmore" class="all_news shad">Загрузить ещё презентации</div>

    Вот так в function.php добавил условие elseif после вывода стандартных:

     
    function true_load_posts(){
    	$args = unserialize(stripslashes($_POST['query']));
    	$args['paged'] = $_POST['page'] + 1; // следующая страница
    	$args['post_status'] = 'publish';
    	$q = new WP_Query($args);
    	if( $q->have_posts() ):
    		while($q->have_posts()): $q->the_post(); 	?>
     
    HTML код вывода стандартных постов
     
    	<?php endwhile;
     
          elseif ( $present->have_posts() ):
          while($present->have_posts()): $present->the_post(); ?>
     
    HTML код вывода кастомных постов
     
     <?php endwhile;
    endif;
     
    	wp_reset_postdata();
    	die();
    }
     
    add_action('wp_ajax_loadmore', 'true_load_posts');
    add_action('wp_ajax_nopriv_loadmore', 'true_load_posts');
    • Миша 28 октября 2016 #

      А почему по-разному объекты названы? $q и $present.

      • Иван 28 октября 2016 #

        А как сделать условие, если стандартный пост то выводить этим кодом, а если кастомный то другим?

        • Миша 29 октября 2016 #
          if( $q->post->post_type == 'post' ) { // стандартный пост
           
          }else{ // кастомный
           
          }

          Про $present понятно?

  • Иван 29 октября 2016 #

    Спасибо! Вот так работает)
    $present я убрал вообще, вывожу стандартным циклом
    просто создал страницу archive-{post-type-name}.php

    • Миша 30 октября 2016 #

      Тоже вариант 🙂

  • Александр 5 ноября 2016 #

    Привет)

    Мегашикарный пост, но я словил баг там, где количество постов меньше указанного в админке - http://test.yarovikov.ru/category/svadba/

    Can't find variable: true_posts

    Вывожу цикл так:

    $loop = new WP_Query( array( 
       'orderby' => 'menu_order',
       'order' => 'DESC',
       'cat' => get_query_var('cat')  
       ));
    • Миша 5 ноября 2016 #

      Привет ) сорри, что-то недопонял, можно больше информации?)

      • Александр 5 ноября 2016 #

        У меня сейчас автоматическая подгрузка постов. В админке настроено показывать 4 поста. Там, где их показывается меньше, при прокрутке в консоли появляется с десяток-другой ошибок - ReferenceError: Can't find variable: true_posts. Например, здесь, если попробовать поскроллить - http://test.yarovikov.ru/category/svadba/

        Скриншот с ошибками - http://www.imageup.ru/img54/2590660/screen-shot-2016-11-05-at-123115.jpg

        • Миша 6 ноября 2016 #

          У меня на той странице ничего не подгружается и ничего нет вообще 🙂 только фото большое и всё.

          • Александр 6 ноября 2016 #

            Большое фото - это и есть пост - одна штука в категории свадьба. Что там еще должно подгружаться? Откуда такое количество ошибок в консоли?

          • Александр 6 ноября 2016 #

            В общем, удалось избавиться от ошибок путем удаления условия

            if (  $wp_query->max_num_pages > 1 ) :
  • Иван 6 ноября 2016 #

    А кстати, как убрать кнопку "Загрузить еще", если пока выводится меньшее кол-во, чем указано в админке?

    К примеру стоит на вывод 6 записей, опубликовано пока 3, а кнопка "Загрузить еще" стоит и смущает)

    Т.е. по идее надо кнопку убирать если выведено меньшее или равное кол-во записей указанных в админке.

    • Миша 6 ноября 2016 #

      А это условие не срабатывает получается?

      <?php if (  $wp_query->max_num_pages > 1 ) : ?>
  • Сергей 31 октября 2019 #

    Здравствуйте, может подскажите, можно ли сделать обновление без перезагрузки, если у меня навигация я даже не знаю как правильно сказать в общем вперёд назад и между ними номера страниц если нужно могу скинуть адрес сайта заранее благодарю))

    • Миша 1 ноября 2019 #

      Добрый день, Сергей!

      У меня для ваш хорошие новости – да, обновление без перезагрузки сделать можно!

      • Сергей 1 ноября 2019 #

        Может у вас есть какой то урок по поводу как это сделать или может знаете где можно прочитать поподробней всё обыскал таких подробных и понятных уроков не нашёл, но может не там и не то искал), Везде предлагают во такую до загрузку но мне такая "портянка" которая получается в итоге когда все посты загруженны))

        • Миша 2 ноября 2019 #

          К сожалению урока нет, если бы был, я бы с радостью поделился бы ссылкой)

          • Сергей 3 ноября 2019 #

            Спс за ответ.

  • Андрей 11 ноября 2019 #

    Здравствуйте, создал кастомные типы записей, но у них другой дизайн, подскажите как сменить

    get_template_part( 'template-parts/single', get_post_format() );

    незнаю как в js подгрузить

                    <?php if (  $wp_query->max_num_pages > 1 ) : ?>
                    <script>
                    var ajaxurl = '<?php echo site_url() ?>/wp-admin/admin-ajax.php';
                    var true_posts = '<?php echo serialize($wp_query->query_vars); ?>';
                    var current_page = <?php echo (get_query_var('paged')) ? get_query_var('paged') : 1; ?>;
                    var max_pages = '<?php echo $wp_query->max_num_pages; ?>';
                    var stemplate = 'template-parts/single-hot.php';
                    var loadingtext = '<?php _e('Loading', 'happy'); ?>';
                    </script>
                    <div class="col-12 render-this">
                        <div class="loadmore"><?php _e('Load more', 'happy'); ?></div>
                    </div>
                    <?php endif; ?>
    • Андрей 11 ноября 2019 #

      js сейчас в таком состоянии

      jQuery(function($){
          var loadtext = $('.loadmore').text();
      	$('.loadmore').click(function(){
      		$(this).text(loadingtext).addClass('spin');
      		var data = {
      			'action': 'loadmore',
      			'query': true_posts,
      			'page' : current_page
      		};
      		$.ajax({
      			url:ajaxurl,
      			data:data,
      			type:'POST',
      			success:function(data){
      				if( data ) { 
                          $('.render-this').before(data);
                          $('.loadmore').text(loadtext).removeClass('spin');
      					current_page++;
                          if (current_page == max_pages) $('.loadmore').remove();
      				} else {
      					$('.loadmore').remove();
      				}
      			}
      		});
      	});
      });
      • Андрей 12 ноября 2019 #

        сам спросил – сам ответил)
        может кому помогу, реализовал так:

        function true_load_posts(){
        	$args = unserialize( stripslashes( $_POST['query'] ) );
        	$args['paged'] = $_POST['page'] + 1;
        	$args['post_status'] = 'publish';
         
        	$stemplate = 'template-parts/single' .  $args['post_type'];
         
        	query_posts( $args );    
         
        	if( have_posts() ) :
        		while( have_posts() ): the_post();
        			get_template_part( $stemplate, get_post_format() );
        		endwhile;
        	endif;
         
        	die();
        }

        сделал переменную stemplate ей присвоил post_type, если стандартные записи то выводит single.php если кастом, то single{название_кастомных_записей}.php
        не знаю насколько это все правильно, но работает)

  • Alexey 21 ноября 2019 #

    Подскажите пожалуйста, что нужно изменить, чтобы это заработало на WooCommerce?
    Вставил кнопку, подключил скрипт, но с php обработчиком проблема, хотя для обычного WP блога все работает отлично. Заранее спасибо за помощь.

  • Михаил 23 февраля 2020 #

    Добрый вечер, у меня ситуация чуть другая,яподключил скрипты,проверил подключение, но подгрузку делаю на своём файле blog.php Сделал вывод постов минимум 4 через чтение, добавляю кнопку , а она не добавляется, цыкл у меня чуть другй через вп квери скрин ссылка http://prntscr.com/r6kqo6 Выше цикл ниже кнопка , но она не выводится. Яуже и так и сяк такое чувство что чего то не хватает в коде.

    • Миша 24 февраля 2020 #

      Добрый вечер,
      $query и $wp_query – не одно и то же.

      • Михаил 25 февраля 2020 #

        Спасибо, я нашёл проблему, кнопка выводится, я всё подключи вставил скрипты и пхп в function , но при клике на кнопку пишет (загружаю) , но при этом посты не загружаются Вот страница на которой делаю http://stp.yugen.com.ua/blog делал всё как по инструкции , но не выходит, со скролом так же не подгружает

      • Михаил 25 февраля 2020 #

        я так понимаю что мне надо что то поменять в функции true_load_posts скрин кода фанкш пхпи блог пхп http://prntscr.com/r7kwa5

  • Евгений 11 марта 2020 #

    Привет! Спасибо за труд! Регулярно пользуюсь твоими решениями.
    Подскажи, как после каждой подгрузки выводить нужный контент, например рекламынй баннер.

    • Миша 11 марта 2020 #

      Привет!

      Да, пожалуйста! 🙂

  • Denis 14 марта 2020 #

    Миша, спасибо за классную статью. Все работает. Но возникла проблема. Использую стандартную пагинацию и твою кнопку. Как сделать, что бы при нажатии на кнопку подгрузки постов, пагинация тоже изменялась.
    Спасибо.

    • Миша 15 марта 2020 #

      Хороший вопрос!

      Ну когда я делал подобное, я подгружал новую пагинацию в том же запросе. Только не сплошным HTML, а через json.

  • Арсений 23 марта 2020 #

    Добрый день, подскажите как можно реализовать для кастомных типов записей?
    (созданных через register_post_type). Спасибо!)

  • Вадим 13 апреля 2020 #

    Добрый день!

    Использовал ваш код, для подгрузки постов, всегда работало на ура, а тут косяк вылез.
    Постоянно выводит в конце подгруженных постов 0.

    Не пойму в чем дело(

    • Миша 14 апреля 2020 #

      Добрый день,

      Посмотрите, в комментах вроде был ответ, и я наверное их закрою, уже и так больше 300.