WordPress как на ладони
wordpress jino

Динамический архив блога с использованием jQuery (Ajax)

Все мы видели архивы, в которых при выборе месяца нас перекидывало на страницу с записями за этот месяц. В WordPress такой вывод архивных ссылок реализуется с помощью функции wp_get_archives(). Аналогичный архив записей получается и при выводе обычных рубрик WordPress, только записи группируются по категориям.

Динамический архив блога с использованием jQuery (Ajax)

Сегодня я хочу рассказать вам, как сделать динамическую архивную страницу. "Динамическая" значит, что  при выборе месяца, результаты будут показываться на той же странице, при помощи AJAX — технологии Javascript. Так как библиотека jQuery предоставляет удобный API по работе с Ajax, то будем использовать этот фреймворк. К тому же, куда сегодня без jQuery? Он ведь используется сплошь и рядом, и наверняка в вашем проекте он уже подключен.

Перед написанием этой статьи я сделал динамическую архивную страницу для этого блога, предлагаю взглянуть (ДЕМО).

Итак.

Чтобы реализовать динамический архив нам нужно пройти 4 этапа:

Оглавление:

Я буду показывать создание динамической страницы архивов на примере базовой темы WordPress: "twentyten".

1. Подключение jQuery в WordPress

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

<?php 
add_action( 'wp_enqueue_scripts', 'my_scripts_method' );
function my_scripts_method(){
	wp_enqueue_script( 'jquery' );
}
?>

Вставлять этот код нужно в файл темы functions.php.

Вариант 2

В первом варианте мы подключили скрипт с нашего сервера, имеющийся в файлах WordPress. Однако, можно изменить ссылку на файл jQuery и подключить его с CDN Google. Преимущество такого подхода в том, что, если в браузере посетителя уже загружен этот файл, то при заходе на ваш сайт браузер уже не будет загружать скрипт/ Загрузка страницы увеличится. Кроме того, в CDN скрипт отдается в сжатом виде, за счет чего файл легче на несколько килобайт:

function my_scripts_method() {
	wp_deregister_script( 'jquery' );
	wp_register_script( 'jquery', '//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js');
	wp_enqueue_script( 'jquery' );
}    

add_action( 'wp_enqueue_scripts', 'my_scripts_method' );
Вариант 3

Самый древний и так называемый "жесткий" вариант подключения jQuery - это прописать ссылку на него в файле шаблона header.php, внутри тега </head> . Вставляем такой html код:

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
к началу

2. Загрузим картинку пред-загрузчик

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

Чтобы в дальнейшем у нас была такая картинка, давайте скачаем её, например, от сюда: Анимированные gif (сервис мне понравился), переименуем её в ajax-loader.gif и загрузим в папку images, которая находится в каталоге нашей темы WordPress. В итоге у нас получиться такой пусть до картинки: http://site.ru/wp-content/themes/twentyten/images/ajax-loader.gif. Ниже мы его используем в коде.

к началу

3. Создание шаблона постоянной страницы

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

<?php
/*
	Template Name: Шаблон архивов
*/
?>

"Шаблон архивов" — это название нашего шаблона, которое мы увидим в админ-панели WordPress, при создании постоянной страницы.

Давайте создадим новый файл в папке темы, с названием tpl_archive.php и вставим туда вышеприведенный код. Затем зайдем в админ-панель WordPress и создадим постоянную страницу, назначив ей, только что созданный, шаблон.

Теперь, заполним этот файл необходимым кодом.

1. В первую очередь, нам нужно вывести выпадающие списки, создадим мы их с помощью функций WordPress: wp_get_archives() и wp_dropdown_categories():

<?php
/*
	Template Name: Шаблон архивов
*/
?>

<?php get_header(); ?>

<div id="archive_browser">
	<div>
		<h4>Месяцы</h4>
		<select id="month-choice">
			<option val="no-choice"> — </option>
			<?php wp_get_archives(array(
	'type' => 'monthly',
	'format'  => 'option'
			)); ?>
		</select>
	</div>
	<div>
		<h4>Рубрики</h4>
		<?php wp_dropdown_categories('show_option_none= -- '); ?>
	</div>
</div>

<div id='archive_pot'></div>

<?php get_footer(); ?>

get_header(); и get_footer(); получают шапку и подвал шаблона соответственно. get_sidebar(); я вырезал намеренно, чтобы он не мешался в понимании кода. Остальная часть кода выводит выпадающие списки Месяцев и Рубрик.

Пустой блок <div id='archive_pot'></div> — это контейнер куда будут выводится результаты запроса, т.е. записи.

2. Оформим выпадающие списки через CSS, для этого добавим такой код сразу после вызова шапки (<?php get_header(); ?>):

<style type="text/css" rel="stylesheet" >

#archive_browser > div { display: inline-block; padding-right: 10px; }

#archive_pot { min-height:150px; }

#archives_table { border-collapse:collapse; margin:15px 0 0 0; width:100%; }

#archives_table td { min-height:25px; padding:4px; border-top:1px solid #eee; border-bottom:1px solid #eee; }
</style>

На этом этапе у меня получилось следующее:

3. Добавим JavaScript код, который будет выполнять запрос к серверу и выводить его в блок archive_pot (код добавляем после css стилей):

<script type="text/javascript">
(function($){
	$(function(){

		$("#archive_browser select").change(function(){
			$("#archive_pot")
	.empty()
	.html("<div style='text-align:center; padding:30px;'><img src='<?php bloginfo('template_url') ?>/images/ajax-loader.gif' /></div>");
	var dateArray = $("#month-choice").val().split("/");
			var y = dateArray[3];
			var m = dateArray[4];
			var c = $("#cat").val();
	$.post(
	"<?php bloginfo('template_url') ?>/scripts/archive_getter.php",
	{
		year : y,
		month : m,
		cat : c
	},
	function(data) {
		$("#archive_pot").html(data).animate({ height: $("#archives_table").height()+40 });
	}
	);
		});
	});
})(jQuery)
</script>

Разберем немного код:
Все что внутри $("#archive_browser select").change(function(){...} будет срабатывать при изменении выпадающих списков.

<?php bloginfo('template_url') ?>/images/ajax-loader.gif — путь до файла-картинки (загрузка...), которая будет подгружаться в период запроса.

<?php bloginfo('template_url') ?>/scripts/archive_getter.php — путь до файла обработчика запроса, который мы создадим на следующем этапе.

$.post(...); — Функция jQuery, создающая запрос браузера к серверу, используя AJAX технологию.

Полные код шаблона постоянной страницы

Файл шаблона постоянной страницы (создаем файл в папке темы и копируем туда этот код):

<?php
/*
	Template Name: Шаблон архивов
*/
?>

<?php get_header(); ?>

<style type="text/css" rel="stylesheet" >

#archive_browser > div { display: inline-block; padding-right: 10px; }

#archive_pot { min-height:150px; }

#archives_table { border-collapse:collapse; margin:15px 0 0 0; width:100%; }

#archives_table td { min-height:25px; padding:4px; border-top:1px solid #eee; border-bottom:1px solid #eee; }
</style>

<script type="text/javascript">
(function($){
	$(function(){

		$("#archive_browser select").change(function(){
			$("#archive_pot")
	.empty()
	.html("<div style='text-align:center; padding:30px;'><img src='<?php bloginfo('template_url') ?>/images/ajax-loader.gif' /></div>");
	var dateArray = $("#month-choice").val().split("/");
			var y = dateArray[3];
			var m = dateArray[4];
			var c = $("#cat").val();
	$.post(
	"<?php bloginfo('template_url') ?>/scripts/archive_getter.php",
	{
		year : y,
		month : m,
		cat : c
	},
	function(data) {
		$("#archive_pot").html(data).animate({ height: $("#archives_table").height()+40 });
	}
	);
		});
	});
})(jQuery)
</script>

<div id="archive_browser">
	<div>
		<h4>Месяцы</h4>
		<select id="month-choice">
			<option val="no-choice"> — </option>
			<?php wp_get_archives(array(
	'type' => 'monthly',
	'format'  => 'option'
			)); ?>
		</select>
	</div>
	<div>
		<h4>Рубрики</h4>
		<?php wp_dropdown_categories('show_option_none= -- '); ?>
	</div>
</div>

<div id='archive_pot'></div>

<?php get_footer(); ?>
к началу

4. Создание файла-обработчика

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

Давайте создадим папку scripts в каталоге темы, в ней создадим файл archive_getter.php (/wp-content/themes/twentyten/scripts/archive_getter.php) и заполним этот файл следующим кодом:

<?php 

// подгружаем среду WP
require($_SERVER['DOCUMENT_ROOT'].'/wp-load.php');

// фильтруем POST данные, передаваемые этому файлу с Javascript
$year = htmlspecialchars(trim($_POST['year']));
$month = htmlspecialchars(trim($_POST['month']));
$cat = htmlspecialchars(trim($_POST['cat']));

?> 

<table id="archives_table">
	<?php
	if( ($year=='') && ($month=='') && ($cat=='-1') ){
		echo "<tr><td style='text-align: center; font-size: 15px; padding: 5px;'>Пожалуйста, выберите дату/категорию из списка выше.</td></tr>";
	}
	else
	{
		// Получаем данные с помощью query_posts
		query_posts("posts_per_page=-1&cat=$cat&monthnum=$month&year=$year");
		// выводим данные в Цикле WordPress
		if( have_posts() ){ while( have_posts() ){ the_post(); ?>
			<tr>
	<td><a href='<?php the_permalink(); ?>'><?php the_title(); ?></a></td>
	<td><?php comments_popup_link(' ', '1 Комментарий', '% Комментариев'); ?></td>
	<td><?php the_time('j.m.Y'); ?></td>
			</tr>
			<?php
		}}
		else // Если постов нет
			echo "<tr><td style='text-align: center; font-size: 15px; padding: 5px;'>Ничего не найдено.</td></tr>";
	} ?>
</table>

Небольшой разбор кода:

Сначала мы подгружаем среду WordPress (все настройки, функции, плагины). Делается это для того, чтобы нам стали доступны функции WordPress, в частности query_posts(), которую мы используем в этом файле для получения данных.

Условием if( ($year=='') && ($month=='') && ($cat=='-1') ){...} мы проверяем существуют ли какие-либо данные, которые мы позднее можем использовать в функции query_posts(), если дынных нет, то выводим сообщение.

query_posts("posts_per_page=-1&cat=$cat&monthnum=$month&year=$year"); и все что ниже это привычный Цикл WordPress.

Вот и все, страница готова!

Вот что у меня получилось (правда, это всего-лишь картинка. Живой пример см. здесь):

П.С. Написать этот пост мене предложили в комменатиях, точнее попросили перевести английскую статью: Динамические архивы (Dynamic Archives). Статья мне понравилась, идея статьи, потому что на её основе можно научится использовать AJAX и попрактиковаться с Циклами WordPress. Переводить статью я не стал, а написал по своему, даже код пришлось изменить. Обращаясь к Вячеславу (комментатору): у вас не получилось реализовать этот метод, потому что оригинальная статья не полная, авторы почему-то не описали некоторые моменты, без которых код работать не будет.

Спортзал новокосино

Спортзал новокосино фитнес клубы в новокосино.

Реклама
Динамический архив блога с использованием jQuery (Ajax) 67 комментариев
Полезные 2 Вопросы 4 Все
  • Ping cайт: kudabra.ru/arhives

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

    Заранее спасибо.

    Ответить2.6 года назад #
    • Kama4090

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

      query_posts("posts_per_page=-1&cat=$cat&monthnum=$month&year=$year");

      Проверьте все ли переменные передаются так как нужно.

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

      По тому вопросу который вы задали я помочь никак не могу - информации нет...

      Ответить2.6 года назад #
  • Роман cайт: jblog-project.ru

    Добрый вечер Тимур! Вот спасибо, вам bravo
    Использовал динамические архивы у себя на блоге и так замечательно получилось!
    Хочу пожелать вам удачи и новых идей!

    Ответить1.8 года назад #
  • Дмитрий cайт: webcomp.by

    Добрый день. Подскажите, как сюда добавиь поиск по тегам?

    Ответить1.3 года назад #
  • Лариса

    Тимур, добрый день!
    Не совсем по теме поста, но тоже про ajax: как правильно передать в аякс-запрос id текущего поста?
    На странице произвольно построенным циклом, через query_posts, выводятся заголовки постов, по клику на них в popup (прикручен colorbox) должен выводиться контент аяксом.
    Пробовала писать id в цикле в переменную js, но она же по завершении вывода записей содержит id последнего поста, соответственно, и контент выводится всегда последнего поста, на что ни кликай... Вот как быть, а?..
    проблема только в этом, и сам запрос, и обработчик написаны правильно (проверила, закинув запрос в тело цикла - в попапе меняется контент по мере его подгрузки прям на глазах). Замучилась уже dash

    • Получить через jQuery, положить в переменную и отправить аяксом?

       $('.class').click(function() {
      		console.log($(this).attr('id'));
      	});
  • Михаил
    @

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

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

  • Дмитрий

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

    • Ann
      $tag = wp_tag_cloud('format=array' );
      		foreach ($tag as $key => $value) {
      			echo ''.$value.'';
      		}
  • Дмитрий

    Помогите!(( Ау, нужна помощь с выводом переменной из массива выбранных чекбоксов. Когда реализую фильтр - выложу исходники. Думаю, пригодится)

  • campusboy1238 cайт: wp-plus.ru
    @

    На сколько мне известно, пушить запросы в файл плагина считается плохими тоном, якобы это небезопасно, потому разработчики WP рекомендуют всё пропускать как обычно - через admin-ajax.php.

    P.S.:Я понимаю, почему ты сделал именно так, типа сократить серверные ресурсы на обработку запроса.

    И ещё: те прелоадеры по ссылке в статье почти все платные, да и качество их низковато, если честно. Можно бесплатно дёргать с codepen.io

    Ответить2 месяца назад #
    1
    • Kama4090

      разработчики WP рекомендуют всё пропускать как обычно - через admin-ajax.php.

      Да так и есть. Давно писал статью... Сейчас бы по-другому написал...

      Ответить2 месяца назад #
      1
  • Антон
    @

    ТИМУР, помоги друг. help
    Нужен гуру, в помощи не сомневаюсь. Только времени мало, Работа срочная.
    Дело вот как, добавил пользовательскую таксономию,

    function create_post_taxonomies(){
    	$labels = array(
    		'name' => _x( 'Имя', 'taxonomy general name' ),
    		'singular_name' => _x( 'Имена', 'taxonomy singular name' ),
    		'search_items' =>  __( 'Найти Имена' ),
    		'all_items' => __( 'Все Имена' ),
    		'parent_item' => __( 'Род. Имя' ),
    		'parent_item_colon' => __( 'Род Имя:' ),
    		'edit_item' => __( 'Изменить Имя' ),
    		'update_item' => __( 'Обновить Имя' ),
    		'add_new_item' => __( 'Добавить Имя' ),
    		'new_item_name' => __( 'Новая Имя' ),
    		'menu_name' => __( 'Имя' ),
    	);
    
    	register_taxonomy('Имя', array('post'), array(
    		'hierarchical' => true,
    		'labels' => $labels,
    		'show_ui' => true,
    		'query_var' => true,
    		'rewrite' => array( 'slug' => 'Имя' ),
    	));
    

    Вот нужно, чтобы архивы вводились не как ДАТА/РУБРИКА, а как РУБРИКА/ИМЯ
    Тоесть чтобы выводились записи из выбранных рубрик, с выбранными метками ИМЯ
    СПАСИБО ЗАРАНЕЕ.. Буду очень признателен друг!

    Ответить19 дней назад #
    1
    • Kama4090

      не понял вопроса... Так и должно выводиться. Архивы по дате - это немного другая тема...

      Ответить18 дней назад #
      • Антон

        Ну дапустим нужно выводить записи за все время из Х рубрики, с тасономия1 таксономия 2 и таксономия3. Тоесть чтобы можно было проверять правила для всех трех таксономии в выпадающем меню.

        Ответить18 дней назад #
        • Kama4090

          Не понимаю вопроса: "выводить записи за все время из Х рубрики, с тасономия1 таксономия 2 и таксономия3" - абсурд какой-то... unknw

          Ответить17 дней назад #
          • Антон
            @

            Точно laugh Сам все перепутал
            Нужно выводить все записи из выбранных трех таксономии.
            Выбор таксономии осуществляться с помощью выпадающих меню, нужно вывести посты с помощью jQuery, без перезагрузки страницы.

            Ответить17 дней назад #

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

Ваш комментарий