¿Cuál es la forma correcta de cargar una entrada individual mediante Ajax?

24 ene 2015, 17:31:20
Vistas: 20.9K
Votos: 2

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?

7
Comentarios

pero, ¿por qué necesitas esto? quiero decir, ¿cuál podría ser la razón para cargar tu contenido usando ajax en lugar de simplemente mostrar los datos dentro de single.php? ¿No sabes que la mayoría de los motores de búsqueda no verán el contenido en absoluto?

Sagive Sagive
24 ene 2015 19:02:54

@SagiveSEO Bueno, este sitio es similar a lo que tengo en mente. Mira cómo esa página carga con el proyecto ya en el div? Noté que en los resultados de búsqueda, lleva a la plantilla single, lo cual está bien para mí.

j85 j85
25 ene 2015 02:31:38

No entiendo... (Lo siento). ¿a qué te refieres con "proyecto ya en el div"? ¿Te refieres a este efecto? https://mixitup.kunkalabs.com/ ??

Sagive Sagive
25 ene 2015 04:03:15

@SagiveSEO Oh, no ese efecto no. Perdón si no fui claro. Cuando haces clic en este enlace, se abre con el proyecto "Partitura" cargado en el div. La página de inicio simplemente se abre sin ningún proyecto cargado.

j85 j85
25 ene 2015 04:32:04

@SagiveSEO Es el área resaltada en rojo aquí: http://i.imgur.com/md0a1Ul.jpg

j85 j85
25 ene 2015 05:17:03

sí, lo entendí después de revisar el tema más en profundidad... esto no importa el código que te di. solo necesitas recuperar lo deseado para devolver. es decir, la imagen, video / etc... el extracto, título y demás.

Sagive Sagive
25 ene 2015 08:37:56

mi código js funciona al cargar la página. Necesitas envolverlo con jQuery y no con document.ready, luego escuchar un clic desde un botón que proporcione el ID de la publicación y luego devolver los datos como respuesta. Ver revisión 2

Sagive Sagive
25 ene 2015 08:39:31
Mostrar los 2 comentarios restantes
Todas las respuestas a la pregunta 1
7

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.

24 ene 2015 19:11:27
Comentarios

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?

j85 j85
25 ene 2015 11:35:10

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!

Sagive Sagive
25 ene 2015 12:42:59

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).

Desi Desi
25 ene 2015 16:54:30

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?

Sagive Sagive
25 ene 2015 17:25:51

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

Desi Desi
25 ene 2015 17:33:37

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

Sagive Sagive
25 ene 2015 18:21:07

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

Sagive Sagive
26 ene 2015 03:38:57
Mostrar los 2 comentarios restantes