Правильный способ загрузки отдельного поста через Ajax?
Я загружаю отдельные записи через 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 на главной странице. Надеюсь, я правильно объясняю. Может кто-то показать, как это делается правильно?
Вот мой взгляд: Загрузите это внутри вашего 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 код не требует изменений - просто установите нужные вам данные.

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

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

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

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

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

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

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