如何通过可选的自定义字段或帖子标题对Wordpress帖子查询进行排序?

时间:2016-08-23 02:26:32

标签: php wordpress wordpress-theming custom-wordpress-pages

我想按昵称(可选自定义字段)按字母顺序对WP_query()的结果进行排序(如果有),姓氏(在帖子标题中),如果不是。

排序顺序:

  1. 如果他们有昵称,请使用它来排序。
  2. 如果他们不这样做,请使用他们的姓氏排序。
  3. 示例数据:

    Post 1
        Title: 'John Adams'
        Nickname: ''
    
    Post 2
        Title: 'Joe Car'
        Nickname: ''
    
    Post 3
        Title: 'John Earnest'
        Nickname: ''
    
    Post 4
        Title: 'James Water'
        Nickname: 'Bumblebee'
    
    Post 5
        Title: 'John Zebra'
        Nickname: 'Disco'
    

    期望的输出:

    在结构上与WP_query()的结果类似的对象/数组(我可以检查have_posts);已按此顺序发布的帖子

    1. John A dams
    2. John' B umblebee'水
    3. Joe C ar
    4. 詹姆斯' D isco'斑马
    5. John E arnest
    6. post_title是个人的名字和姓氏。

      该人的昵称custom_field_nickname有一个可选自定义字段。

      我想返回所有superhero类型的帖子(要么有昵称,要么没有)。 当前查询:

      $args = array( 'post_type' => 'superhero' );
      $query = new WP_Query( $args );
      

      目前我的功能是使用add_filter对这些帖子进行排序:

      function posts_orderby_lastname ($orderby_statement)
      {
        $orderby_statement = "RIGHT(post_title, LOCATE(' ', REVERSE(post_title)) - 1) ASC";
          return $orderby_statement;
      }
      

      如何修改该过滤器或以某种方式为我想要的过帐订单设置orderby选项?

3 个答案:

答案 0 :(得分:1)

使用以下代码来满足您的要求:

<?php
query_posts(array('post_type' => 'superhero'));
$names = array();
?>

<?php if ( have_posts() ) : ?>
<?php while (have_posts()) : the_post(); ?>
    <div id="lists">
    <ul>
    <?php
    // check whether custom field exist or not
    if (get_post_meta($post->ID, 'nick_name', true) ) { // custom field exist
        $explode = explode(' ',get_the_title()); // explode main title
        $nick = get_post_meta($post->ID, 'nick_name', true); // get nickname
        $names[] = $explode[0].' '.$nick.' '.$explode[1]; // form a name with Firstname Nickname LastName
    } else { // no custom field value
        $explode = explode(' ',get_the_title());  // explode main title
        $names[] = $explode[0].' '.$explode[1]; // Form a name with Firstname Lastname
    }
    ?>
    </ul>
    </div>
<?php endwhile; ?>
<?php endif; ?>
<?php wp_reset_query();?>

<?php
    /* Sort function to sort array */
    function cmp($a, $b)
    {
        $a = substr(strstr($a," "), 1);
        $b = substr(strstr($b," "), 1);
        return strcasecmp($a, $b);
    }

    uasort($names, "cmp");
    foreach ($names as $key => $value) {
        echo $value.'<br />';
    }
?>

答案 1 :(得分:0)

所以我最终这样做了:

// Build post queries
$query = new WP_Query($args);
// Extract post array from objects
$queryPosts = $query->posts;
// Custom sort each array according to "nickname"
usort($queryPosts, compare_the_posts);
// Replace old array of posts with newly sorted one
$query->posts = $queryPosts;

结合此自定义比较功能

// If a post has a specified "nickname", use that to sort with. If not, use the last word of the post title (last name)
function compare_posts($a, $b) {
    if (strlen($a->nick_name) > 0) {
        $a = $a->nick_name;
    } else {
        $a = last_word($a->post_title);
    }
    if (strlen($b->nick_name) > 0) {
        $b = $b->nick_name;
    } else {
        $b = last_word($b->post_title);
    }
  return strcasecmp($a, $b);
}

// (Helper function) Last word of a sentence
function last_word($str) {
    $last_word_pos = strrpos($str, ' ') + 1;
    $last_word = substr($str, $last_word_pos);
    return $last_word;
}

答案 2 :(得分:0)

希望这会对你有所帮助。

REQUEST:SELECT SQL_CALC_FOUND_ROWS  wp_posts.ID
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 = 'post'
   AND (wp_posts.post_status = 'publish')
   AND (wp_postmeta.meta_key = 'about_order'
   AND mt1.meta_key = 'job_title' )
GROUP BY wp_posts.ID
ORDER BY wp_postmeta.meta_value DESC
LIMIT 0, 12