Modo corretto per caricare un singolo post tramite Ajax?
Sto caricando singoli post via Ajax in un div che ho configurato nella mia pagina index. Tutto funziona bene da questo punto di vista. Voglio usare history.js per gestire push/pop dello stato così che se gli utenti inseriscono example.com/my-post
nella barra degli indirizzi, si carichi la pagina index con il post già caricato nel div. Qui sta il problema.
Questa è una versione semplificata della funzione che sto usando (quella reale include anche uno 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' );
Ecco come lo sto chiamando:
$('.post-link').on('click', function(e) {
e.preventDefault();
var post_id = $(this).data('id'), // attributo data-id per .post-link
projectTitle = $(this).data('title'), // attributo data-title per .post-link
projectSlug = $(this).data('slug'), // attributo data-slug per .post-link
ajaxURL = site.ajaxurl; // URL Ajax localizzato da 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;
}
});
});
Ecco il 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(); // resetta la query ?>
Mi chiedo se sto procedendo nel modo sbagliato. Sono confuso e una parte di me pensa che dovrei mettere tutto l'html nel mio template single
e chiamarlo dalla funzione Ajax. Ma poi non so esattamente come funzionerebbe perché se l'utente inserisce example.com/my-post
nel browser, caricherà solo il post singolo senza tutto l'html della pagina index. Spero di star spiegando correttamente. Qualcuno può mostrarmi come si fa?
Ecco la mia opinione: Caricalo direttamente nel tuo single.php, perché usare AJAX? Google non sarà in grado di vedere questo contenuto (utilizzando la maggior parte dei crawler).
In ogni caso - ecco il modo corretto per restituire i dati...
nota che puoi usare get_post o wp_query, dipende da te.
Parte JS:
jQuery(document).ready(function($) {
$.post(ajax_object.ajaxurl, {
action: 'my_load_ajax_content',
post_id: post_id // << dovresti prenderlo da 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">'.__('Non ho trovato nulla', 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');
Spero che questo aiuti.
ripeto, non lo consiglierei, ma... dovrebbe funzionare.
REVISIONE PER CARICAMENTO POST AL CLICK
primo: il pulsante / link - dovrebbe essere qualcosa come
<button class="get_project" data-postid="POSTID QUI!">NOME PROGETTO</button>
secondo: il codice JS che ascolta il click:
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);
});
})
});
Il codice PHP non ha bisogno di modifiche - basta impostare i dati che ti servono.

Scusa, penso di non essere stato chiaro nella mia domanda. Non ho problemi a recuperare il post. Ho aggiornato il mio post per mostrarti la chiamata Ajax completa e anche il mio loop WordPress. Il mio problema è che quando aggiorno (o inserisco direttamente l'url del progetto nel browser, ad esempio example.com/titolo-post
, non si carica perché quell'url non esiste. Quindi come posso fare per farlo caricare con il progetto già caricato come questa pagina?

scusa, ancora non capisco. Se il tuo custom post "single" non viene visualizzato - forse hai dimenticato di creare una pagina single-projects.php? quando clicchi su un link a una pagina personalizzata che ha il file destinato a mostrare quel contenuto - allora... non dovresti avere problemi. Questo non ha nulla a che fare con ajax...!

Ho sia una pagina single che una single-projects ma non ne ho bisogno perché sto costruendo un sito one page. I post saranno solo nella home page quindi voglio che abbiano un url così: example.com/titolo-del-post
invece di example.com/progetti/titolo-del-post
. Posso reindirizzare il secondo al primo usando htaccess
ma non sono sicuro di come posso far caricare il post usando quell'url (example.com/titolo-del-post
).

ascolta amico... è difficile capire cosa vuoi veramente. Quando clicchi il link - non vuoi andare su un'altra pagina? ma il tuo ajax funziona - quindi? cosa vuoi? solo aggiungere un trattino all'url?

No, non voglio che vada su un'altra pagina. Voglio che si comporti esattamente come questa pagina ma senza l'hashtag nell'URL: http://themetrust.com/demos/reveal/#partitura

ma è proprio questo che fa l'ajax... quindi - quale parte ti manca? cosa non funziona?

Prima di tutto... c'è uno script che viene caricato prima di jQuery (non so se è correlato) - vedo la chiamata ajax ma il tuo url continua a caricarsi. Perché non provi il mio standard - funzionante - testato ajax... Puoi anche contattarmi su Skype e così potrò dare un'occhiata migliore all'interno - il mio skype: sagive-seo
