如何对“query_posts”进行排序通过自定义字段功能,同时通过另一个自定义字段限制帖子

发布于 2024-10-01 01:49:09 字数 682 浏览 1 评论 0原文

我正在使用以下功能查询 WP 中的一系列帖子:

<?php 
$thirtydays = date('Y/m/d', strtotime('+30 days'));
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
query_posts( array( 
    'post_type' => array('post', 'real-estate'), 
    'meta_key' => 'Time          Available', 
    'meta_compare' => '<=', 
    'meta_value' => $thirtydays, 
    'paged' => $paged )); 
?>

这部分工作正常。它基本上会提取我所有的房地产帖子,但只返回“可用时间”为 30 天或更短的结果。

我还需要使用另一个自定义字段“价格”中的数据按从低到高的升序对帖子进行排序。

每当我添加标准 'orderby' =>; 'meta_value', 'meta_key' =>; “价格” 30 天内不再显示结果。

有什么办法可以将这两者结合起来吗?是否可以添加一个按钮来重新运行查询并按价格、卧室等排序?或者这对 WP 来说太具体了?

I'm querying a series of posts in WP with the following function:

<?php 
$thirtydays = date('Y/m/d', strtotime('+30 days'));
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
query_posts( array( 
    'post_type' => array('post', 'real-estate'), 
    'meta_key' => 'Time          Available', 
    'meta_compare' => '<=', 
    'meta_value' => $thirtydays, 
    'paged' => $paged )); 
?>

This part is working fine. It's basically pulling all my Real Estate posts, but only returning results that have a 'Time Available' of 30 days or less.

I need this to also order the posts in ascending order from low to high using the data from another custom field, 'Price.'

Whenever I add the standard 'orderby' => 'meta_value', 'meta_key' => 'Price' it no longer shows results within 30 days.

Is there any way I can combine these two? And is it possible to add a button which re-runs the query and sorts by Price, Bedrooms, etc? Or is this too specific for WP?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

蓝颜夕 2024-10-08 01:49:09

我相信这会提供您想要的您所需要的。这是一个名为 PostsOrderedByMetaQuery 的类,它扩展了 WP_Query 并接受新参数 'orderby_meta_key' 和 'orderby_order'

class PostsOrderedByMetaQuery extends WP_Query {
  var $posts_ordered_by_meta = true;
  var $orderby_order = 'ASC';
  var $orderby_meta_key;
  function __construct($args=array()) {
    add_filter('posts_join',array(&$this,'posts_join'),10,2);
    add_filter('posts_orderby',array(&$this,'posts_orderby'),10,2);
    $this->posts_ordered_by_meta = true;
    $this->orderby_meta_key = $args['orderby_meta_key'];
    unset($args['orderby_meta_key']);
    if (!empty($args['orderby_order'])) {
      $this->orderby_order = $args['orderby_order'];
      unset($args['orderby_order']);
    }
    parent::query($args);
  }
  function posts_join($join,$query) {
    if (isset($query->posts_ordered_by_meta)) {
      global $wpdb;
      $join .=<<<SQL
INNER JOIN {$wpdb->postmeta} postmeta_price ON postmeta_price.post_id={$wpdb->posts}.ID
       AND postmeta_price.meta_key='{$this->orderby_meta_key}'
SQL;
    }
    return $join;
  }
  function posts_orderby($orderby,$query) {
    if (isset($query->posts_ordered_by_meta)) {
      global $wpdb;
      $orderby = "postmeta_price.meta_value {$this->orderby_order}";
    }
    return $orderby;
  }
}

您会像这样调用它:

$thirtydays = date('Y/m/d', strtotime('+30 days'));
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$query = new PostsOrderedByMetaQuery(array(
  'post_type' => array('post', 'real-estate'),
  'meta_key' => 'Time Available',
  'meta_compare' => '<=',
  'meta_value' => $thirtydays,
  'paged' => $paged,
  'orderby_meta_key' => 'Price',
  'orderby_order'    => 'DESC',
));
foreach($query->posts as $post) {
  echo " {$post->post_title}\n";
}

您可以将 PostsOrderedByMetaQuery 类复制到主题的 functions.php 文件中,也可以在 .php 文件中使用它您可能正在编写的插件的。

如果您想快速测试它,我已经发布了代码的独立版本 到 Gist,您可以将其下载并以 test.php 的形式复制到 Web 服务器的根目录,根据您的用例进行修改,然后使用 http 之类的 URL 从浏览器发出请求: //example.com/test.php

希望这有帮助。

-迈克

P.S.这个答案是与我刚刚在 WordPress Answers 上给出的答案非常相似,这是 StackOverflow 的姐妹网站,很多像我这样的 WordPress 爱好者每天都会回答问题。您可能想看到也回答,因为它有更多的解释,并且因为您可能想查看WordPress 答案。希望您将来也考虑在 那里 发布您的 WordPress 问题?

I believe this will provide you want you need. It's a class called PostsOrderedByMetaQuery that extends WP_Query and accepts new arguments 'orderby_meta_key' and 'orderby_order':

class PostsOrderedByMetaQuery extends WP_Query {
  var $posts_ordered_by_meta = true;
  var $orderby_order = 'ASC';
  var $orderby_meta_key;
  function __construct($args=array()) {
    add_filter('posts_join',array(&$this,'posts_join'),10,2);
    add_filter('posts_orderby',array(&$this,'posts_orderby'),10,2);
    $this->posts_ordered_by_meta = true;
    $this->orderby_meta_key = $args['orderby_meta_key'];
    unset($args['orderby_meta_key']);
    if (!empty($args['orderby_order'])) {
      $this->orderby_order = $args['orderby_order'];
      unset($args['orderby_order']);
    }
    parent::query($args);
  }
  function posts_join($join,$query) {
    if (isset($query->posts_ordered_by_meta)) {
      global $wpdb;
      $join .=<<<SQL
INNER JOIN {$wpdb->postmeta} postmeta_price ON postmeta_price.post_id={$wpdb->posts}.ID
       AND postmeta_price.meta_key='{$this->orderby_meta_key}'
SQL;
    }
    return $join;
  }
  function posts_orderby($orderby,$query) {
    if (isset($query->posts_ordered_by_meta)) {
      global $wpdb;
      $orderby = "postmeta_price.meta_value {$this->orderby_order}";
    }
    return $orderby;
  }
}

You would call it like this:

$thirtydays = date('Y/m/d', strtotime('+30 days'));
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$query = new PostsOrderedByMetaQuery(array(
  'post_type' => array('post', 'real-estate'),
  'meta_key' => 'Time Available',
  'meta_compare' => '<=',
  'meta_value' => $thirtydays,
  'paged' => $paged,
  'orderby_meta_key' => 'Price',
  'orderby_order'    => 'DESC',
));
foreach($query->posts as $post) {
  echo " {$post->post_title}\n";
}

You can copy the PostsOrderedByMetaQuery class to your theme's functions.php file, or you can use it within a .php file of a plugin you may be writing.

If you want to test it quickly I've posted a self-contained version of the code to Gist which you can download and copy to your web server's root as test.php, modify for your use case, and then request from your browser using a URL like http://example.com/test.php.

Hope this helps.

-Mike

P.S. This answer is very similar to an answer I just gave over at WordPress Answers, which is the sister site of StackOverflow where lots of WordPress enthusiasts like me answer questions daily. You might want to see that answer too because it has a tad more explanation and because you might want to see WordPress Answers. Hope you'll consider posting your WordPress questions over there too in the future?

云裳 2024-10-08 01:49:09

因为 'orderby' => 'meta_value' 需要 meta_key,并且您的 meta_key 已用于比较,我认为您无法执行此操作。 meta_key 仅接受单个值,而不接受选项数组。这绝对是一个限制,如果您找不到解决方案,我鼓励您提出请求。

至于重新运行查询的按钮,您只需重新加载页面并传递查询变量即可更改排序。不幸的是,您仍然需要解决问题的第一部分。

更新

您始终可以使用 PHP 自己对返回的数组进行排序。

另外,不确定您在可用时间内检查什么,但您可以注册一个过滤器,它可以帮助您进一步自定义查询 add_filter('posts_where', ...); http://codex.wordpress.org/Function_Reference/query_posts

Because 'orderby' => 'meta_value' requires meta_key, and your meta_key is already in use for a comparison, I don't think you can do this. meta_key only accepts a single value and not an array of options. This is definitely a limitation and I encourage you to open a request if you don't find a solution.

As far as the button to re-run the query, you could simply reload the page and pass a query variable to change the sort. Unfortunately you still have to solve the first part of your question.

UPDATE

You could always sort the returned array yourself using PHP.

Also, not sure what you are checking with time available but you could register a filter that may help you customize the query a bit further add_filter('posts_where', ...); http://codex.wordpress.org/Function_Reference/query_posts

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文