使用下拉菜单按自定义字段数值对帖子进行排序

时间:2012-08-02 作者:user1571535

我读过无数与此非常相似的答案和问题,但我就是无法让它适用于我的具体情况。

我有一些属于“财产”类别的帖子。在里面category.php 我希望这些帖子最初以升序的日期顺序出现(按照通常的顺序)。

然后我想有一个下拉菜单,它提供了查看选项:

最新价格(默认)每个帖子都被分配了一个自定义字段“property\\u price”,这是一个数字值。我还需要分页才能工作。

首字母随此作为我的query_posts:

<?php
if ( have_posts() ) :
  $paged = ( get_query_var(\'paged\') ) ? get_query_var(\'paged\') : 1;
  $args = array(
     \'meta_key\' => \'property_price\',
     \'orderby\'  => \'meta_value_num\',
     \'order\'    => \'ASC\',
     \'paged\'    => $paged
  );
  query_posts( $args );
  while ( have_posts() ) :
    the_post();
这显然只是呈现了一个列表。然而,即使在这一点上,我也被困在了WordPress坚持这样排序:1、10、100、2、3,所以实际上并没有按正确的顺序排序。我想用\'orderby\' => \'meta_value_num\' 应该解决这个问题吗?

如果有人能帮忙,我将非常感激。对我温柔一点,我不是专家,所以很乐意接受傻瓜式的指示。

提前谢谢。

3 个回复
SO网友:gmazzap

\'meta_value_num\' 不是魔术,它将值转换为数字,但是,要正确转换为数字,值必须与数字兼容。

在OP中,据说字段值是“数字”的,但我敢打赌有些不是数字,例如货币符号,如“10$”或“10.00”,或其他符号,如“10-”。

还要考虑使用千分位分隔符很可能会导致转换失败,因为MySQL可能会将其误认为十进制分隔符。

如果要使用元字段进行排序,请遵循以下规则:

请勿使用任何其他非数字字符(无货币或其他符号,无空格…)如果您遵循之前的规则,则订单\'meta_value_num\' 将按预期工作。

如果您问自己如何正确设置使用以前规则输入的价格的格式,答案是number_format.

例如,在意大利,格式正确的价格是€ 1.000,50 (一千欧元五十美分)。

按照之前的规则,应将该价格输入为1000.50

要输出正确的格式化价格,可以使用如下自定义函数:

function formatted_price( $number ) {
    // force 2 decimals, comma as decimal separator and dot as thousands separator
    return \'&euro; \' . number_format ( (float) $number, 2, ",", "." );
}
并像这样使用它:

while ( have_posts() ) :
    the_post();

    if ( $price = get_post_meta( get_the_ID(), \'property_price\', TRUE ) ) {
        // assuming the price is stored in the \'property_price\' custom field
        echo formatted_price( $price );
    }
也就是说,I strongly suggest you avoid the usage of query_posts 并将其替换为\'pre_get_posts\'.

从…起Codex:

。。。它效率低下(重新运行SQL查询),并且在某些情况下会彻底失败(尤其是在处理POST分页时)。任何现代的WP代码都应该使用更可靠的方法,比如使用pre\\u get\\u posts钩子。

因此,请从category.php 在你的functions.php 写入:

add_action( \'pre_get_posts\', \'order_properties_by_price\' );

function order_properties_by_price( $query ) {
    if ( is_admin() || ! $query->is_main_query() || ! $query->is_category( \'property\' ) )
        return;
    $byprice = filter_input( INPUT_GET, \'orderby\', FILTER_SANITIZE_STRING ); 
    if ( empty( $byprice ) )
        return;
    if ( $byprice === \'price\' ) {
        $order = strtoupper( filter_input( INPUT_GET, \'order\', FILTER_SANITIZE_STRING ) ); 
        if ( $order !== \'DESC\' ) $order = \'ASC\';
        $query->set( \'meta_key\', \'property_price\' );
        $query->set( \'orderby\', \'meta_value_num\' );
        $query->set( \'order\', $order );
    }
}
现在,假设您的“属性”存档URL为

http://www.example.com/category/property/
当然,它将显示“属性”类别中按日期排序的帖子(从新到旧)。

使用上面发布的代码,URL

http://www.example.com/category/property/?orderby=price
将按价格和URL升序显示“property”类别中的帖子

http://www.example.com/category/property/?orderby=price&order=DESC
将按价格降序显示“属性”类别中的帖子。

因此,您需要做的是,创建一个下拉列表,将页面重定向到正确的URL。

您可以编写自定义函数来输出下拉列表:

function order_properties_menu() {
    if ( ! is_category(\'property\') ) return;
    $url = get_category_link( get_term_by( \'slug\', \'property\', \'category\' ) );
    $form = \'<form id="orderbyprice" action="#" method="GET">\'
        . \'<label>Order by:</label><select name="order">\';
    $htl = esc_url( add_query_arg( array( \'orderby\' => \'price\', \'order\' => \'DESC\' ), $url ) ) ;
    $lth = esc_url( add_query_arg( array(\'orderby\' => \'price\', \'order\' => \'ASC\' ), $url ) );
    $options = array(
        \'latest\' => array( \'Latest\', $url ),
        \'htl\'    => array( \'Price High to Low\', $htl ),
        \'lth\'    => array( \'Price Low to High\', $lth ) 
    );
    $format = \'<option value="%s"%s>%s</option>\';
    foreach( $options as $id => $option ) {
        $sel = \'latest\';
        if ( get_query_var( \'orderby\' ) === \'meta_value_num\' )
            $sel = get_query_var( \'order\' ) === \'DESC\' ? \'htl\' : \'lth\';
        $selected = selected( $sel, $id, FALSE );
        $form .= sprintf( $format, esc_url( $option[1] ), $selected, esc_html( $option[0] ) );
    }
    echo $form . \'</select></form>\';
    ?>
    <script>
        jQuery(document).on( \'change\', \'#orderbyprice select\', function() {
            window.location.href = jQuery(this).val();
        });
    </script>
    <?php
}
此功能输出一个下拉菜单,允许用户从3个订购选项中进行选择,当选择其中一个选项时,页面将相应重定向。

在中添加此函数后functions.php, 把它放在你的category.php

order_properties_menu();
将显示select(选择)。

请注意order_properties_menu() 函数需要jQuery。

SO网友:Fränk

你正在以一种不太理想的方式做一些事情。下面是如何解决您的问题。

1. Create a category-property.php template file

在此文件中粘贴标准WordPress循环。如果您访问站点中的属性类别,您应该只看到该类别中的帖子,按日期排序(从最新到最旧)。

通过使用模板层次结构(http://codex.wordpress.org/Template_Hierarchy), 我们现在有了一个页面,可以显示我们想要的帖子。

如果安装调试栏插件(http://wordpress.org/extend/plugins/debug-bar/) 您可以验证category-property.php 用于此查询。

2. Modify the main query via the pre_get_posts filter

如果您使用query_posts(), 这会对主查询运行额外的查询,这不仅浪费资源,还会导致分页不工作等大量问题。。

所以我们要做的是编写一个函数(需要functions.php) 这会改变特定页面上的主查询,以按照我们想要的顺序进行排序。

function my_prefix_sort_property_category( $query ) {
    // if we\'re not in the admin, and it\'s the main query, and it\'s a property category
    if ( ! is_admin() && $query->is_main_query() && is_category( \'Property\' ) ) {
        // then modify the main query
        $query->set( \'meta_key\', \'property_price\' );
        $query->set( \'orderby\', \'meta_value_num\' );
        $query->set( \'order\', \'ASC\' );
    }
}
add_action( \'pre_get_posts\', \'my_prefix_sort_property_category\' );

SO网友:user1576978

我曾经遇到过这个问题,我相信您的自定义域没有设置为INT,对吗?对于meta\\u value\\u num work,它应该是INT,而不是string,即使您只在其中写入数字

结束

相关推荐

Order posts by date

我是一个女孩,请原谅我的英语。也许这很容易,但我却不知道这一点。但问题是我想在主页上输出最近3天的帖子。像这样:30/03/12 职位1职位2岗位329/03/12 职位1职位2岗位328/03/12 职位1职位2岗位3我试过:$loopday = \'\'; if ( have_posts() ) : while ( have_posts() ) : the_post(); if ($loopday !== get_the_time(\'D M j\')