I link Articolo Successivo/Precedente possono essere ordinati per ordine menu o per meta key?

19 nov 2012, 19:23:48
Visualizzazioni: 28.3K
Voti: 40

Ho una serie di articoli che sono ordinati per un valore meta_key. Potrebbero anche essere disposti per ordine menu, se necessario.

I link articolo successivo/precedente (generati da next_post_link, previous_post_link, o posts_nav_link) navigano tutti in ordine cronologico. Mentre capisco questo comportamento predefinito, non capisco come modificarlo. Ho scoperto che viene mappato attraverso adjacent_post_link in link-template.php, ma poi sembra piuttosto hard-coded. È consigliabile riscriverlo da zero per sostituirlo, o esiste una soluzione migliore.

2
Commenti

Nota che la seconda risposta sembra fornire il risultato corretto.

Thomas Thomas
11 mar 2016 14:34:10
Tutte le risposte alla domanda 13
7
36

Comprendere gli interni

L'"ordine" di "ordinamento" dei post adiacenti (successivo/precedente) non è realmente un "ordine" di ordinamento. Si tratta di una query separata per ogni richiesta/pagina, ma ordina la query in base al post_date - o al genitore del post se si dispone di un post gerarchico come oggetto attualmente visualizzato.

Quando si esaminano gli interni di next_post_link(), si vede che è sostanzialmente un wrapper API per adjacent_post_link(). Quest'ultima funzione chiama internamente get_adjacent_post() con l'argomento/flag $previous impostato su bool(true|false) per ottenere il link al post successivo o precedente.

Cosa filtrare?

Dopo aver approfondito, si vedrà che get_adjacent_post() Link alla fonte dispone di alcuni utili filtri per il suo output (ovvero il risultato della query): (Nome Filtro/Argomenti)

  • "get_{$adjacent}_post_join"

    $join
    // Solo se `$in_same_cat`
    // oppure: ! empty( $excluded_categories` 
    // e poi: 
    // " INNER JOIN $wpdb->term_relationships AS tr 
    //     ON p.ID = tr.object_id 
    // INNER JOIN $wpdb->term_taxonomy tt 
    //     ON tr.term_taxonomy_id = tt.term_taxonomy_id"; 
    // e se $in_same_cat allora AGGIUNGE: 
    // " AND tt.taxonomy = 'category' 
    // AND tt.term_id IN (" . implode(',', $cat_array) . ")";
    $in_same_cat
    $excluded_categories
    
  • "get_{$adjacent}_post_where"

    $wpdb->prepare(
          // $op = $previous ? '<' : '>'; | $current_post_date
           "WHERE p.post_date $op %s "
          // $post->post_type
          ."AND p.post_type = %s "
          // $posts_in_ex_cats_sql = " AND tt.taxonomy = 'category' 
          // AND tt.term_id NOT IN (" . implode($excluded_categories, ',') . ')'; 
          // O stringa vuota se $in_same_cat || ! empty( $excluded_categories
          ."AND p.post_status = 'publish' $posts_in_ex_cats_sql "
        ",
        $current_post_date,
        $post->post_type
    )
    $in_same_cat
    $excluded_categories
    
  • "get_{$adjacent}_post_sort"

    "ORDER BY p.post_date $order LIMIT 1"`
    

Quindi si può fare molto con esso. Si parte dal filtrare la clausola WHERE, così come la tabella JOIN e l'istruzione ORDER BY.

Il risultato viene memorizzato nella cache per la richiesta corrente, quindi non aggiunge query aggiuntive se si chiama quella funzione più volte su una singola pagina.

Costruzione automatica della query

Come @StephenHarris ha sottolineato nei commenti, esiste una funzione di core che potrebbe tornare utile nella costruzione della query SQL: get_meta_sql() - Esempi nel Codex. Fondamentalmente questa funzione viene utilizzata solo per costruire l'istruzione SQL meta che viene utilizzata in WP_Query, ma in questo caso (o altri) è possibile utilizzarla anche. L'argomento che si passa è un array, lo stesso che si aggiungerebbe a un WP_Query.

$meta_sql = get_meta_sql(
    $meta_query,
    'post',
    $wpdb->posts,
    'ID'
);

Il valore restituito è un array:

$sql => (array) 'join' => array(),
        (array) 'where' => array()

Quindi è possibile utilizzare $sql['join'] e $sql['where'] nel callback.

Dipendenze da tenere a mente

Nel tuo caso la cosa più semplice sarebbe intercettarlo in un piccolo (mu)plugin o nel file functions.php del tema e modificarlo in base alla variabile $adjacent = $previous ? 'previous' : 'next'; e alla variabile $order = $previous ? 'DESC' : 'ASC';:

I nomi effettivi dei filtri

Quindi i nomi dei filtri sono:

  • get_previous_post_join, get_next_post_join
  • get_previous_post_where, get_next_post_where
  • get_previous_post_sort, get_next_post_sort

Racchiuso in un plugin

...e il callback del filtro sarebbe (ad esempio) qualcosa come il seguente:

<?php
/** Plugin Name: (#73190) Modifica l'ordine di ordinamento del link al post adiacente */
function wpse73190_adjacent_post_sort( $orderby )
{
    return "ORDER BY p.menu_order DESC LIMIT 1";
}
add_filter( 'get_previous_post_sort', 'wpse73190_adjacent_post_sort' );
add_filter( 'get_next_post_sort', 'wpse73190_adjacent_post_sort' );
19 nov 2012 19:40:07
Commenti

+1. Solo per informazione, (@magnakai) se stai facendo qualcosa di simile per le meta query, dai un'occhiata a get_meta_sql()

Stephen Harris Stephen Harris
19 nov 2012 20:30:12

+1 a te @StephenHarris ! Non l'avevo mai visto prima. Breve domanda: Come ho letto dal codice sorgente, devi passare un oggetto query completamente qualificato, come faresti questo con i filtri menzionati sopra? Per quanto posso vedere vengono passate solo stringhe di query, dato che la query viene eseguita dopo i filtri.

kaiser kaiser
19 nov 2012 20:58:39

no, $meta_query è semplicemente l'array che passeresti a WP_Query per l'argomento meta_query: In questo esempio: $meta_sql = get_meta_sql( $meta_query, 'post', $wpdb->posts, 'ID'); - questo genera le parti JOIN e WHERE della query che dovrebbero essere aggiunte.

Stephen Harris Stephen Harris
19 nov 2012 21:41:06

@StephenHarris Momento perfetto per modificare una (mia) risposta.

kaiser kaiser
20 nov 2012 02:28:57

@StephenHarris, sto avendo problemi ad applicare l'output di get_meta_sql() - puoi aiutarmi a collegare i puntini?

Jodi Warren Jodi Warren
20 nov 2012 13:27:27

@Magnakai è un array di $sql => (array) 'join' => array(), 'where' => array(). Quindi semplicemente prendi $sql['join']; o $sql['where'].

kaiser kaiser
26 nov 2013 19:13:39

Questo ha funzionato, tranne per il fatto che i link sono invertiti. Il previous_post_link genera il link che dovrebbe generare next_post_link e viceversa. Ho provato a cambiare l'ordine da DESC ad ASC ma continua a farlo.

Dan Dan
10 mag 2019 16:53:23
Mostra i restanti 2 commenti
2
27

La risposta di Kaiser è fantastica e approfondita, tuttavia modificare solo la clausola ORDER BY non è sufficiente a meno che il tuo menu_order non corrisponda all'ordine cronologico.

Non posso prendermi il merito, ma ho trovato il seguente codice in questo gist:

<?php
/**
 * Personalizza l'ordine dei link ai post adiacenti
 */
function wpse73190_gist_adjacent_post_where($sql) {
  if ( !is_main_query() || !is_singular() )
    return $sql;

  $the_post = get_post( get_the_ID() );
  $patterns = array();
  $patterns[] = '/post_date/';
  $patterns[] = '/\'[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}\'/';
  $replacements = array();
  $replacements[] = 'menu_order';
  $replacements[] = $the_post->menu_order;
  return preg_replace( $patterns, $replacements, $sql );
}
add_filter( 'get_next_post_where', 'wpse73190_gist_adjacent_post_where' );
add_filter( 'get_previous_post_where', 'wpse73190_gist_adjacent_post_where' );

function wpse73190_gist_adjacent_post_sort($sql) {
  if ( !is_main_query() || !is_singular() )
    return $sql;

  $pattern = '/post_date/';
  $replacement = 'menu_order';
  return preg_replace( $pattern, $replacement, $sql );
}
add_filter( 'get_next_post_sort', 'wpse73190_gist_adjacent_post_sort' );
add_filter( 'get_previous_post_sort', 'wpse73190_gist_adjacent_post_sort' );

Ho modificato i nomi delle funzioni per WP.SE.

Se modifichi solo la clausola ORDER BY, la query continua a cercare post con date maggiori o minori della data del post corrente. Se i tuoi post non sono in ordine cronologico, non otterrai il post corretto.

Questo codice modifica la clausola WHERE per cercare post dove il menu_order è maggiore o minore del menu_order del post corrente, oltre a modificare la clausola orderby.

Inoltre, la clausola orderby non dovrebbe essere hardcoded per usare DESC poiché dovrà cambiare in base a se stai ottenendo il link al post successivo o precedente.

16 apr 2013 06:18:47
Commenti

Una nota: La clausola WHERE cerca il formato 'YYYY-mm-dd HH:mm:ss'. Se questo formato non viene rispettato, non funzionerà. Poiché il valore non è impostato dal database, ma dall'Applicazione, dovrai verificare prima questo formato quando costruisci l'espressione regolare.

kaiser kaiser
6 apr 2014 15:11:15

Se vuoi ordinare per post_title puoi sostituire tutte le istanze di menu_order nel codice sopra e dovrebbe funzionare bene. Fai attenzione però al secondo elemento nell'array $replacements - ho dovuto racchiuderlo tra apici singoli per farlo funzionare, cioè $replacements[] = '\'' . $the_post->post_title . '\'';

Ben Stevens Ben Stevens
1 lug 2021 22:26:28
5

Ho provato ad agganciarmi senza successo. Potrebbe essere solo un problema della mia configurazione, ma per coloro che non riescono a far funzionare l'hook, ecco la soluzione più semplice:

<?php
    $all_posts = new WP_Query(array(
        'orderby' => 'menu_order',
        'order' => 'ASC',
        'posts_per_page' => -1
    ));

    foreach($all_posts->posts as $key => $value) {
        if($value->ID == $post->ID){
            $nextID = $all_posts->posts[$key + 1]->ID;
            $prevID = $all_posts->posts[$key - 1]->ID;
            break;
        }
    }
?>
<?php if($prevID): ?>
    <span class="prev">
        <a href="<?= get_the_permalink($prevID) ?>" rel="prev"><?= get_the_title($prevID) ?></a>
    </span>
<?php endif; ?>
<?php if($nextID): ?>
    <span class="next">
        <a href="<?= get_the_permalink($nextID) ?>" rel="next"><?= get_the_title($nextID) ?></a>
    </span>
<?php endif; ?>
26 ott 2017 13:38:52
Commenti

dopo alcune ore di tentativi per far funzionare get_previous_post_where, get_previous_post_join e get_previous_post_sort con tipi di post personalizzati e un ordinamento complesso che include meta key, ho rinunciato e ho usato questo. Grazie!

squarecandy squarecandy
13 lug 2018 01:52:16

Anche io, non solo volevo ordinare per Menu Order, ma anche cercare post con una specifica meta_key e meta_value, quindi questo era il metodo migliore. L'unica modifica che ho fatto è stata di racchiuderlo in una funzione.

MrCarrot MrCarrot
10 feb 2019 10:35:30

questo codice è suscettibile a errori di out of range

eballeste eballeste
2 apr 2020 04:35:51

@eballeste, se ti riferisci a ottenere il primo post quando sei sull'ultimo e l'ultimo quando sei sul primo, guarda la mia risposta qui sotto

Eli Jayson Eli Jayson
3 apr 2020 22:10:50

si, l'ho visto dopo e ho votato, grazie

eballeste eballeste
9 apr 2020 02:38:44
0
function wpse73190_gist_adjacent_post_sort( $sql ) {
    $pattern = '/post_date/';
    $replacement = 'menu_order';

    return preg_replace( $pattern, $replacement, $sql );
}

add_filter( 'get_next_post_sort', 'wpse73190_gist_adjacent_post_sort' );
add_filter( 'get_previous_post_sort', 'wpse73190_gist_adjacent_post_sort' );
20 giu 2013 08:00:36
0

Per quello che vale, ecco come puoi ordinare per menu_order per un specifico custom post type:

/**
 * Personalizza l'ordine dei post adiacenti
 */
add_filter('get_next_post_sort', function($order) {
    if (is_singular('my_custom_post_type')) {
        return 'ORDER BY p.menu_order ASC LIMIT 1';
    }

    return $order;
}, 10);

add_filter('get_previous_post_sort', function($order) {
    if (is_singular('my_custom_post_type')) {
        return 'ORDER BY p.menu_order DESC LIMIT 1';
    }

    return $order;
}, 10);

add_filter('get_next_post_where', function() {
    if (is_singular('my_custom_post_type')) {
        global $post, $wpdb;
        return $wpdb->prepare("WHERE p.menu_order > %s AND p.post_type = %s AND p.post_status = 'publish'", $post->menu_order, $post->post_type);
    }
}, 10);

add_filter('get_previous_post_where', function() {
    if (is_singular('my_custom_post_type')) {
        global $post, $wpdb;
        return $wpdb->prepare("WHERE p.menu_order < %s AND p.post_type = %s AND p.post_status = 'publish'", $post->menu_order, $post->post_type);
    }
}, 10);

Spero che questo possa aiutare qualcun altro!

4 ago 2021 21:00:58
0

Basandomi sulla risposta di @Szabolcs Páll ho creato questa classe di utilità con metodi helper per ottenere i post di un tipo ordinati per menu order e per ottenere anche il post successivo e precedente in base all'ordine del menu. Ho inoltre aggiunto condizioni per verificare se il post corrente è il primo o l'ultimo post per ottenere rispettivamente l'ultimo o il primo post.

Ad esempio:

// $currentPost è il primo per menu order
getPreviousPostByMenuOrder($postType, $$currentPost->ID)
// restituisce => l'ultimo post per menu order

// $currentPost è l'ultimo per menu order
getPreviousPostByMenuOrder($postType, $$currentPost->ID)
// restituisce => il primo post per menu order

La classe completa:

class PostMenuOrderUtils {

    public static function getPostsByMenuOrder($postType){
        $args =[
            'post_type' => $postType,
            'orderby' => 'menu_order',
            'order' => 'ASC',
            'posts_per_page' => -1
        ];

        $posts = get_posts($args);

        return $posts;
    }

    public static function getNextPostByMenuOrder($postType, $postID){
        $posts = self::getPostsByMenuOrder($postType);

        $nextPost = null;

        foreach($posts as $key => $value) {
            if($value->ID == $postID){
                $nextPost = $posts[$key] !== end($posts) ? $posts[$key + 1] : $posts[0];

                break;
            }
        }

        return $nextPost;
    }

    public static function getPreviousPostByMenuOrder($postType, $postID){
        $posts = self::getPostsByMenuOrder($postType);


        $prevPost = null;

        foreach($posts as $key => $value) {
            if($value->ID == $postID){
                $prevPost = $key !== 0 ? $posts[$key - 1] : end($posts);
                break;
            }
        }

        return $prevPost;
    }

}
16 mag 2019 23:04:20
1

Basandomi sulla risposta di @Szabolcs Páll e sul post di bbloomer su come aggiungere pulsanti next/prev nella pagina singola del prodotto WooCommerce, ho creato questo codice.

Ordina tutti i prodotti per meta key e aggiunge pulsanti prev/next sopra e sotto il prodotto.

(La meta key può essere anche un campo ACF!)

/**
 * @snippet       Aggiungi pulsanti next/prev ordinati per meta key o campo ACF @ Pagina Singola Prodotto WooCommerce
 * @testedwith    WooCommerce 4.8.0
 * @source        Elron : https://wordpress.stackexchange.com/a/365334/98773
 * @thanks        bbloomer : https://businessbloomer.com/?p=20567
 * @thanks        Szabolcs Páll : https://wordpress.stackexchange.com/a/284045/98773
 */

add_action('woocommerce_before_single_product', 'elron_prev_next_product');

// e se li vuoi anche in fondo...
add_action('woocommerce_after_single_product', 'elron_prev_next_product');

function elron_prev_next_product()
{
   global $post;

   echo '<div class="prev-next-buttons">';

   $all_posts = new WP_Query(
      array(
         'post_type' => 'product',
         'meta_key' => 'the_meta_key_or_acf_field', // <-- MODIFICA QUESTO
         'orderby' => 'meta_value',
         'order' => 'DESC',
         'posts_per_page' => -1
      )
   );

   foreach ($all_posts->posts as $key => $value) {
      if ($value->ID == $post->ID) {
         $nextID = $all_posts->posts[$key + 1]->ID;
         $prevID = $all_posts->posts[$key - 1]->ID;
         break;
      }
   }

   if ($prevID) : ?>
      <a href="<?= get_the_permalink($prevID) ?>" rel="prev" class="prev" title="<?= get_the_title($prevID) ?>"><?= esc_attr__('Prodotto precedente') ?></a>
   <?php endif; ?>
   <?php if ($nextID) : ?>
      <a href="<?= get_the_permalink($nextID) ?>" rel="next" class="next" title="<?= get_the_title($nextID) ?>"><?= esc_attr__('Prodotto successivo') ?></a>
   <?php endif; ?>
<?php

   echo '</div>';
}

Se vuoi il file scss aggiuntivo che ho usato: _prev-next-buttons.scss

.prev-next-buttons {
    background: $lightpurple;
    padding: 2em;
    text-align: center;

    a {
        opacity: 0.7;
        border-radius: 0.5em;
        border: $white 1px solid;
        color: $white;
        display: inline-block;
        padding: 0.5em 0.8em;
        text-decoration: none;
        margin: 0 0.1em;
        &:hover, &:focus {
            opacity: 1;
        }
    }

    .prev {
        &:before {
            content: "  ";
        }
    }
    .next {
        &:after {
            content: "  ";
        }
    }
}

.rtl {
    .prev-next-buttons {
        .prev {
            &:before {
                content: "  ";
            }
        }
        .next {
            &:after {
                content: "  ";
            }
        }
    }
}

28 apr 2020 21:51:17
Commenti

Grazie per le preziose informazioni. Le ho utilizzate con il mio tipo di post personalizzato che ha anche un campo data personalizzato. Ha funzionato perfettamente su WordPress 5.9.3. Posso anche confermare che ha funzionato con i tipi di post e i campi personalizzati che sono stati creati utilizzando plugin di terze parti come ACF.

Mycodingproject Mycodingproject
10 mag 2022 14:44:00
2

Nessuna delle risposte elencate qui o su Internet in generale che ho potuto trovare al momento della stesura sembrava offrire una soluzione ragionevolmente semplice/elegante per presentare i link Post Successivo/Precedente ordinati per meta key. Questa soluzione funziona bene per me ed è facile da adattare. Buon utilizzo!

add_filter( 'get_previous_post_where', function( $where ) {
    return get_adjacent_post_where( $where, false) ;
});
add_filter( 'get_next_post_where', function ( $where ) {
    return get_adjacent_post_where( $where, true );
}); 

function get_adjacent_post_where( $where, $is_next ) {  

    global $post;

    /* Inserisci il tuo post type -> */
    $post_type = "_my_post_type_";

    if ($post_type == $post->post_type){

        global $wpdb;

        $show_private = current_user_can( 'read_private_pages', $post->ID );
        /* Inserisci il nome della tua meta key personalizzata -> */
        $meta_key = '_my_meta_key_name_'; 
        $meta_value = get_post_meta($post->ID,$meta_key,true);
        $operand = $is_next?">":"<";
        $direction = $is_next?"ASC":"DESC";

        $sub_query = "(SELECT m.post_id FROM `" . $wpdb->postmeta . "` AS m JOIN `" . $wpdb->posts . "` as p1 ON m.post_id = p1.ID "
        . "WHERE m.meta_key = '$meta_key' AND m.meta_value $operand '$meta_value' "
        . "AND (p1.post_status = 'publish'" . ($show_private?" OR p1.post_status = 'private') ":") ")
        . "ORDER BY m.meta_value $direction LIMIT 1)";
         
        /* La subquery annidata aggira le attuali limitazioni di mysql/mariadb */
        $where = "WHERE p.post_type = '$post_type'  AND p.ID IN (SELECT * FROM $sub_query as sq)";  
    }

    return $where;

}
28 gen 2024 20:24:54
Commenti

Nel tuo codice ci sono riferimenti a tabelle con prefisso, ad esempio kc_wppostmeta e kc_wpposts. La best practice è utilizzare l'oggetto globale $wpdb per specificare queste tabelle, ad esempio $wpdb->posts invece di kc_wpposts.

Penso inoltre valga la pena notare che questo presuppone che tu stia ottenendo contenuti pubblicati pubblicamente o privatamente nella tua sub-query. C'è un'intera sezione di condizioni che gestisce questo aspetto nel codice core: https://github.com/WordPress/wordpress-develop/blob/8338c630284124bbe79dc871822d6767e3b45f0b/src/wp-includes/link-template.php#L1893

MikeNGarrett MikeNGarrett
2 feb 2024 22:17:57

Grazie @MikeNGarrett. Ho apportato le modifiche. Fammi sapere se ho mancato il bersaglio.

Collie Collie
5 feb 2024 02:55:03
0

Trovo questo piccolo plugin davvero utile: http://wordpress.org/plugins/wp-query-powered-adjacent-post-link/

WP_Query Powered Adjacent Post Link è un plugin per sviluppatori. Aggiunge la funzione wpqpapl(); a WordPress che può restituire informazioni sul post precedente e successivo a quello corrente. Accetta argomenti per l'utilizzo nella classe WP_Query.

26 nov 2013 20:17:59
0

Questo ha funzionato per me:

add_filter( 'get_previous_post_where', 'so16495117_mod_adjacent_bis' );
add_filter( 'get_next_post_where', 'so16495117_mod_adjacent_bis' );
function so16495117_mod_adjacent_bis( $where ) {
    global $wpdb;
    return $where . " AND p.ID NOT IN ( SELECT post_id FROM $wpdb->postmeta WHERE ($wpdb->postmeta.post_id = p.ID ) AND $wpdb->postmeta.meta_key = 'archive' AND $wpdb->postmeta.meta_value = 1 )";
}

Preso da: https://stackoverflow.com/questions/16495117/how-to-skip-certain-links-on-adjacent-posts-in-wordpress

12 mar 2015 16:22:08
0

Anch'io ho avuto problemi con questo. Magicamente sono riuscito a farlo funzionare così:

E non ho dovuto scrivere nemmeno una riga di codice :)

4 feb 2020 18:03:26
0

Ho modificato il codice di Szabolcs Páll sopra per ordinare secondo una meta_key personalizzata e all'interno di una categoria specifica, ma ho anche cercato di aggiungere delle condizioni per i primi e gli ultimi post.

Sui primi e sugli ultimi post non mostrava il link corretto per il successivo/precedente con il codice originale, mostrando solo un link per l'ID del post corrente su cui mi trovavo.

Quello che segue ha funzionato per me, ma non sono sicuro se ci siano potenziali problemi (non sono un programmatore molto avanzato).

<?php
$all_posts = new WP_Query(array(
    'taxonomy' => 'category',
    'category_name' => 'projects',
    'meta_key' => 'grid_number_projects',
    'orderby' => 'meta_value',
    'order' => 'ASC',
    'posts_per_page' => -1
));
foreach($all_posts->posts as $key => $value) {
    if($value->ID == $post->ID){
        $nextID = isset($all_posts->posts[$key + 1]) ? $all_posts->posts[$key + 1]->ID : null;
        $prevID = isset($all_posts->posts[$key - 1]) ? $all_posts->posts[$key - 1]->ID : null;
        break;
    }
}
?>
<div class="project-nav-prev">
    <?php if($prevID): ?>
        <a href="<?= get_the_permalink($prevID) ?>" rel="prev"><span class="arrow">←</span> PROGETTO PRECEDENTE </br><?= get_the_title($prevID) ?></a>
    <?php endif; ?>
</div>
<div class="project-nav-next">
    <?php if($nextID): ?>
        <a href="<?= get_the_permalink($nextID) ?>" rel="next">PROGETTO SUCCESSIVO <span class="arrow">→</span> </br><?= get_the_title($nextID) ?></a>
    <?php endif; ?>
</div>
23 mar 2023 14:18:59
4
-2

Ho trovato un modo molto più semplice per implementare una navigazione tra post basata su meta-key, senza la necessità di modificare functions.php.

Il mio esempio: hai un products.php e vuoi navigare tra i prodotti. Il prodotto precedente è quello più economico, il prodotto successivo è quello più costoso.

Ecco la mia soluzione per single.php:

<div class="post_navigation">

<?php

// Prepara il loop
$args = (
'post_type' => 'products',
'post_status' => 'publish',
'meta_key' => 'price',
'orderby' => 'meta_value_num',
'order' => 'ASC',
'posts_per_page' => -1
);
query_posts($args);

// Inizializza l'array in cui verranno memorizzati gli ID di TUTTI i post prodotti
$posts = array();

// ... e ora avviamo il loop
while ( have_posts() ) : the_post();
$posts[] += $post->ID;
endwhile;

// Resetta la Query
wp_reset_query();

// Identifica la posizione del prodotto corrente nell'array $posts
$current = array_search(get_the_ID(), $posts);

// Identifica l'ID del prodotto precedente
$prevID = $posts[$current-1];

// Identifica l'ID del prodotto successivo
$nextID = $posts[$current+1];

// Link "prodotto precedente"
if (!empty($prevID)) { ?>
<a href="/?p=<?php echo $prevID; ?>">prodotto precedente</a>
<?php }
// Link "prodotto successivo"
if (!empty($nextID)) { ?>
<a href="/?p=<?php echo $nextID; ?>">prodotto successivo</a>

<?php } ?>
21 mag 2014 11:25:46
Commenti

-10 per questa risposta. Come può essere una soluzione migliore se stai usando query_posts quando il codex afferma che non dovrebbe essere utilizzato.

Pieter Goosen Pieter Goosen
21 mag 2014 11:31:30

ma funziona. quindi l'alternativa è WP_Query o cosa?

Kent Miller Kent Miller
21 mag 2014 12:22:49

Sì, dovresti usare WP_Query come nelle risposte precedenti.

Pieter Goosen Pieter Goosen
21 mag 2014 12:27:09

@KentMiller, c'è un diagramma informativo nella pagina del codex, e potresti anche trovare utile questa domanda. Vale davvero la pena familiarizzare con queste convenzioni.

Jodi Warren Jodi Warren
21 mag 2014 13:56:19