Pot fi ordonate linkurile Next/Prev ale articolelor după ordinea din meniu sau după o meta key?

19 nov. 2012, 19:23:48
Vizualizări: 28.3K
Voturi: 40

Am o serie de articole care sunt ordonate după valoarea unei meta_key. Acestea ar putea fi aranjate și după ordinea din meniu (menu order), dacă este necesar.

Linkurile next/prev ale articolelor (generate de next_post_link, previous_post_link, sau posts_nav_link) navighează toate după cronologie. Deși înțeleg acest comportament implicit, nu înțeleg cum să-l modific. Am descoperit că se mapează prin adjacent_post_link în link-template.php, dar apoi pare destul de codat direct în sistem. Este recomandat să rescriu această funcționalitate de la zero pentru a o înlocui, sau există o soluție mai bună?

2
Comentarii

Reține că al doilea răspuns pare să ofere rezultatul corect.

Thomas Thomas
11 mar. 2016 14:34:10
Toate răspunsurile la întrebare 13
7
36

Înțelegerea mecanismelor interne

Ordinea de "sortare" a postărilor adiacente (următoare/anterioară) nu este cu adevărat o "ordine" de sortare. Este o interogare separată pentru fiecare solicitare/pagină, dar sortează interogarea după post_date - sau după părintele postării dacă aveți o postare ierarhică ca obiect afișat în prezent.

Când analizați mecanismele interne ale funcției next_post_link(), veți observa că este practic un înveliș API pentru adjacent_post_link(). Această din urmă funcție apelează intern get_adjacent_post() cu argumentul/flag-ul $previous setat la bool(true|false) pentru a obține link-ul postării următoare sau anterioare.

Ce să filtrați?

După o analiză mai profundă, veți observa că get_adjacent_post() Sursă are câteva filtre utile pentru rezultatul său (adică rezultatul interogării): (Numele filtrului/Argumente)

  • "get_{$adjacent}_post_join"

    $join
    // Numai dacă `$in_same_cat`
    // sau: ! empty( $excluded_categories` 
    // și apoi: 
    // " 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"; 
    // iar dacă $in_same_cat atunci ADĂUGAȚI: 
    // " 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, ',') . ')'; 
          // SAU șir gol dacă $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"`
    

Deci puteți face foarte multe cu acestea. Aceasta începe cu filtrarea clauzei WHERE, precum și a tabelei JOIN și a instrucțiunii ORDER BY.

Rezultatul este stocat în cache în memorie pentru solicitarea curentă, astfel încât nu adaugă interogări suplimentare dacă apelați această funcție de mai multe ori pe o singură pagină.

Construirea automată a interogărilor

După cum a menționat @StephenHarris în comentarii, există o funcție de bază care ar putea fi utilă atunci când construiți interogarea SQL: get_meta_sql() - Exemple în Codex. Practic, această funcție este folosită doar pentru a construi instrucțiunea meta SQL care este utilizată în WP_Query, dar o puteți folosi și în acest caz (sau în altele). Argumentul pe care îl introduceți este un array, exact același care s-ar adăuga la un WP_Query.

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

Valoarea returnată este un array:

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

Deci puteți folosi $sql['join'] și $sql['where'] în callback-ul dvs.

Dependințe de reținut

În cazul dvs., cel mai simplu ar fi să interceptați acest lucru într-un mic (mu)plugin sau în fișierul functions.php al temei și să-l modificați în funcție de variabila $adjacent = $previous ? 'previous' : 'next'; și variabila $order = $previous ? 'DESC' : 'ASC';:

Numele reale ale filtrelor

Deci numele filtrelor sunt:

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

Împachetat ca un plugin

...iar callback-ul filtrului ar fi (de exemplu) ceva de genul următorului:

<?php
/** Plugin Name: (#73190) Modifică ordinea de sortare a link-urilor de postări 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
Comentarii

+1. Doar pentru informație, (@magnakai) dacă faci ceva de genul pentru interogările meta, verifică get_meta_sql()

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

+1 pentru tine @StephenHarris! Nu am văzut aceasta înainte. O întrebare scurtă: Cum am înțeles din sursă, trebuie să transmiți un obiect de interogare complet calificat, cum ai face asta cu filtrele menționate mai sus? Din câte văd, sunt transmise doar șiruri de interogare, deoarece interogarea este executată după filtre.

kaiser kaiser
19 nov. 2012 20:58:39

nu, $meta_query este doar array-ul pe care l-ai pasa la WP_Query pentru argumentul meta_query: În acest exemplu: $meta_sql = get_meta_sql( $meta_query, 'post', $wpdb->posts, 'ID'); - acesta generează părțile JOIN și WHERE ale interogării care ar trebui adăugate.

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

@StephenHarris Momentul perfect pentru a edita unul (al meu) răspuns.

kaiser kaiser
20 nov. 2012 02:28:57

@StephenHarris, am probleme în aplicarea rezultatului funcției get_meta_sql() - poți să mă ajuți să le conectez?

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

@Magnakai este un array $sql => (array) 'join' => array(), 'where' => array(). Deci pur și simplu ia $sql['join']; sau $sql['where'].

kaiser kaiser
26 nov. 2013 19:13:39

A funcționat, cu excepția faptului că linkurile sunt inversate. previous_post_link generează linkul pe care ar trebui să-l genereze next_post_link și invers. Am încercat să schimb ordinea de la DESC la ASC, dar tot așa se întâmplă.

Dan Dan
10 mai 2019 16:53:23
Arată celelalte 2 comentarii
2
27

Răspunsul lui Kaiser este minunat și detaliat, totuși simpla modificare a clauzei ORDER BY nu este suficientă dacă menu_order nu corespunde cu ordinea cronologică.

Nu pot revendica meritul pentru asta, dar am găsit următorul cod în acest gist:

<?php
/**
 * Personalizează ordinea linkurilor către postările adiacente
 */
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' );

Am modificat numele funcțiilor pentru WP.SE.

Dacă schimbi doar clauza ORDER BY, interogarea va continua să caute postări cu o dată mai mare sau mai mică decât data curentă. Dacă postările tale nu sunt în ordine cronologică, nu vei obține postarea corectă.

Acest cod modifică clauza WHERE pentru a căuta postări unde menu_order este mai mare sau mai mic decât menu_order-ul postării curente, pe lângă modificarea clauzei orderby.

De asemenea, clauza orderby nu ar trebui să fie hardcodată să folosească DESC, deoarece va trebui să comute în funcție de faptul dacă cauți linkul către următoarea sau anterioara postare.

16 apr. 2013 06:18:47
Comentarii

O observație: Clauza WHERE caută formatul 'YYYY-mm-dd HH:mm:ss'. Dacă acest format nu este respectat, nu va funcționa. Deoarece valoarea nu este setată de baza de date, ci de aplicație, va trebui să verificați acest format înainte de a construi expresia regulată.

kaiser kaiser
6 apr. 2014 15:11:15

Dacă doriți să ordonați după post_title, puteți înlocui toate aparițiile lui menu_order în codul de mai sus și ar trebui să funcționeze. Aveți grijă la al doilea element din array-ul $replacements însă - a trebuit să-l încadrez în ghilimele simple pentru a funcționa, adică $replacements[] = '\'' . $the_post->post_title . '\'';

Ben Stevens Ben Stevens
1 iul. 2021 22:26:28
5

Am încercat să folosesc hook-ul fără succes. Poate fi doar o problemă de configurare din partea mea, dar pentru cei care nu reușesc să facă hook-ul să funcționeze, iată cea mai simplă soluție:

<?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 oct. 2017 13:38:52
Comentarii

după câteva ore de încercare de a face get_previous_post_where, get_previous_post_join și get_previous_post_sort să funcționeze corect cu tipuri personalizate de articole și ordonări complexe care includ meta chei, am renunțat și am folosit asta. Mulțumesc!

squarecandy squarecandy
13 iul. 2018 01:52:16

La fel și eu, nu doar că voiam să ordonez după Menu Order, dar și să caut articole cu o meta_key și meta_value specifică, așa că aceasta a fost cea mai bună metodă. Singura modificare pe care am făcut-o a fost să o încapsulez într-o funcție.

MrCarrot MrCarrot
10 feb. 2019 10:35:30

acest cod este susceptibil la erori de depășire a intervalului

eballeste eballeste
2 apr. 2020 04:35:51

@eballeste, dacă te referi la obținerea primului post când ești pe ultimul și ultimului când ești pe primul, vezi răspunsul meu mai jos

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

da, l-am văzut după și am dat upvote, mulțumesc

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 iun. 2013 08:00:36
0

Apropo, iată cum poți ordona după menu_order pentru un anumit tip de postare personalizată:

/**
 * Personalizează ordinea postărilor adiacente
 */
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);

Sper că acest lucru îi va ajuta pe alții!

4 aug. 2021 21:00:58
0

Bazat pe răspunsul lui @Szabolcs Páll, am creat această clasă utilitară cu metode helper pentru a putea obține postări de un anumit tip ordonate după meniu, precum și pentru a obține postările următoare și anterioare după ordinea din meniu. Am adăugat și condiții pentru a verifica dacă postarea curentă este prima sau ultima din listă, pentru a returna ultima sau prima postare respectiv.

De exemplu:

// $currentPost este prima după ordinea din meniu
getPreviousPostByMenuOrder($postType, $$currentPost->ID)
// returnează => ultima postare după ordinea din meniu

// $currentPost este ultima după ordinea din meniu
getPreviousPostByMenuOrder($postType, $$currentPost->ID)
// returnează => prima postare după ordinea din meniu

Clasa completă:

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 mai 2019 23:04:20
1

Bazat pe răspunsul lui @Szabolcs Páll și postul lui bbloomer despre adăugarea butoanelor următor/precedent în pagina WooCommerce Single Product, am creat acest cod.

Sortează toate produsele după meta key și adaugă butoanele prev/next deasupra și sub produs.

(Meta key poate fi și un câmp ACF!)

/**
 * @snippet       Adaugă butoane următor/precedent sortate după meta key sau câmp ACF @ WooCommerce Single Product Page
 * @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');

// și dacă le dorești și în partea de jos...
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', // <-- SCHIMBĂ ACESTA
         '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__('Produsul anterior') ?></a>
   <?php endif; ?>
   <?php if ($nextID) : ?>
      <a href="<?= get_the_permalink($nextID) ?>" rel="next" class="next" title="<?= get_the_title($nextID) ?>"><?= esc_attr__('Produsul următor') ?></a>
   <?php endif; ?>
<?php

   echo '</div>';
}

Dacă dorești fișierul suplimentar scss pe care l-am folosit: _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
Comentarii

Mulțumesc pentru informațiile valoroase. Le-am folosit cu tipul meu personalizat de postare care are și un câmp de dată personalizat. A funcționat perfect pe WordPress 5.9.3. Pot confirma de asemenea că a funcționat și cu tipurile de postări personalizate și câmpurile create folosind plugin-uri terțe precum ACF.

Mycodingproject Mycodingproject
10 mai 2022 14:44:00
2

Niciunul dintre răspunsurile enumerate aici sau pe internet în general pe care le-am putut găsi până în momentul scrierii acestui text nu părea să ofere o soluție rezonabil de simplă/elegantă pentru afișarea link-urilor Post Anterior/Următor ordonate după cheie meta. Această soluție funcționează bine pentru mine și este ușor de adaptat. Bucurați-vă!

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;

    /* Introduceți tipul postului dvs. -> */
    $post_type = "_my_post_type_";

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

        global $wpdb;

        $show_private = current_user_can( 'read_private_pages', $post->ID );
        /* Introduceți numele cheii meta a câmpului personalizat -> */
        $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)";
         
        /* Subinterogarea imbricată funcționează în jurul limitărilor curente ale mysql/mariadb */
        $where = "WHERE p.post_type = '$post_type'  AND p.ID IN (SELECT * FROM $sub_query as sq)";  
    }

    return $where;

}
28 ian. 2024 20:24:54
Comentarii

Ai câteva referințe la tabele prefixate în codul tău, de exemplu kc_wppostmeta și kc_wpposts. Cea mai bună practică este să folosești obiectul global $wpdb pentru a specifica aceste tabele, de exemplu $wpdb->posts în loc de kc_wpposts.

De asemenea, cred că merită menționat că acest lucru presupune că obții conținut public sau privat publicat în sub-interogarea ta. Există o întreagă secțiune de condiții care se ocupă de asta în codul de bază: https://github.com/WordPress/wordpress-develop/blob/8338c630284124bbe79dc871822d6767e3b45f0b/src/wp-includes/link-template.php#L1893

MikeNGarrett MikeNGarrett
2 feb. 2024 22:17:57

Mulțumesc @MikeNGarrett. Am făcut modificările. Te rog să-mi spui dacă am greșit ceva.

Collie Collie
5 feb. 2024 02:55:03
0

Găsesc acest mic plugin foarte util: http://wordpress.org/plugins/wp-query-powered-adjacent-post-link/

WP_Query Powered Adjacent Post Link este un plugin pentru dezvoltatori. Adaugă funcția wpqpapl(); în WordPress, care poate returna informații despre postarea anterioară și următoare față de cea curentă. Acceptă argumente pentru utilizare în clasa WP_Query.

26 nov. 2013 20:17:59
0

Aceasta soluție a funcționat pentru mine:

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 )";
}

Preluat de la: https://stackoverflow.com/questions/16495117/how-to-skip-certain-links-on-adjacent-posts-in-wordpress

12 mar. 2015 16:22:08
0

Am avut și eu probleme cu asta. Am reușit să funcționeze magic astfel:

Și nu a trebuit să scriu niciun cod singur :)

4 feb. 2020 18:03:26
0

Am editat codul lui Szabolcs Páll de mai sus pentru a ordona după un meta_key personalizat și în cadrul unei categorii specifice, dar și pentru a încerca să adaug condiții pentru primele și ultimele postări.

La prima și ultima postare, nu afișa corect link-ul următor/anterior cu codul original, arătând doar un link pentru ID-ul postării curente pe care mă aflam.

Următorul cod a funcționat pentru mine, dar nu sunt sigur dacă există potențiale probleme cu el. (Nu sunt cel mai avansat coder)

<?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> PROIECT ANTERIOR </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">PROIECT URMĂTOR <span class="arrow">→</span> </br><?= get_the_title($nextID) ?></a>
    <?php endif; ?>
</div>
23 mar. 2023 14:18:59
4
-2

Am găsit o metodă mult mai ușoară pentru a implementa o navigare între postări bazată pe meta-chei, fără a fi nevoie să modific fișierul functions.php.

Exemplul meu: Aveți un products.php și doriți să navigați între produse. Produsul anterior este următorul cel mai ieftin, iar următorul produs este următorul cel mai scump.

Iată soluția mea pentru single.php:

<div class="post_navigation">

<?php

// Pregătirea loop-ului
$args = array(
'post_type' => 'products',
'post_status' => 'publish',
'meta_key' => 'price',
'orderby' => 'meta_value_num',
'order' => 'ASC',
'posts_per_page' => -1
);
query_posts($args);

// Inițializarea array-ului în care vor fi stocate ID-urile tuturor postărilor de produse
$posts = array();

// ... și acum să începem loop-ul
while ( have_posts() ) : the_post();
$posts[] += $post->ID;
endwhile;

// Resetarea interogării
wp_reset_query();

// Identificarea poziției produsului curent în array-ul $posts 
$current = array_search(get_the_ID(), $posts);

// Identificarea ID-ului produsului anterior
$prevID = $posts[$current-1];

// Identificarea ID-ului produsului următor
$nextID = $posts[$current+1];

// Link "produsul anterior"
if (!empty($prevID)) { ?>
<a href="/?p=<?php echo $prevID; ?>">produsul anterior</a>
<?php }
// Link "produsul următor"
if (!empty($nextID)) { ?>
<a href="/?p=<?php echo $nextID; ?>">produsul următor</a>

<?php } ?>
21 mai 2014 11:25:46
Comentarii

-10 pentru acest răspuns. Cum poate fi aceasta o soluție mai bună dacă folosești query_posts când codexul spune că nu ar trebui folosit.

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

dar funcționează. deci alternativa este WP_Query sau ce?

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

Da, WP_Query ar trebui folosit ca în răspunsurile anterioare.

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

@KentMiller, există o diagramă informativă pe pagina codex, și poți găsi de asemenea această întrebare utilă. Merită să te familiarizezi cu aceste convenții.

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