Обновление цикла с помощью формы

2 янв. 2012 г., 01:07:25
Просмотры: 1.05K
Голосов: 2

Я разрабатываю фотогалерею на WordPress в качестве системы управления контентом. Для оформления интерфейса и манипуляций (например, сортировки) я активно использую jQuery-плагины. Проблема в том, что постов слишком много! 737 штук, каждый с миниатюрой, отображаемой на странице. Это неизбежно тормозит любой браузер, особенно учитывая, что плагин сортировки "клонирует" изображения при их упорядочивании. Посты создаются с помощью скрипта Wp_query:

<?php
 $paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
 $post_per_page = 15; // (-1 показывает все посты) УСТАНАВЛИВАЕТ КОЛИЧЕСТВО ОТОБРАЖАЕМЫХ ИЗОБРАЖЕНИЙ!
 $do_not_show_stickies = 1; // 0 для показа sticky-записей
 $args=array(
'post_type' => array ('post'),
'orderby' => 'rand',
'order' => 'ASC',
'paged' => $paged,
'posts_per_page' => $post_per_page
);
$pf_categorynotin = get_post_meta($wp_query->post->ID, true);
if($pf_categorynotin){
    $args['tax_query'] = array(
        array(
            'taxonomy' => 'category',
            'field' => 'slug',
            'terms' => $pf_categorynotin,
            'operator' => 'NOT IN'
        )
    ); //category__in
}
$temp = $wp_query;  // сохраняем оригинальный запрос во временной переменной для последующего использования
$wp_query = null;
$wp_query = new WP_Query($args);

if( have_posts() ) :
    echo '<ul id="applications" class="applications pf_item3">';
    $r = 0;
    while ($wp_query->have_posts()) : $wp_query->the_post();
        $post_cat = array();
        $post_cat = wp_get_object_terms($post->ID, "category");
        $post_cats = array();
        $post_rel = "";
        for($h=0;$h<count($post_cat);$h++){
                $post_rel .= $post_cat[$h]->slug.' ';
                $post_cats[] = $post_cat[$h]->name;
            }
    $r++;
    echo'<li data-id="id-'. $r .'" data-type="'.$post_rel.'" >';
    if (get_post_meta($post->ID, 'port_thumb_image_url', true)) { ?>
<a  class="tozoom" href="<?php echo get_post_meta($post->ID, 'port_large_image_url', true); ?>" rel="example4" title="<?php echo $post->post_title; ?>">
<img src="<?php echo get_post_meta($post->ID, 'port_thumb_image_url', true); ?>" class="portfolio_box" alt="<?php the_title(); ?>" width="199px" height="134px" /></a>
    <?php } ?>
        </li>
    <?php endwhile ?>
         </ul>

Элементы сортируются по их html5-тегам с помощью меню в сайдбаре.

Вы можете посмотреть это в действии здесь: http://marbledesigns.net/marbledesigns/products

Сейчас скрипт случайным образом загружает 15 постов и отображает их. Я хочу иметь возможность перезагружать посты на основе выбора из меню (по категориям) и обновлять список изображений без перезагрузки страницы. Мне нужно менять не только то, какие посты из каких категорий отображаются, но и количество постов на странице.

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

Ищу эффективное решение! Пожалуйста, помогите!

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

Да, AJAX — это правильный путь.

По сути, вы можете написать свою собственную функцию обратного вызова для AJAX-хука WordPress в файле functions.php вашей темы. Затем ваша функция может возвращать данные в любом удобном вам формате. Я обычно возвращаю JSON. Я проведу вас по процессу настройки.

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

add_action('wp_ajax_nopriv_get_images', 'get_images_callback');

get_images — это действие $_POST, которое вы будете использовать для вашей формы/jQuery AJAX-метода.

Далее настраиваем AJAX, который будет обрабатывать запрос и возвращать запрошенные изображения. В WordPress уже есть скрипт для обработки AJAX — admin-ajax.php. В примере ниже мы отправляем POST-запрос к нему.

jQuery(document).ready(function($) {
    var params = {
        action: 'get_images',
        category: 5,
        limit: 20
    };
    jQuery.post(<?php echo admin_url('admin-ajax.php'); ?>, params, function(response) {
        // здесь ваша магия!
    });
});

(Примечание: Есть более правильный способ указания URL админки, чем использование PHP echo, но я привожу простой и быстрый пример, чтобы вы могли настроить это самостоятельно.)

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

function get_images_callback(){
    $category = $_POST('category'); // получаем запрошенную категорию
    $limit = $_POST('limit'); // получаем запрошенный лимит

    // ваш WP Query получает нужные записи/изображения и сохраняет данные в $images
    // можно также вернуть количество изображений в $num
    // или, возможно, какие-то дополнительные данные в $data

    header('Content-type: application/json');
    print json_encode(array('images' => $images, 'number' => $num, 'data' => $data));
    die();
}

Вот и всё. В вашей jQuery-функции обязательно правильно обрабатывайте возвращаемые данные. Чтобы получить данные, просто обращайтесь к ним так: response.images, response.num или response.data. Если images возвращается как массив, вам нужно будет перебрать его, чтобы получить данные, как и с любым другим массивом. Например:

jQuery.each(response.images,function(key,val){
    // работаем со значениями
}); 

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

2 янв. 2012 г. 15:13:20
Комментарии

Еще одна вещь, которая замедляет страницу гораздо больше, чем 15 изображений — это 22 JS и 5 CSS файлов... Когда запустите сайт, подумайте об использовании W3TC для объединения и минификации.

Velvet Blues Velvet Blues
2 янв. 2012 г. 15:42:58

Я знаю ;), сейчас он отключен, потому что кэширование делает отладку JS кошмаром! Огромное спасибо!!!

frankV frankV
2 янв. 2012 г. 17:55:32