问题出在这里,我认为有一个输入错误:
筛选器的名称为posts_fields
不post_fields
.
这可以解释为什么title2
字段未知,因为它的定义未添加到生成的SQL字符串中。
备选方案-单个过滤器
我们可以将其重写为仅使用单个过滤器:
add_filter( \'posts_orderby\', function( $orderby, \\WP_Query $q )
{
// Do nothing
if( \'_custom\' !== $q->get( \'orderby\' ) )
return $orderby;
global $wpdb;
$matches = \'The\'; // REGEXP is not case sensitive here
// Custom ordering (SQL)
return sprintf(
"
CASE
WHEN {$wpdb->posts}.post_title REGEXP( \'^($matches)[[:space:]]+\' )
THEN TRIM( SUBSTR( {$wpdb->posts}.post_title FROM %d ))
ELSE {$wpdb->posts}.post_title
END %s
",
strlen( $matches ) + 1,
\'ASC\' === strtoupper( $q->get( \'order\' ) ) ? \'ASC\' : \'DESC\'
);
}, 10, 2 );
现在,您可以使用激活自定义订购
_custom
orderby参数:
$args_post = array
\'post_type\' => \'release\',
\'orderby\' => \'_custom\', // Activate the custom ordering
\'order\' => \'ASC\',
\'posts_per_page\' => -1,
);
$loop = new WP_Query($args_post);
while ($loop->have_posts() ) : $loop->the_post();
备选方案-递归
TRIM()
让我们通过以下方式实现递归思想
Pascal Birchler,
commented here:
add_filter( \'posts_orderby\', function( $orderby, \\WP_Query $q )
{
if( \'_custom\' !== $q->get( \'orderby\' ) )
return $orderby;
global $wpdb;
// Adjust this to your needs:
$matches = [ \'the \', \'an \', \'a \' ];
return sprintf(
" %s %s ",
wpse_sql( $matches, " LOWER( {$wpdb->posts}.post_title) " ),
\'ASC\' === strtoupper( $q->get( \'order\' ) ) ? \'ASC\' : \'DESC\'
);
}, 10, 2 );
例如,我们可以将递归函数构造为:
function wpse_sql( &$matches, $sql )
{
if( empty( $matches ) || ! is_array( $matches ) )
return $sql;
$sql = sprintf( " TRIM( LEADING \'%s\' FROM ( %s ) ) ", $matches[0], $sql );
array_shift( $matches );
return wpse_sql( $matches, $sql );
}
这意味着
$matches = [ \'the \', \'an \', \'a \' ];
echo wpse_sql( $matches, " LOWER( {$wpdb->posts}.post_title) " );
将生成:
TRIM( LEADING \'a \' FROM (
TRIM( LEADING \'an \' FROM (
TRIM( LEADING \'the \' FROM (
LOWER( wp_posts.post_title)
) )
) )
) )
备选方案-MariaDB通常我喜欢使用MariaDB而不是MySQL。这样就容易多了,因为MariaDB 10.0.5
supports REGEXP_REPLACE
:
/**
* Ignore (the,an,a) in post title ordering
*
* @uses MariaDB 10.0.5+
*/
add_filter( \'posts_orderby\', function( $orderby, \\WP_Query $q )
{
if( \'_custom\' !== $q->get( \'orderby\' ) )
return $orderby;
global $wpdb;
return sprintf(
" REGEXP_REPLACE( {$wpdb->posts}.post_title, \'^(the|a|an)[[:space:]]+\', \'\' ) %s",
\'ASC\' === strtoupper( $q->get( \'order\' ) ) ? \'ASC\' : \'DESC\'
);
}, 10, 2 );