¿Cuál es la forma correcta de cargar una entrada individual mediante Ajax?
Estoy cargando entradas individuales mediante Ajax en un div que he configurado en mi página de inicio. Todo funciona bien en este aspecto. Quiero usar history.js para push/pop del estado para que si los usuarios ingresan example.com/mi-entrada
en la barra de direcciones, cargue la página de inicio con la entrada ya cargada en el div. Ahí es donde está el problema.
Esta es una versión simplificada de la función que estoy usando (la real también incluye un slide):
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' );
Así es como lo estoy llamando:
$('.post-link').on('click', function(e) {
e.preventDefault();
var post_id = $(this).data('id'), // atributo data-id para .post-link
projectTitle = $(this).data('title'), // atributo data-title para .post-link
projectSlug = $(this).data('slug'), // atributo data-slug para .post-link
ajaxURL = site.ajaxurl; // URL Ajax localizada desde 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;
}
});
});
Aquí está el loop
<?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(); // reiniciar la consulta ?>
Me pregunto si estoy abordando esto de la manera incorrecta. Estoy confundido y una parte de mí piensa que debería poner todo el HTML en mi plantilla single
y llamarla desde la función Ajax. Pero entonces tampoco sé exactamente cómo funcionaría eso porque si el usuario ingresa example.com/mi-entrada
en su navegador, solo cargará la entrada individual sin todo el HTML de la página de inicio. Espero estar explicando esto correctamente. ¿Puede alguien mostrarme cómo se hace?
Aquí está mi punto de vista: ¿Por qué no cargarlo directamente en tu single.php en lugar de usar AJAX? Google no podrá ver este contenido (usando la mayoría de rastreadores).
En cualquier caso, aquí está la forma correcta de devolver los datos...
Ten en cuenta que puedes usar get_post o wp_query. Depende de ti.
Parte JS:
jQuery(document).ready(function($) {
$.post(ajax_object.ajaxurl, {
action: 'my_load_ajax_content',
post_id: post_id // << deberías obtener esto desde un input...
}, function(data) {
var $response = $(data);
var postdata = $response.filter('#postdata').html();
$('.TARGETDIV').html(postdata);
});
});
Parte 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">'.__('No se encontró nada', 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');
Espero que esto ayude.
De nuevo, no recomendaría hacer esto, pero... debería funcionar.
REVISIÓN PARA OBTENER POST AL HACER CLIC
Primero: el botón/enlace debería ser algo como:
<button class="get_project" data-postid="POSTID AQUÍ!">NOMBRE DEL PROYECTO</button>
Segundo: el código JS que escucha el clic:
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);
});
})
});
El código PHP no necesita cambios, solo configura los datos que necesites.

Lo siento, creo que no fui claro en mi pregunta. No tengo problemas para recuperar la publicación. Actualicé mi publicación para mostrarte la llamada Ajax completa y también mi bucle de WordPress. Mi problema es que cuando actualizo (o ingreso la URL del proyecto directamente en el navegador, es decir example.com/titulo-del-post
), no carga porque esa URL no existe. Entonces, ¿cómo hago para que cargue con el proyecto ya cargado como esta página?

Lo siento, todavía no entiendo. Si tu publicación personalizada "single" no aparece, ¿quizás olvidaste crear una página single-projects.php? Cuando haces clic en un enlace a una página personalizada que tiene el archivo destinado a mostrar ese contenido, entonces... no deberías tener ningún problema. ¡Esto no tiene nada que ver con ajax!

Tengo tanto una página single como una single-projects, pero no las necesito porque estoy construyendo un sitio de una sola página. Las publicaciones solo estarán en la página de inicio, así que quiero que tengan una URL como esta: example.com/titulo-del-post
en lugar de example.com/projects/titulo-del-post
. Puedo redirigir la última a la primera usando htaccess
, pero no estoy seguro de cómo hacer que la publicación se cargue usando esa URL (example.com/titulo-del-post
).

escucha amigo... es difícil entender lo que realmente quieres. Cuando haces clic en el enlace - ¿no quieres ir a otra página? pero tu ajax funciona - entonces? ¿qué es lo que quieres? ¿solo agregar un guión a la URL?

No, no quiero que vaya a otra página. Quiero que se comporte exactamente como esta página pero sin el hashtag en la URL: http://themetrust.com/demos/reveal/#partitura

pero esto es lo que hace el ajax... entonces - ¿qué parte te falta? ¿qué no funciona?

Primero que nada... hay un script cargándose antes de jQuery (no sé si está relacionado) - veo la llamada ajax pero tu URL aún se carga. ¿Por qué no pruebas mi estándar - funcional - probado ajax... También puedes contactarme por Skype y así podré echar un mejor vistazo - mi skype: sagive-seo
