Правильный способ загрузки отдельного поста через Ajax?

24 янв. 2015 г., 17:31:20
Просмотры: 20.9K
Голосов: 2

Я загружаю отдельные записи через Ajax в div, который настроен на моей главной странице. С этим всё работает нормально. Я хочу использовать history.js для push/pop состояния, чтобы когда пользователи вводят example.com/my-post в адресную строку, загружалась главная страница с уже загруженной записью в div. Именно здесь возникает проблема.

Это упрощенная версия функции, которую я использую (в реальности также включает слайд):

function my_load_ajax_content () {

    $args = array(
        'p' => $_POST['post_id'],
        'post_type' => 'projects'
        );

    $post_query = new WP_Query( $args );
    while( $post_query->have_posts() ) : $post_query->the_post(); ?>

    <div class="post-container">
        <div id="project-content">
            <?php the_title( '<h1 class="entry-title">', '</h1>' ); ?>
            <?php the_content(); ?>
        </div>
    </div><!-- .post-container -->

    <?php
    endwhile;
    wp_die();
}

add_action ( 'wp_ajax_nopriv_load-content', 'my_load_ajax_content' );
add_action ( 'wp_ajax_load-content', 'my_load_ajax_content' );

Вот как я её вызываю:

$('.post-link').on('click', function(e) {
    e.preventDefault();

    var post_id = $(this).data('id'), // атрибут data-id для .post-link
        projectTitle = $(this).data('title'), // атрибут data-title для .post-link
        projectSlug = $(this).data('slug'), // атрибут data-slug для .post-link
        ajaxURL = site.ajaxurl; // Ajax URL локализован из functions.php

    $.ajax({
        type: 'POST',
        url: ajaxURL,
        context: this,
        data: {'action': 'load-content', post_id: post_id },
        success: function(response) {
            $('#project-container').html(response);
            return false;
        }
    });
});

Вот цикл

<?php $home_query = new WP_Query('post_type=projects');

while($home_query->have_posts()) : $home_query->the_post(); ?>

    <article class="project">
        <?php the_post_thumbnail( 'home-thumb' ); ?>
        <div class="overlay">
            <a class="post-link expand" href="<?php the_permalink(); ?>" data-id="<?php the_ID(); ?>" data-title="<?php the_title(); ?>" data-slug="<?php global $post; echo $post->post_name; ?>">+</a>
        </div>
    </article>

<?php endwhile; ?>
<?php wp_reset_postdata(); // сброс запроса ?>

Я думаю, возможно, я делаю это неправильно. Я в замешательстве, и часть меня думает, что нужно поместить весь HTML в мой шаблон single и вызывать его из Ajax-функции. Но тогда я точно не знаю, как это будет работать, потому что если пользователь вводит example.com/my-post в браузере, загрузится только отдельная запись без всего HTML на главной странице. Надеюсь, я правильно объясняю. Может кто-то показать, как это делается правильно?

7
Комментарии

но зачем вам это? то есть, какая может быть причина загружать ваш контент через ajax вместо того, чтобы просто показывать данные внутри single.php? Вы же знаете, что большинство поисковых систем вообще не увидят контент?!

Sagive Sagive
24 янв. 2015 г. 19:02:54

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

j85 j85
25 янв. 2015 г. 02:31:38

Я не понимаю... (Извините). что вы имеете в виду под "проектом уже в div"? Вы имеете в виду этот эффект? https://mixitup.kunkalabs.com/ ??

Sagive Sagive
25 янв. 2015 г. 04:03:15

@SagiveSEO О, нет, не этот эффект. Извините, если я был неясен. Когда вы нажимаете эту ссылку, она открывается с загруженным проектом "Partitura" в div. Домашняя страница просто открывается без загруженных проектов.

j85 j85
25 янв. 2015 г. 04:32:04

@SagiveSEO Это область, выделенная красным здесь: http://i.imgur.com/md0a1Ul.jpg

j85 j85
25 янв. 2015 г. 05:17:03

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

Sagive Sagive
25 янв. 2015 г. 08:37:56

Мой JS-код работает при загрузке страницы. Вам нужно обернуть его с помощью jQuery, а не document.ready, затем отслеживать клик по кнопке, которая передает ID поста, и возвращать данные в качестве ответа. Смотрите версию 2.

Sagive Sagive
25 янв. 2015 г. 08:39:31
Показать остальные 2 комментариев
Все ответы на вопрос 1
7

Вот мой взгляд: Загрузите это внутри вашего single.php, зачем вообще использовать ajax? Google не сможет увидеть это (используя большинство краулеров).

В любом случае - вот правильный способ вернуть данные...
обратите внимание, что вы можете использовать get_post или wp_query. на ваше усмотрение.

JS часть:

jQuery(document).ready(function($) {
    $.post(ajax_object.ajaxurl, {
        action: 'my_load_ajax_content ',            
        post_id: post_id  // << должен получить это из input...

    }, function(data) {

        var $response   =   $(data);
        var postdata    =   $response.filter('#postdata').html();

        $('.TARGETDIV').html(postdata);
    });
});

PHP часть:

function my_load_ajax_content () {

    $pid        = intval($_POST['post_id']);
    $the_query  = new WP_Query(array('p' => $pid));

    if ($the_query->have_posts()) {
        while ( $the_query->have_posts() ) {
            $the_query->the_post();

            $data = '
            <div class="post-container">
                <div id="project-content">
                    <h1 class="entry-title">'.get_the_title().'</h1>
                    <div class="entry-content">'.get_the_content().'</div>
                </div>
            </div>  
            ';

        }
    } 
    else {
        echo '<div id="postdata">'.__('Ничего не найдено', THEME_NAME).'</div>';
    }
    wp_reset_postdata();


    echo '<div id="postdata">'.$data.'</div>';
}

add_action ( 'wp_ajax_nopriv_load-content', 'my_load_ajax_content' );
add_action ( 'wp_ajax_load-content', 'my_load_ajax_content' );

Надеюсь, это поможет.
повторюсь, я бы не рекомендовал делать так, но... это должно работать.

ИЗМЕНЕНИЕ ДЛЯ ПОЛУЧЕНИЯ ПОСТА ПО КЛИКУ

первое: кнопка / ссылка - должна выглядеть примерно так

<button class="get_project" data-postid="ID ПОСТА ЗДЕСЬ!">НАЗВАНИЕ ПРОЕКТА</button>

второе: js код, реагирующий на клик:

jQuery(function($){

    $('.get_project').click(function() {

        var postid = $(this).attr('data-postid');

        $.post(ajax_object.ajaxurl, {
            action: 'my_load_ajax_content ',            
            postid: postid
        }, function(data) {
            var $response   =   $(data);
            var postdata    =   $response.filter('#postdata').html();
            $('.TARGETDIV').html(postdata);
        });

    })

});

PHP код не требует изменений - просто установите нужные вам данные.

24 янв. 2015 г. 19:11:27
Комментарии

Извините, кажется, я неясно сформулировал вопрос. У меня нет проблем с получением записи. Я обновил свой пост, чтобы показать вам полный Ajax-запрос и также мой WordPress-цикл. Моя проблема в том, что при обновлении (или при прямом вводе URL проекта в браузере, например example.com/post-title), он не загружается, потому что этот URL не существует. Так как мне сделать, чтобы он загружался с уже загруженным проектом, как на этой странице?

j85 j85
25 янв. 2015 г. 11:35:10

Извините, я все еще не понимаю. Если ваша "одиночная" запись (custom post) не отображается - возможно, вы забыли создать страницу single-projects.php? Когда вы кликаете на ссылку к кастомной странице, у которой есть файл, предназначенный для отображения этого контента - то... у вас не должно быть проблем. Это вообще не связано с ajax...!

Sagive Sagive
25 янв. 2015 г. 12:42:59

У меня есть и single page, и single-projects page, но они мне не нужны, потому что я строю одностраничный сайт. Записи будут только на главной странице, поэтому я хочу, чтобы у них был URL такого вида: example.com/title-of-post вместо example.com/projects/title-of-post. Я могу перенаправить последний на первый с помощью htaccess, но я не уверен, как я могу сделать, чтобы запись загружалась с этим URL (example.com/title-of-post).

Desi Desi
25 янв. 2015 г. 16:54:30

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

Sagive Sagive
25 янв. 2015 г. 17:25:51

Нет, я не хочу перехода на другую страницу. Я хочу, чтобы это работало точно так же, как на этой странице, но без хэштега в URL: http://themetrust.com/demos/reveal/#partitura

Desi Desi
25 янв. 2015 г. 17:33:37

но это именно то, что делает ajax... так что - какой части тебе не хватает? что не работает?

Sagive Sagive
25 янв. 2015 г. 18:21:07

Во-первых... есть скрипт, загружающийся перед jQuery (не знаю, связано ли это) - я вижу AJAX-запрос, но ваш URL всё равно загружается. Почему бы не попробовать мой стандартный - рабочий - проверенный AJAX... Также вы можете связаться со мной в Skype, тогда я смогу лучше разобраться в проблеме - мой Skype: sagive-seo

Sagive Sagive
26 янв. 2015 г. 03:38:57
Показать остальные 2 комментариев