Pagination avec requête SQL personnalisée

9

J'ai ma propre chaîne SQL pour sélectionner les publications de type de publication personnalisé avec une clause WHERE spécifique. J'ai utilisé le décalage et la limite pour renvoyer les messages appropriés en fonction de la page affichée. Ça marche bien.

Maintenant, je voudrais faire fonctionner previous_posts_link()et les next_posts_link()fonctions. Ils sont tous deux appelés à partir de get_posts_nav_linkquelles utilisations global $wp_query.

Existe-t-il un moyen de réaffecter global $wp_queryma chaîne SQL ou mes $wpdb->get_resultsrésultats ou autre chose? Ainsi, les fonctions natives previous_posts_link()et next_posts_link()WP fonctionneraient.

Sinon, comment puis-je reproduire les fonctions de lien précédent et suivant?

J'apprécierais vraiment toute aide et conseil! Je suis totalement coincé avec ça.
Merci :)

REMARQUE: je viens de remarquer que cela previous_posts_link()fonctionne correctement sur toutes les pages, mais no idea whydans ce cas, pourquoi next_posts_linkne fonctionne pas: S

Voici le code:

$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$post_per_page = intval(get_query_var('posts_per_page'));
$offset = ($paged - 1)*$post_per_page;

$sql = "
SELECT SQL_CALC_FOUND_ROWS  wp_posts.*, wp_postmeta.* 
FROM wp_posts 
INNER JOIN wp_postmeta ON (wp_posts.ID = wp_postmeta.post_id)
INNER JOIN wp_postmeta AS mt1 ON (wp_posts.ID = mt1.post_id) 
WHERE 1=1  
    AND wp_posts.post_type = 'movie' 
    AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private') 
    AND ((wp_postmeta.meta_key = '_expiry_date' AND CAST(wp_postmeta.meta_value AS DATE) >= '".$current_date."') 
        OR (mt1.meta_key = '_expiry_date' AND CAST(mt1.meta_value AS CHAR) = ''))
GROUP BY wp_posts.ID 
ORDER BY wp_posts.post_date DESC
LIMIT ".$offset.", ".$post_per_page;

$movies_all_current = $wpdb->get_results( $sql, OBJECT);

if($movies_all_current) {
global $post;

//loop
foreach( $movies_all_current as $key=>$post ) {
    setup_postdata($post);
    //display each post
    //...
} //end foreach ?>

    //navigation
<div class="navigation">
    <div class="previous panel"><?php previous_posts_link('&laquo; newer') ?></div>
    <div class="next panel"><?php next_posts_link('older &raquo;') ?></div>
</div>
}
dashaluna
la source

Réponses:

16

D'accord, je suis arrivé à la fin. Je ne pouvais pas utiliser la WP_Queryclasse car j'avais vraiment besoin d'avoir mon propre SQL assez grand et complexe. Voici ce que j'ai fini par avoir:

Dans functions.phpJ'ai mon SQL et ma logique personnalisés pour compter les valeurs nécessaires pour la logique de pagination WP:

function vacancies_current( ){
    global $wpdb, $paged, $max_num_pages, $current_date;

    $paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
    $post_per_page = intval(get_query_var('posts_per_page'));
    $offset = ($paged - 1)*$post_per_page;

    /* Custom sql here. I left out the important bits and deleted the body 
     as it will be specific when you have your own. */
    $sql = "
        SELECT SQL_CALC_FOUND_ROWS  {$wpdb->posts}.*
        FROM {$wpdb->posts}
        ....
        GROUP BY {$wpdb->posts}.ID 
        ORDER BY {$wpdb->posts}.post_date DESC
        LIMIT ".$offset.", ".$post_per_page."; ";   

    $sql_result = $wpdb->get_results( $sql, OBJECT);

    /* Determine the total of results found to calculate the max_num_pages
     for next_posts_link navigation */
    $sql_posts_total = $wpdb->get_var( "SELECT FOUND_ROWS();" );
    $max_num_pages = ceil($sql_posts_total / $post_per_page);

    return $sql_result;
}

Ensuite, dans mon fichier de modèle, j'aurais:

<?php 
    $vacancies_current = vacancies_current();
    /*followed by a standart loop to display your results */ 
 ?>
<div class="navigation">
    <div class="previous panel"><?php previous_posts_link('&laquo; previous vacancies',$max_num_pages) ?></div>
    <div class="next panel"><?php next_posts_link('more vacancies &raquo;',$max_num_pages) ?></div>
</div>

L'astuce était de fournir previous_posts_link()et de next_posts_linkla $max_num_pagesvaleur et évidemment de la calculer correctement.

Cela fonctionne très bien. J'espère que cela aidera quelqu'un :)

Dasha

dashaluna
la source
+1 beau travail. Je suis tombé sur cela (et j'ai beaucoup emprunté, merci) tout en recherchant ma réponse à stackoverflow.com/questions/16057059/… . Je me demandais si vous connaissez un moyen d'utiliser une instruction SQL personnalisé comme celui - ci, mais dans un pre_get_posts () action par codex.wordpress.org/... ? Je trouve que cette solution est sensible au problème 404 sur la dernière page, selon wordpress.org/support/topic/… . Comment avez-vous surmonté cela?
Sepster
1

Jetez un œil aux requêtes personnalisées - qui vous permettent de modifier l'appel wp_query de nombreuses façons intéressantes et utiles, et de repousser les résultats dans votre objet de requête globale.

anu
la source
1

Développant la réponse d'Anu. Au lieu de vous fier à votre requête SQL personnalisée, vous pouvez utiliser la classe WP_Query et laisser WordPress gérer tout le gros du SQL. Cela résoudrait sûrement votre problème de navigation.

Exemple de requête pour le type de publication de film dans votre méta-clé _expiry_date:

$today = getdate();
$args = array(
    'post_type' => 'movie',
    'meta_query' => array(
            'meta_key' => '_expiry_date',
            'meta_value' => $today,
            'meta_compare' => '< '
                    ),
    'posts_per_page' => -1,
     'order'    => 'DESC'
    );

    $movie_query = new WP_Query( $args );

    while ( $movie_query->have_posts() ) : $movie_query->the_post(); 
    // Do stuff
   endwhile; ?>

 <div class="navigation">
<div class="previous panel"><?php previous_posts_link('&laquo; newer') ?></div>
<div class="next panel"><?php next_posts_link('older &raquo;') ?></div>
</div>
Chris_O
la source
merci pour la réponse, cependant, je ne peux pas compter sur la WP_Queryclasse car j'ai besoin de construire mon propre SQL personnalisé. J'y suis arrivé à la fin, voir ma réponse si intéressé :)
dashaluna
-2
<?php

global $wpdb, $paged;
query_posts($query_string . '&posts_per_page=9');
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$author = isset($_GET['author_name']) ? get_userdatabylogin($author_name) : get_userdata(intval($author));

query_posts($query_string . '&posts_per_page=9');

$args = array(
'post_type' => 'post',
'meta_query' => array(
        'meta_key' => 'autor',
    'post_status' => 'publish',
        'meta_value' => $author->id,
            ),
'paged' => $paged,
'posts_per_page' => 9,
'order'    => 'DESC'
);

$postsQuery = new WP_Query( $args );

?> 

Modèle:

<h1lánky od <?php echo $author->display_name; ?></h1>
        <ul class="thumbnails">

            <?php while ( $postsQuery->have_posts() ) : $postsQuery->the_post();  ?>
                <li class="span3">
                <div class="thumbnail">
                    <a href="<?php the_permalink(); ?>">
                    <?php the_post_thumbnail(array(260, 259)); ?>
                    </a>
                    <?php
                    $class = '';
                    if (in_category('fashion')) {
                    $class = "link-fashion";
                    } else if (in_category('beauty')) {
                    $class = "link-beauty";
                    } else if (in_category('gourmet')) {
                    $class = "link-gourmet";
                    } else if (in_category('lifestyle')) {
                    $class = "link-lifestyle";
                    } else if (in_category('about-us')) {
                    $class = "link-about";
                    }
                    ?>
                    <a href="<?php the_permalink(); ?>">
                    <h2 class="<?=  $class ?>">
                        <span></span>
                        <?php
                        // short_title('...', 25); 
                        echo get_the_title();
                        ?>
                    </h2>
                    </a>
                    <?php the_excerpt(); ?>
                    <hr>
                </div>
                </li>
            <?php endwhile; ?>

        </ul>
        <?php wp_pagenavi(); ?>
iceoverr
la source
2
Veuillez également ajouter une explication à votre code, pourquoi exécutez-vous deux requêtes, une avec query_postset une avecWP_Query
Pieter Goosen