Filtrar posts por categoría con AJAX al hacer clic

24 jul 2014, 17:19:33
Vistas: 16.5K
Votos: 4

Este es mi primer acercamiento a AJAX, he estado combinando fragmentos de código de varios tutoriales lo que probablemente no ha ayudado.

Tengo una lista de categorías en mi página de inicio (index.php) y una lista de los posts más recientes. Cuando un usuario hace clic en una categoría quiero que esta lista de posts se actualice sin refrescar la página. Actualmente cuando hago clic en un filtro todos los posts se cargan en mi contenedor de respuesta (no se filtra por categoría) y el único contenido que se carga es the_content(), aunque mi plantilla (listing-post.php) solicita la imagen destacada, la categoría etc.

Estoy usando Bones como mi tema inicial, por eso wp_localize_script está en este archivo (está funcionando). Solo he incluido código que sé que tiene problemas (sé que el resto del sitio y JS funciona bien).

bones.php

// Agregar ruta AJAX para usar en load-posts.js
$getPath = array('ajaxURL' => admin_url('admin-ajax.php'));
wp_localize_script('main-js', 'pathToFile', $getPath);

functions.php

// Filtro AJAX por Categoría
add_action( 'wp_ajax_load_cat_posts', 'load_cat_posts' );
add_action( 'wp_ajax_nopriv_load_cat_posts', 'load_cat_posts' );

function load_cat_posts () {
    $cat_id = $_REQUEST['cat']; // Corregido: obtener directamente el ID de categoría
    $args = array (
      'cat' => $cat_id,
      'posts_per_page' => 10,
      'order' => 'DESC'
    );

    $posts = get_posts($args);

    ob_start ();

    foreach ( $posts as $post ) {
      setup_postdata( $post ); ?>

      <?php get_template_part( 'partials/listing', 'post'); ?>

   <?php } wp_reset_postdata();

   $response = ob_get_contents();
   ob_end_clean();

   echo $response;
   die(1);
}

index.php

<?php $categories = get_categories(); ?>

<ul class="category-filters">
    <?php foreach ( $categories as $cat ) { ?>
        <li id="cat-<?php echo $cat->term_id; ?>">
            <a class="<?php echo $cat->slug; ?> ajax" data-cat="<?php echo $cat->term_id; ?>" href="javascript:void(0)"><?php echo $cat->name; ?></a>
        </li>
    <?php } ?>
</ul>

listing-post.php

<li class="standard-post">
    <article id="<?php echo sanitize_title_with_dashes( get_the_title() ); ?>" <?php post_class(); ?> role="article">

        <?php if (has_post_thumbnail()) { ?>
            <div class="article-image">
                <?php the_post_thumbnail('large'); ?> <!-- Corregido: añadidas comillas -->
            </div>
        <?php } ?>

        <div class="article-left">
            <?php foreach((get_the_category()) as $category) { ?>
                <span class="article-category"><?php echo $category->cat_name . ' ';?></span>
            <?php } ?>
            </div>

            <div class="article-right">
            <header class="article-header">
                <h1 class="article-title"><?php the_title(); ?></h1>
                <p class="article-time">
                    <?php printf( __( '<time class="updated" datetime="%1$s" pubdate>%2$s</time>', 'bonestheme' ), get_the_time(), get_the_time(get_option('date_format'))); ?>
                </p>
            </header>

            <section class="entry-content">
                <?php the_content(); ?>
            </section>
        </div>

    </article>
</li>

load-posts.js

function cat_ajax_get(currentCat) {
    $('a.ajax').removeClass('current');
    $('a.ajax').addClass('current');
    $('#loading-animation').show();
    $.ajax({
        type: 'POST',
        url: pathToFile.ajaxURL, // Corregido: usar la variable localizada
        data: {action: 'load_cat_posts', cat: currentCat },
        success: function(response) {
            $('.article-listing').html(response);
            $('#loading-animation').hide();
            return false;
        }
    });
};

ajaxFilters: function() {
    $('.category-filters a').on('click', $.proxy(function(clickEvent) {
        $clickTarget = $(clickEvent.currentTarget);
        var currentCat = $clickTarget.attr('data-cat');
        cat_ajax_get(currentCat);
    },this));
}
4
Comentarios

Recuerdo haber tenido un problema similar en el pasado. Es una posibilidad remota, pero intenta agregar esto a functions.php add_action('template_redirect', 'register_scripts');

gdaniel gdaniel
24 jul 2014 17:43:24

Me temo que eso no ha resuelto el problema. Gracias por intentarlo de todos modos.

GuerillaRadio GuerillaRadio
24 jul 2014 17:53:13

Antes de responder con más profundidad, ¿podría ser el error tipográfico en add_action( 'wp_ajax_oad_cat_posts', 'load_cat_posts' ); (es decir, wp_ajax_oad debería ser wp_ajax_load)?

John P Bloch John P Bloch
24 jul 2014 17:55:50

¡Sí lo es, muchas gracias John! Estoy editando la pregunta ahora ya que tengo otro problema.

GuerillaRadio GuerillaRadio
24 jul 2014 18:24:36
Todas las respuestas a la pregunta 1
0

Esta línea en functions.php es tu problema:

$cat_id = get_post_meta($_REQUEST['cat']);

Creo que estás malinterpretando el propósito de la función get_post_meta(). Está diseñada para obtener metadatos de una entrada de WordPress, no datos de una solicitud POST al sitio. El primer parámetro de la función get_post_meta() es el $post_id, pero como estás pasando el ID de categoría en su lugar, obtendrás false o un array de todos los valores meta si existe una entrada con el mismo ID que ese ID de categoría. En cualquiera de esos casos, el valor de la variable de consulta cat no será un ID de categoría válido, por lo que esa parte de la consulta será ignorada y se devolverán todas las entradas. Si cambias esa línea por esto, solucionarás el problema y tu código probablemente funcionará:

$cat_id = absint( $_REQUEST['cat'] );

La función absint() simplemente convierte el valor proporcionado por el usuario en un entero positivo.

23 ene 2016 20:30:26