AJAX must go on: читаем в wordpress архивы без перезагрузки страницы (или а-ля ВКонтакте с помощью jQuery)
Продолжаем совершенствовать сайт на базе wordpress. Речь опять идёт о сайте моей жены. В предыдущей статье описал, как подгружать содержание статьи по нажатию на ссылку “Читать дальше” через AJAX, теперь – обеспечим чтение всего архива без перезагрузки страницы (wordpress бьёт их по страницам, по страницам и будем подгружать).
Начну с конца. Посмотреть результат моей работы Вы можете здесь http://www.nice-tour.nov.ru/news. Просто нажимайте PageDown на своей клавиатуре и следите за скроллбаром – увидите, что содержимое подгржается по ходу Вашего чтения.
Для начала заставим наш сайт самостоятельно нажимать ссылку “следующая страница” в момент, когда пользователь пролистал сайт практически до самой ссылки “следующая страница”. Несмотря на то, что задача простая до невозможности, её решение имеет массу подводных камней. Для начала приведу сценарий на jQuery:
var backgroundAction = false; jQuery(function() { if (!$(".page-container").length) return; $(window) .bind('scroll', function(e) { var content = $(".page-container:last"); if ( $(window).scrollTop() + (1+1) * $(window).height() > content.offset().top + content.height() ) { backgroundAction = true; $(".nextpostslink").click(); backgroundAction = false; }; }) ; });
Как видно, скрипт просто примитивен. Сначала проверяю, а есть ли на странице контейнеры “страниц”. Если нет – то и не нужен наш сценарий. Если есть – цепляю обработчик на scroll
для окна. Дальше проверяю позицию последнего контейнера “виртуальной страницы” по отношению к окну. И если до его (контейнера) нижней границы (top+height
) осталось меньше одной высоты окна (то есть одно нажатие page down, поэтому и написал (1+1)*$(window).height
), имитирую нажатие на ссылку (следующая страница). Указанный класса nextpostslink
является стандартным в случае wordpress.
Дальше всё будет сложнее. Теперь, собственно, нам и нужно обеспечить возможность AJAX загрузки следующей страницы при нажатии на ссылку (не важно как мы её “нажали” – предыдущим сценарием или мышкой). И для решения этой задачи, к великому моему сожалению, без модификации файлов темы я ничего сделать не смог. Буду благодарен за любые подсказки о том, как обеспечить независимую от темы реакцию на подобный AJAX запрос.
Итак, модифицируем файл темы. Приведу пример на index.php, но править придётся все файлы для архивов (archives.php и так далее, если они есть).
';}; }; if (have_posts()) { $post = $posts[0]; // Hack. Set $post so that the_date() works. if( !is_ajax_read_next_page() ) { if(is_category()){ echo 'Архив рубрики: »'.single_cat_title('',FALSE).' «
'; }elseif(is_day()){ echo 'Архив: » '.get_the_time('F jS, Y').'«
'; }elseif(is_month()){ echo 'Архив: » '.get_the_time('F, Y').' «
'; }elseif(is_year()){ echo 'Архив: » '.get_the_time('Y').' «
'; } elseif(is_search()){ echo 'Результаты поиска
'; }elseif(is_author()){ echo 'Автор архива
'; }elseif(isset($_GET['paged']) && !empty($_GET['paged'])){ // If this is a paged archive echo 'Архивы блога
'; }elseif(is_tag()){ echo 'Теги архива: » '.single_tag_title('',FALSE).' «
'; }; ?>" >" class="entry">Рубрики: Теги: ', ', ', ''); ?> Не найдено
К сожалению, по Вашему запросу ничего не найдено.
Выделением показал свои модификации файла темы. Как видно, в случае ответа на AJAX запрос мы отдаём токлько свой контейнер “страницы” и оформленные темой анонсы статей. Всё остальное – обрезаем (точнее – просто не генерируем). Безусловно, можно пытаться ту же работу проделать уже на стороне клиента, на jQuery, но тогда чем же это будет быстрее? Мы заставим wordpress генерировать и sidebar, и всё остальное, а потом всё это будем резать? Да и зачем на клиента вешать лишнюю работу? Хотя такой вариант попробую, он, возможно, будет работать без модификации файлов темы, чем и интересен…
А теперь сценарий, который выполнит AJAX запрос при нажатии на ссылку “Следующая страница”:
jQuery(function() { jQuery('#content') .delegate('', 'onupdate.ajaxReadMore', function(e) { jQuery('.page-container').AJAXReadMore({ ajaxData: { 'ajax-read-next-page-mode':'1' }, contentElSelector: ".page-container", errorMessage: "Ошибка загрузки следующей страницы.
Попробуйте позднее.", moreElSelector: ".nextpostslink", moreContainerSelector: ".navigation", scrollToSelector: ".navigation" }); }) .trigger('onupdate.ajaxReadMore') ; });
Как видно, этот сценарий использует jQuery плагин AJAXReadMore, который я собрал в предыдущей статье. И понимать этот код следует следующим образом: при обновлении содержимого страницы мы находим контейнеры с классом page-container (именно такой контейнер мы и добавили в файл темы), и находим в нём ссылку с классом nextpostslink. При нажатии на эту ссылку мы будем скроллировать документ в окне браузера до начала нашего контейнера page-container, подгружать следующую страницу, после чего с анимацией удаляем контейнер со ссылкой (navigation) и показываем подгруженное содержание.
Файл плагина wordpress:
Суть проста до безобразия – просто подключаем описанные выше сценарии в “подвал” страницы (да, тема должна поддерживать подвал – wp_footer
, как это сделать – писал раньше).
Также мы добавили предикат is_ajax_read_next_page
. Он даёт нам возможность определить, готовим ли мы ответ на AJAX запрос или на обычный HTTP GET запрос. И определяет он (предикат) этот факт по наличию URL параметра ‘ajax-read-next-page-mode’, который добавляется в запрос при конфигурировании плагина AJAXReadMore.
Такие вот дела. Работает это решение здесь. В ближайшее время внедрю и к себе на блог, руки не дошли пока что
Здравствуйте, установил плагин. По нажатию читать далее идет загрузка, а потом все равно перезагружает страницу? В чем проблема? Помогите пожалуйста!!! вот адрес сайта http://snv.emo.su
Николай, благодарен Вам за использование моего творчества :-). Вижу, AJAX Read more Вы установили и он у Вас успешно работает. Смотрим дальше.
А вот к AJAX Read Next Page тема у Вас не готова. Я так понимаю, для формирования постраничных ссылок (1, 2, 3, следующая) Вы использовали какой-то плагин? При этом этот плагин не проставил «стандартный» для wordpress класс для ссылки на следующую страницу, поэтому мои скрипты и не находят ссылку. Если Вам нужна постраничная навигация, рекомендую плагин WP-PageNavi (если тема не готова под него, её легко можно «допилить», процедура описана здесь: “Оживляем” постраничную навигацию в темах (wordpress и плагин WP-PageNavi)). Указанный плагин хорош тем, что кроме приличного дизайна даёт ещё и корректные классы для ссылок. Как уже понятно из статьи, класс для ссылки на следующую страницу должен быть
nextpostslink
, как и рекомендуется кодексом wordpress.Итак, после указанных манипуляций мои скрипты будут находить у Вас ссылку на следующую страницу архива. Но этого недостаточно. В статье выше описаные модификации, которые необходимо внести в файлы темы (index.php, archives.php (если есть), home.php (если есть)). Скрипты ориентированы на наличие контейнера
.page-container
, которого нет, а также на наличие условного формирования страницы (чтобы корректно сформировать ответ на ajax запрос). До модификации файлов темы Вам необходимо в папку plugins распаковать архив (должна появиться папка с аналогичным наименованием). В ней — описанные выше скрипты. Заходим в консоли wordpress в меню Плагины и активируем плагин AJAX Read Next Page. Вот теперь необходимо внести в файлы темы описанные выше изменения. И при нажатии на ссылку «Следующая» (подразумевается — страница) её содержание будет подгружаться непосредственно в текущую страницу через ajax. И только после того, как Вы отладите этот процесс, можно приступать к следующему — автоматической загрузке следующей страницы при скроллировании. Грузим в plugins архив плагина AJAX next posts link auto click и его активируем. И всё должно заработать.Сообщайте пожалуйста о проблемах и результатах, буду рад помочь. Законченное решение выложу по мере готовности в репозиторий wordpress.
Николай, Вы сейчас отказались от использования плагина AJAX-Read-More. Не подскажете, какой функциональности Вам не хватило в этом плагине?
Очень признателен, что ответили. Не использую, так как идет загрузка материала и все на этом, а в чем проблема не пойму.
Николай, буду Вам благодарен, если Вы снова активируете плагин (только перед этим обновите его, последняя версия в репозитории) и сразу сообщите мне (лучше всего в комментарии на статью о самом плагине). Я тогда смогу посмотреть, что не так, и исправить.
Ваш сайт сейчас не отвечает — где то в PHP коде ошибка. При чём ошибка не runtime, а времени «компиляции», если так можно выразиться, то есть — в синтаксисе где-то ошибка.
Спасибо, Сергей Сергеевич. НО у меня другая теперь проблема, не могу зайти в консоль, что делать????
Для начала рекомендую «отключить» все плагины. Процедура следующая — переименуйте каталог plugins. И попробуйте войти в консоль. Если получится, тогда переименуйте указаный каталог обратно и по одному активируйте плагины. При активации они будут проверяться на фатальные ошибки и Вы увидите, какой из плагинов «убил» Ваш сайт. У меня такое было не раз в процессе обновления плагинов, поэтому — смело можете испробовать подобный метод.
Спасибо. Буду пробовать!!
Сделал как вы сказали, пришлось перейти на платный хостинг. установил ваш плагин, но безрезультатно.
Раз меняли хостинг, рекомендую проверить версию PHP на хостинге, MySQL, расширения PHP — выполнены ли требования WordPress. На всякий случай можно заменить все файлы WordPress (скачать и перезалить). Ну а дальше поможет уже только отладчик. Рекомендую для начала включить отладку в PHP.ini. (debug, если не ошибаюсь). Тогда уже можно будет увидеть хоть что-то.
Все заново сделал. Поставил плагин, но все равно не идет!! Даже и не знаю.
Николай, так у Вас сайт вообще не отвечает сейчас. Ряд вопросов:
- Адрес-то сайта прежний?
- Без плагина сайт нормально работает?
- Какая версия PHP на хостинге?
- версия WordPress?
добрый день, вот адрес сайта s-n-v.ru, раотает сейчас все нормально, версия php5, wordpress 3.2.1
Николай, благодарю за информацию и ссылку http://s-n-v.ru/.
Отличное решение, но никак не могу приспособить его для вывода комментариев. Может есть какие-то готовые варианты? Если что, благодарен.
Я планирую в дальнейшем для комментариев свой плагин строить, но здесь потребуется модификация темы… Так что полностью готового плагина для Вашей задачи предложить не могу.
Добрый день! У меня стоит версии 3.3 wordpressa и слетела постраничная навигация рубрик. Я как понимаю без её не будет работать AJAX Read Next Page?!
На самом деле мой плагин не связан с постраничной навигацией. Он использует и «преобразует» ссылки со «стандартным» для wordpress классом
.nextpostslink
. Посему прямой связи между плагином постраничной навигации и моим плагином нет.Значит сейчас буду пытаться поставить плагин. с версией 3.3 работает нормально?!
Денис » Да, проблем не заметил. Но — он сам по себе работать не будет. Для работы этого плагина требуется внесение изменений в тему, которые описаны в статье. К сожалению, архитектура WordPress не ориентирована на текущий момент на AJAX, посему и приходится «допиливать».
как я понимаю нужно закачать три плагина (AJAX next posts link auto click, AJAX Read More, AJAX Read Next Page), а дальше править в теме где надо чтоб работали скрипты?! Только я так и не понял что именно добавлять надо?!
Суть в следующем: AJAX Read More — самостоятельный плагин (продолжение статьи по подгружает через AJAX), AJAX next posts link auto click — тоже самостоятельный, хотя полноценным его не назовёшь. Он всего лишь вызывает событие onclick для ссылки
.nextpostslink
, сам его не обрабатывает. Поэтому если он будет поставлен сам по себе, то при прокрутке архива статей вниз «автоматом» будет загружаться следующая страница архива, но не через AJAX, а «обычным» переходом.И третий плагин (AJAX Read Next Page) также самостоятелен. Он может быть установлен и один, сам по себе. При этом нажимать на ссылку «следующая страница» придётся самому (либо предыдущий плагин для этого использовать), а он лишь обеспечит подгрузку следующей страницы архива через AJAX. Но для корректного формирования AJAX ответа как раз и требуется модификация темы (в статье приведён пример модификации archives.php, в Вашем случае этим файлом может оказаться и categories.php, и tags.php, и index.php). Суть в том, что в том случае, если формируется ajax ответ, требуется только часть страницы, без sidebar и прочего, посему «ненужную» часть Вы должны генерировать только по условию (пример в статье).
Вообще понять не могу, мб нуб просто… установил все плагины, залил скрипты в футер, добавил контейнер в индекс, а ошибка все та-же 500, уже всяко перекопал, даже не знай куда бы еще копнуть… И еще… Что за странная запись php? вида <!—?php , двойные ковычки в дивах div=»»content»» Это по приколу или так надо?)
Ошибка 500 — лучше всего для её обнаружения включить режим отладки в php.ini и увидите, на чём возникает ошибка. Касательно записи <!—?php — это начало комментария, то есть конкретно этот блок Php кода в комментариях, он не будет исполнен, его можно просто пропустить.
Двойные кавычки в id ни к чему, тут один из плагинов у меня так лихо код отобразил… исправлю.
И пожалуйста сообщить адрес сайта, на котором проводите эксперименты, а то так я точно ничем помочь не смогу…
ikar-kch.ru/test
т.е. ссылка типа http://ikar-kch.ru/test/?cat=1 выдаст ошибку, ибо за отсутствием файла category.php использует модифицированный index.php
Нет, конечно, всё будет работать без ошибок. У меня никакой привязки к конкретной структуре url нет, мой плагин url не разбирает (кроме выявления одного параметра), url разбирает сам wordpress.
Обратите внимание на тот факт, что в index.php код нужно вставлять с условным оператором, как у меня и покано, и он будет «вырезать» лишнее только в том случае, если обнаружит в url параметр, сгенерированный моим jquery плагином. если его нет — index.php будет работать по старому, поэтому и в Вашем случае он будет работать замечательно.
Немного не в ту сторону идем, ссылку я привел для просмотра, сейчас убрал из индекса все лишнее, кроме контейнера «page-container», не работает подгрузка… Может просто что-то где-то просмотрел? 3 плагина установлены в футере скрипт… что еще может не так быть? файл индекса:<?php include ( «header2.php»); ?> <?php if (have_posts()) : ?><div class=»page-container»> <?php while (have_posts()) : the_post(); ?> <div class=»post» id=»post-<?php the_ID(); ?>»><div class=»homepage_post»> <div class=»homepage_in»> <div class=»sdf»><?php if(function_exists(‘get_the_image’)) { get_the_image(array(‘image_scan’ => true)); } ?></div> <h2><a href=»<?php the_permalink() ?>» rel=»bookmark»><?php the_title(); ?></a></h2> <?php the_excerpt(__(‘Read More »’));?> <div class=»excrept_but» style=»color: #99958c;»> Комментарии: <?php comments_popup_link(’0′, ’1′, ‘%’); ?> | <?php the_views() ?> </div> <p class=»pageInfo»> </div></div></div> <?php endwhile; ?></div><!—[if IE]><div style=»display: block; float: right;»><![endif]—> <hr><center><br> <?php wp_pagenavi(); ?> <!—[if IE]></div><![endif]—> <?php else : ?> <h2 class=»center»>Записей не найдено. Попробуйте воспользоваться поиском?</h2> <p><strong>К сожалению, по вашему запросу ничего не найдено</strong></p> <p><em></em></p> <?php include (TEMPLATEPATH . ‘/searchform.php’); ?> <?php endif; ?><![if !IE]><?php get_sidebar(); ?><![endif]> <?php include ( «footer_ie.php»); ?>в футере<?php wp_footer(); ?>код всякий….<!—?phpadd_action(‘init’, ajax_read_next_page_init);function is_ajax_read_next_page() { return ($_GET['ajax-read-next-page-mode']);}function ajax_read_next_page_init(){ $pluginDIR = WP_PLUGIN_DIR . ‘/’ . dirname(plugin_basename(__FILE__)) . ‘/’; $pluginURL = WP_PLUGIN_URL . ‘/’ . dirname(plugin_basename(__FILE__)) . ‘/’; if(!is_admin()) { wp_register_script( ‘jquery.ajax.readmore’, $pluginURL . «jquery.ajax.readmore.js», array(‘jquery’), false, true ); wp_register_script( ‘readNextPage’, $pluginURL . «readNextPage.js», array(‘jquery.ajax.readmore’), false, true ); wp_enqueue_script(‘jquery.ajax.readmore’); wp_enqueue_script(‘readNextPage’); };}?—><script type=»text/javascript»>var backgroundAction = false;jQuery(function() { if (!$(«.page-container»).length) return; $(window) .bind(‘scroll’, function(e) { var content = $(«.page-container:last»); if ( $(window).scrollTop() + (1+1) * $(window).height() > content.offset().top + content.height() ) { backgroundAction = true; $(«.nextpostslink»).click(); backgroundAction = false; }; }) ;});jQuery(function() { jQuery(‘#content’) .delegate(», ‘onupdate.ajaxReadMore’, function(e) { jQuery(‘.page-container’).AJAXReadMore({ ajaxData: { ‘ajax-read-next-page-mode’:’1′ }, contentElSelector: «.page-container», errorMessage: «Ошибка загрузки следующей страницы.<br>Попробуйте позднее.», moreElSelector: «.nextpostslink», moreContainerSelector: «.navigation», scrollToSelector: «.navigation» }); }) .trigger(‘onupdate.ajaxReadMore’) ;});</script>Что-то не так видимо
ой как не красиво))) все ентеры убрал)
Сергей, добрый день!Скажите, использование вашего плагина не препятствует корректной индексации поисковиками, в частности Рубрик?
Жорик » абсолютно не препятствует. Все ссылки для поисковиков остаются просто ссылками. Иная реакция на click на них вешается уже через jQuery плагин мой уже на клиенте. Чтобы проверить — просто отключите скрипты в браузере на время. Увидите, что всё работает. Так же это всё видит и поисковый робот.
… и еще, заметил такой момент: в коде присутствуют ссылки постраничной навигации. Поэтому, они скорее всего будут проиндексированы. Cсылка на страницу выглядит так:
site.ru/news/page/2, соответственно, рано или поздно, эта ссылка появится в выдаче поисковиков, и пользователь, вполне сможет по ней перейти.
На примере сайта вашей жены — получается так, что когда я перехожу по этой ссылке (на страницу № 2) я попадаю именно на нее, а логично было бы попадать на страницу Рубрики (
site.ru/news) и именно в то место, где начинается контент этой страницы (что то на подобии якоря)
Жорик » Я сознательно не стал переделывать постраничную выдачу wordpress. Во-первых, мой плагин требует поддержки javascript. Но и без неё всё должно работать (как работало бы без плагина). Поэтому постраничная выдача сохранена. И, кроме того, когда страниц будет более 100 — не всякий браузер потянет страницу такого размера (в частности — мобильный). Поэтому будущее за постраничной выдачей.
…хммм, прошло 2 дня и без ответа! модератор наверное на курорт махнул:)
Жорик » Не, не на курорт. У меня в жизни сейчас серьёзный момент, посему и несколько задерживаюсь с ответами. Чуть позднее опишу ситуацию.