পরবর্তী / পূর্ববর্তী পোস্ট লিঙ্কগুলি মেনু আদেশ বা একটি মেটা কী দ্বারা অর্ডার করা যেতে পারে?


32

আমার কাছে এমন একটি সিরিজ পোস্ট রয়েছে যা একটি মেটা_কি মান দ্বারা অর্ডার করা হয়। এগুলি মেনু অর্ডার দিয়েও সাজানো যেতে পারে, প্রয়োজনে।

পরবর্তী / পূর্ববর্তী পোস্টে লিঙ্ক (দ্বারা উত্পন্ন next_post_link, previous_post_linkঅথবা posts_nav_linkকালপঞ্জি সকল নেভিগেট করুন। যদিও আমি এই ডিফল্ট আচরণ বুঝতে, আমি বুঝতে না কিভাবে এটা পরিবর্তন। আমি দেখেছি যে এটা লিঙ্ক template.php মধ্যে adjacent_post_link মাধ্যমে মানচিত্র, কিন্তু তারপরে এটি মোটামুটি শক্ত কোডড বলে মনে হচ্ছে it এটি প্রতিস্থাপনের জন্য এটি স্ক্র্যাচ থেকে পুনরায় লেখার পরামর্শ দেওয়া হয়েছে, বা এর থেকে আরও ভাল সমাধান আছে।


2
আপনার সমস্যার জন্য এখানে নিখুঁত প্লাগইন রয়েছে: wordpress.org/support/topic/… wordpress.org/extend/plugins/… আপনাকে ধন্যবাদ এমব্রোসাইট! :)
মিগুয়েলব

1
মনে রাখবেন যে দ্বিতীয় উত্তরটি সঠিক ফলাফল পেয়েছে বলে মনে হচ্ছে।
টমাস

উত্তর:


29

ইন্টার্নাল বোঝা

সংলগ্ন (পরবর্তী / পূর্ববর্তী) পোস্টগুলির "সাজানোর" ক্রমটি আসলে "ক্রম" নয়। এটি প্রতিটি অনুরোধ / পৃষ্ঠায় একটি পৃথক ক্যোয়ারী, তবে এটি আপনার post_date- বা পোস্ট প্যারেন্টের দ্বারা ক্যোয়ারীটি সাজায় যদি আপনার বর্তমানে প্রদর্শিত অবজেক্ট হিসাবে শ্রেণিবদ্ধ পোস্ট থাকে।

যখন তোমাদের অভ্যন্তরীণ কটাক্ষপাত করা next_post_link(), তাহলে আপনি দেখতে যে এটি মূলত জন্য একটি API মোড়কের এর adjacent_post_link()। পরবর্তী ফাংশনটি পরবর্তী বা পূর্ববর্তী পোস্টের লিঙ্কটি দখল করতে আর্গুমেন্ট / ফ্ল্যাগ সেট get_adjacent_post()করে অভ্যন্তরীণভাবে কল করে ।$previousbool(true|false)

ফিল্টার কি?

এটি আরও গভীরভাবে খনন করার পরে, আপনি দেখতে পাবেন যে get_adjacent_post() উত্স লিঙ্কটির আউটপুটটির জন্য কয়েকটি দুর্দান্ত ফিল্টার রয়েছে (ওরফে ক্যোয়ারী ফলাফল): (ফিল্টার নাম / যুক্তি)

  • "get_{$adjacent}_post_join"

    $join
    // Only if `$in_same_cat`
    // or: ! empty( $excluded_categories` 
    // and then: 
    // " 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"; 
    // and if $in_same_cat then it APPENDS: 
    // " 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, ',') . ')'; 
          // OR empty string if $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"`

সুতরাং আপনি এটি দিয়ে অনেক করতে পারেন । এটি WHEREক্লজ ফিল্টার করার পাশাপাশি JOINএড টেবিল এবং ORDER BYবিবৃতি দিয়ে শুরু হয়।

ফলাফলটি বর্তমান অনুরোধটির জন্য মেমোরিতে ক্যাশে হয়ে যায়, তাই আপনি যদি কোনও একক পৃষ্ঠায় একাধিকবার ফোন করে ফাংশনটি কল করেন তবে এটি অতিরিক্ত অনুসন্ধান যুক্ত করে না।

স্বয়ংক্রিয় ক্যোয়ারী বিল্ডিং

@ স্টেফেনহারিস মন্তব্যগুলিতে যেমন উল্লেখ করেছেন, এসকিউএল ক্যোয়ারী তৈরির সময় একটি মূল ফাংশন কার্যকর হতে পারে: get_meta_sql()- কোডেক্সে উদাহরণ । মূলত এই ফাংশনটি কেবল ব্যবহৃত মেটা এসকিউএল স্টেটমেন্টটি তৈরি করতে ব্যবহৃত হয় WP_Queryতবে আপনি এটি এ ক্ষেত্রে (বা অন্যরাও) এটি ব্যবহার করতে পারেন। আপনি যে আর্গুমেন্টটি এতে ফেলেছেন তা হ'ল একটি অ্যারে, হুবহু একই যা যুক্ত করবে WP_Query

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

ফেরতের মানটি একটি অ্যারে:

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

সুতরাং আপনি $sql['join']এবং $sql['where']আপনার কলব্যাক ব্যবহার করতে পারেন ।

নির্ভরতা মাথায় রাখতে হবে

আপনার ক্ষেত্রে সবচেয়ে সহজ বিষয় হ'ল এটি একটি ছোট (মিউ) প্লাগইনে বা আপনার থিম ফাংশন.এফপি ফাইলের মধ্যে বাধা এবং পরিবর্তনশীল $adjacent = $previous ? 'previous' : 'next';এবং ভেরিয়েবলের উপর নির্ভর করে এটিকে $order = $previous ? 'DESC' : 'ASC';পরিবর্তন করা:

প্রকৃত ফিল্টার নাম

সুতরাং ফিল্টার নামগুলি হল:

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

একটি প্লাগইন হিসাবে আবৃত

... এবং ফিল্টার কলব্যাক (উদাহরণস্বরূপ) নিম্নলিখিতগুলির মতো কিছু হবে:

<?php
/** Plugin Name: (#73190) Alter adjacent post link sort order */
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' );

2
+1 টি। কেবল তথ্যের জন্য, (@ ম্যাগনাকাই) মেটা প্রশ্নের জন্য যদি এমন কিছু করে থাকেন তবে দেখুনget_meta_sql()
স্টিফেন হ্যারিস

আপনাকে +1 স্টেফেনহরিস! এটি আগে কখনও দেখেনি। সংক্ষিপ্ত প্রশ্ন: আমি উত্স থেকে পড়েছি যে আপনাকে একটি পুরোপুরি যোগ্য কোয়েরি অবজেক্টটি পাস করতে হবে, আপনি উল্লিখিত ফিল্টারগুলির সাথে এটি কীভাবে করবেন? যতদূর আমি দেখতে পাচ্ছি কেবল ক্যোয়ারী স্ট্রিংগুলি কেটে গেছে, ফিল্টারগুলির পরে কোয়েরি কার্যকর করা হয়।
কায়সার

2
না, $meta_queryকেবলমাত্র অ্যারেটি আপনি , যুক্তিটির WP_Queryজন্য যাবেন meta_query: উদাহরণস্বরূপ: $meta_sql = get_meta_sql( $meta_query, 'post', $wpdb->posts, 'ID');- এটি কোয়েরির JOINএবং WHEREঅংশটি তৈরি করে যা যুক্ত করা দরকার।
স্টিফেন হ্যারিস

@ স্টেফেনহরিস একটি উত্তর (আমার) সম্পাদনা করার জন্য সঠিক মুহূর্ত।
কায়সার

@ স্টেফেনহরিস, get_meta_sql () এর আউটপুট প্রয়োগ করতে আমার সমস্যা হচ্ছে - আপনি কি বিন্দুতে যোগ দিতে সাহায্য করতে পারেন?
Jodi ওয়ারেন

21

কায়সার এর উত্তর সন্ত্রস্ত এবং পুঙ্খানুপুঙ্খ, তবে শুধু দফা করে অর্ডার পরিবর্তন যথেষ্ট আপনার যদি না নয় menu_orderমিল আপনার কালানুক্রমিকভাবে।

আমি এর জন্য ক্রেডিট নিতে পারি না, তবে আমি এই লিস্টে নিম্নলিখিত কোডটি পেয়েছি :

<?php
/**
 * Customize Adjacent Post Link Order
 */
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' );

আমি ডাব্লুপিএসই জন্য ফাংশন নাম পরিবর্তন করেছি।

যদি আপনি কেবল অর্ডার বাই ক্লজটি পরিবর্তন করেন তবে ক্যোয়ারী এখনও বর্তমান পোস্টের চেয়ে বড় বা তার চেয়ে কম পোস্ট সন্ধান করবে। যদি আপনার পোস্টগুলি কালানুক্রমিকভাবে না থাকে তবে আপনি সঠিক পোস্ট পাবেন না।

অর্ডারব্লেজ ক্লজটি সংশোধন করার পাশাপাশি মেনু_র্ডারটি বর্তমান পোস্টের মেনু_আর্ডারের চেয়ে বড় বা কম যেখানে পোস্টগুলি সন্ধান করে সেখানে এটি সন্ধান করে।

অর্ডবাই ধারাটিও ডিইএসসি ব্যবহারের জন্য হার্ডকোড করা উচিত নয় কারণ আপনি পরবর্তী বা পূর্ববর্তী লিঙ্কটি পাচ্ছেন কিনা তার ভিত্তিতে এটি পরিবর্তন করতে হবে switch


3
একটি নোট: WHEREধারাটি সন্ধান করছে 'YYYY-mm-dd HH:mm:ss'। যদি এটি পূরণ না হয়, এটি কাজ করবে না। মানটি ডিবি দ্বারা নির্ধারিত নয়, তবে অ্যাপ্লিকেশন দ্বারা নিয়মিত এক্সপ্রেশন তৈরি করার সময় আপনাকে প্রথমে সেই বিন্যাসটি পরীক্ষা করতে হবে।
কায়সার

5

সাফল্য ছাড়া হুক ইন চেষ্টা। আমার কনফিগারেশনের সমস্যা হতে পারে তবে যারা হুককে কাজ করতে পারেন না তাদের পক্ষে এখানে সহজ সমাধান রয়েছে:

<?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; ?>

পেতে চেষ্টা কয়েক ঘন্টা পরে get_previous_post_where, get_previous_post_joinএবং get_previous_post_sortকাস্টম পোস্ট ধরনের এবং জটিল ক্রম যে মেটা কী-অন্তর্ভুক্ত সাথে খেলো চমৎকার, আমি ছেড়ে দিল এবং এই ব্যবহার করা হয়েছে। ধন্যবাদ!
স্কয়ারকাণ্ডি

এখানেও একইভাবে, আমি কেবল মেনু অর্ডার দ্বারা অর্ডার করতে চাইনি, তবে একটি নির্দিষ্ট মেটা_কি এবং মেটা_ভ্যালু সহ পোস্টগুলিও সন্ধান করেছি, সুতরাং এটি সেরা পদ্ধতি ছিল। আমি যে পরিবর্তনটি করেছি তা হ'ল এটি কোনও ফাংশনে আবৃত করা।
মিঃ কিরোট

4
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' );

1

@Szabolcs Pall এর উপর ভিত্তি করে উত্তর আমি সাহায্যকারী পদ্ধতির জন্য এই ইউটিলিটি বর্গ তৈরি করেছি মেনু আদেশ দ্বারা ধরনের পোস্ট পেতে এবং সেইসাথে মেনু আদেশ দ্বারা পরবর্তী এবং পূর্ববর্তী পোস্টে পেতে সক্ষম হবে। আমি অতিরিক্ত শর্ত যুক্ত করেছি যে যথাযথভাবে সর্বশেষ বা প্রথম পোস্ট পাওয়ার জন্য বর্তমান পোস্টটি প্রথম বা শেষ পোস্ট কিনা added

উদাহরণ স্বরূপ:

// $currentPost is first by menu order
getPreviousPostByMenuOrder($postType, $$currentPost->ID)
// returns => last post by menu order

// $currentPost is last by menu order
getPreviousPostByMenuOrder($postType, $$currentPost->ID)
// returns => first post by menu order

সম্পূর্ণ শ্রেণি:

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

}

0

আমি এই ছোট প্লাগইনটি সত্যিই সার্থক বলে মনে করি: http://wordpress.org/plugins/wp-query-powered-adjacent-post-link/

ডাব্লুপি_কিউরি চালিত অ্যাজাসেন্ট পোস্ট লিঙ্কটি বিকাশকারীদের জন্য একটি প্লাগইন। এটি wpqpapl();ওয়ার্ডপ্রেসে ফাংশন যুক্ত করে যা আগের এবং পরবর্তী পোস্টের তথ্য বর্তমানের কাছে ফিরিয়ে দিতে পারে। এটি WP_Queryক্লাসে ব্যবহারের জন্য যুক্তি গ্রহণ করে ।


0

এটি আমার পক্ষে কাজ করেছে:

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

থেকে নেওয়া: https://stackoverflow.com/questions/16495117/how-to-skip-certain-links-on-adjacent-posts-in-wordpress


-1

ফাংশন.এফপি পরিবর্তন করার প্রয়োজন ছাড়াই মেটা-কী ভিত্তিক পোস্ট নেভিগেশন অর্জনের জন্য আমি একটি আরও সহজ উপায় খুঁজে পেয়েছি।

আমার উদাহরণ: আপনার একটি product.php আছে এবং আপনি পণ্যগুলির মধ্যে স্যুইচ করতে চান। পূর্ববর্তী পণ্য পরবর্তী সস্তা এক, পরের পণ্য পরের আরও ব্যয়বহুল।

সিঙ্গেল.এফপি এর জন্য আমার সমাধানটি এখানে আসে :

<div class="post_navigation">

<?php

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

// Initialize array in which the IDs of ALL products posts will be stored
$posts = array();

// ... and now let's start the loop
while ( have_posts() ) : the_post();
$posts[] += $post->ID;
endwhile;

// Reset Query
wp_reset_query();

// Identify the position of the current product within the $posts-array 
$current = array_search(get_the_ID(), $posts);

// Identify ID of previous product
$prevID = $posts[$current-1];

// Identify ID of next product
$nextID = $posts[$current+1];

// Link "previous product"
if (!empty($prevID)) { ?>
<a href="/?p=<?php echo $prevID; ?>">previous product</a>
<?php }
// Link "next product"
if (!empty($nextID)) { ?>
<a href="/?p=<?php echo $nextID; ?>">next product</a>

<?php } ?>

এই উত্তরের জন্য -10। query_postsকোডেক্স যখন জানিয়েছে যে এটি ব্যবহার করা উচিত নয়, আপনি কীভাবে এটি ব্যবহার করছেন যদি এটি এর থেকে আরও ভাল সমাধান হতে পারে।
পিটার গুজন

কিন্তু এটি কাজ করে. তাহলে বিকল্পটি ডাব্লুপি_কিউয়ারি বা কী?
কেন্ট মিলার

হ্যাঁ, WP_Queryআগের উত্তরগুলির মতো ব্যবহার করা উচিত।
পিটার গুজন

1
@ কেন্টমিলার, কোডেক্স পৃষ্ঠায় একটি তথ্যবহুল চিত্র রয়েছে এবং আপনি এই প্রশ্নটি কার্যকর বলে মনে করতে পারেন। এই কনভেনশনগুলির সাথে নিজেকে পরিচিত করা ভাল।
জোদি ওয়ারেন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.