Cargar más publicaciones Botón Ajax en WordPress

Resuelto Addzy asked hace 54 años • 2 respuestas

Revisé las preguntas anteriores y probé muchos de los diferentes métodos que parecen existir para hacer esto. Lo más cerca que estoy de trabajar es este aquí: Cómo implementar la paginación en un WP_Query Ajax personalizado

Lo he probado todo y simplemente no funciona. Absolutamente nada cambia en la página. Si inspecciona el botón Cargar más y hace clic en él, jQuery realiza la acción Cargar más botón a medida que cambia de <a id="more_posts">Load More</a>a <a id="more_posts" disables="disabled">Load More</a>lo cual, de todos modos, ni siquiera eso me parece correcto. No es agregar las publicaciones, creo que me falta algo simple pero por mi vida no puedo resolverlo.

El código en mi archivo de plantilla es:

<div id="ajax-posts" class="row">
    <?php 
    $postsPerPage = 3;
    $args = [
        'post_type' => 'post',
        'posts_per_page' => $postsPerPage,
        'cat' => 1
    ];

    $loop = new WP_Query($args);

    while ($loop->have_posts()) : $loop->the_post(); ?>
        <div class="small-12 large-4 columns">
            <h1><?php the_title(); ?></h1>
            <p><?php the_content(); ?></p>
        </div>
        <?php
    endwhile; 

    echo '<a id="more_posts">Load More</a>';
    
    wp_reset_postdata(); 
    ?>
</div>

El código en mi archivo de funciones es:

function more_post_ajax(){
    $offset = $_POST["offset"];
    $ppp = $_POST["ppp"];

    header("Content-Type: text/html");
    $args = [
        'suppress_filters' => true,
        'post_type' => 'post',
        'posts_per_page' => $ppp,
        'cat' => 1,
        'offset' => $offset,
    ];

    $loop = new WP_Query($args);

    while ($loop->have_posts()) { $loop->the_post(); 
        the_content();
    }
    exit; 
}

add_action('wp_ajax_nopriv_more_post_ajax', 'more_post_ajax'); 
add_action('wp_ajax_more_post_ajax', 'more_post_ajax');

Y mi jQuery en el pie de página es:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script type="text/javascript">
    jQuery(document).ready( function($) {
        var ajaxUrl = "<?php echo admin_url('admin-ajax.php')?>";
        
        // What page we are on.
        var page = 5; 
        // Post per page
        var ppp = 3; 

        $("#more_posts").on("click", function() {
            // When btn is pressed.
            $("#more_posts").attr("disabled",true);

            // Disable the button, temp.
            $.post(ajaxUrl, {
                action: "more_post_ajax",
                offset: (page * ppp) + 1,
                ppp: ppp
            })
            .success(function(posts) {
                page++;
                $("#ajax-posts").append(posts);
                // CHANGE THIS!
                $("#more_posts").attr("disabled", false);
            });
        });
    });
</script>

¿Alguien puede ver algo que me falta o puede ayudar?

Addzy avatar Jan 01 '70 08:01 Addzy
Aceptado

ACTUALIZACIÓN 24.04.2016.

Creé un tutorial en mi página https://madebydenis.com/ajax-load-posts-on-wordpress/ sobre cómo implementar esto en el tema Twenty Sixteen, así que no dudes en consultarlo :)

EDITAR

Probé esto en Twenty Fifteen y está funcionando, por lo que debería funcionar para usted.

En index.php (suponiendo que quieras mostrar las publicaciones en la página principal, pero esto debería funcionar incluso si lo pones en una plantilla de página) puse:

    <div id="ajax-posts" class="row">
        <?php
            $postsPerPage = 3;
            $args = array(
                    'post_type' => 'post',
                    'posts_per_page' => $postsPerPage,
                    'cat' => 8
            );

            $loop = new WP_Query($args);

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

         <div class="small-12 large-4 columns">
                <h1><?php the_title(); ?></h1>
                <p><?php the_content(); ?></p>
         </div>

         <?php
                endwhile;
        wp_reset_postdata();
         ?>
    </div>
    <div id="more_posts">Load More</div>

Esto generará 3 publicaciones de la categoría 8 (tenía publicaciones en esa categoría, así que la usé, puedes usar lo que quieras). Incluso puedes consultar la categoría en la que estás

$cat_id = get_query_var('cat');

Esto le dará la identificación de categoría para usar en su consulta. Podrías poner esto en tu cargador (cargar más div) y extraerlo con jQuery como

<div id="more_posts" data-category="<?php echo $cat_id; ?>">Load More</div>

Y tirar de la categoría con

var cat = $('#more_posts').data('category');

Pero por ahora, puedes omitir esto.

Siguiente en funciones.php agregué

wp_localize_script( 'twentyfifteen-script', 'ajax_posts', array(
    'ajaxurl' => admin_url( 'admin-ajax.php' ),
    'noposts' => __('No older posts found', 'twentyfifteen'),
));

Justo después del existente wp_localize_script. Esto cargará el propio admin-ajax.php de WordPress para que podamos usarlo cuando lo llamemos en nuestra llamada ajax.

Al final del archivo funciones.php agregué la función que cargará tus publicaciones:

function more_post_ajax(){

    $ppp = (isset($_POST["ppp"])) ? $_POST["ppp"] : 3;
    $page = (isset($_POST['pageNumber'])) ? $_POST['pageNumber'] : 0;

    header("Content-Type: text/html");

    $args = array(
        'suppress_filters' => true,
        'post_type' => 'post',
        'posts_per_page' => $ppp,
        'cat' => 8,
        'paged'    => $page,
    );

    $loop = new WP_Query($args);

    $out = '';

    if ($loop -> have_posts()) :  while ($loop -> have_posts()) : $loop -> the_post();
        $out .= '<div class="small-12 large-4 columns">
                <h1>'.get_the_title().'</h1>
                <p>'.get_the_content().'</p>
         </div>';

    endwhile;
    endif;
    wp_reset_postdata();
    die($out);
}

add_action('wp_ajax_nopriv_more_post_ajax', 'more_post_ajax');
add_action('wp_ajax_more_post_ajax', 'more_post_ajax');

Aquí agregué una clave paginada en la matriz, para que el bucle pueda realizar un seguimiento de en qué página se encuentra cuando carga sus publicaciones.

Si ha agregado su categoría en el cargador, agregaría:

$cat = (isset($_POST['cat'])) ? $_POST['cat'] : '';

Y en lugar de 8, pondrías $cat. Esto estará en la $_POSTmatriz y podrás usarlo en ajax.

La última parte es el propio ajax. En funciones.js puse dentro del $(document).ready();entorno.

var ppp = 3; // Post per page
var cat = 8;
var pageNumber = 1;


function load_posts(){
    pageNumber++;
    var str = '&cat=' + cat + '&pageNumber=' + pageNumber + '&ppp=' + ppp + '&action=more_post_ajax';
    $.ajax({
        type: "POST",
        dataType: "html",
        url: ajax_posts.ajaxurl,
        data: str,
        success: function(data){
            var $data = $(data);
            if($data.length){
                $("#ajax-posts").append($data);
                $("#more_posts").attr("disabled",false);
            } else{
                $("#more_posts").attr("disabled",true);
            }
        },
        error : function(jqXHR, textStatus, errorThrown) {
            $loader.html(jqXHR + " :: " + textStatus + " :: " + errorThrown);
        }

    });
    return false;
}

$("#more_posts").on("click",function(){ // When btn is pressed.
    $("#more_posts").attr("disabled",true); // Disable the button, temp.
    load_posts();
});

Lo guardé, lo probé y funciona :)

Imágenes como prueba (no te preocupes por el estilo de mala calidad, se hizo rápidamente). Además el contenido de la publicación es un galimatías xD

ingrese la descripción de la imagen aquí

ingrese la descripción de la imagen aquí

ingrese la descripción de la imagen aquí

ACTUALIZAR

Para 'carga infinita' en lugar de hacer clic en el evento en el botón (simplemente hazlo invisible, con visibility: hidden;) puedes probar con

$(window).on('scroll', function () {
    if ($(window).scrollTop() + $(window).height()  >= $(document).height() - 100) {
        load_posts();
    }
});

Esto debería ejecutar la load_posts()función cuando estés a 100 píxeles de la parte inferior de la página. En el caso del tutorial en mi sitio, puedes agregar una verificación para ver si las publicaciones se están cargando (para evitar que el ajax se active dos veces), y puedes activarlo cuando el desplazamiento llegue a la parte superior del pie de página.

$(window).on('scroll', function(){
    if($('body').scrollTop()+$(window).height() > $('footer').offset().top){
        if(!($loader.hasClass('post_loading_loader') || $loader.hasClass('post_no_more_posts'))){
                load_posts();
        }
    }
});

Ahora bien, el único inconveniente en estos casos es que nunca podrás desplazarte hasta el valor de $(document).height() - 100o $('footer').offset().toppor algún motivo. Si eso sucediera, simplemente aumente el número al que va el pergamino.

Puedes comprobarlo fácilmente poniendo console.logmensajes en tu código y ver en el inspector lo que arrojan.

$(window).on('scroll', function () {
    console.log($(window).scrollTop() + $(window).height());
    console.log($(document).height() - 100);
    if ($(window).scrollTop() + $(window).height()  >= $(document).height() - 100) {
        load_posts();
    }
});

Y simplemente ajústelo en consecuencia;)

Espero que esto ayude :) Si tiene alguna pregunta, simplemente pregunte.

dingo_d avatar Jul 23 '2015 13:07 dingo_d