我有一个自定义的帖子类型(演讲者),我想加载按姓氏排序的演讲者列表。我似乎想不出来。我尝试了以下帖子中的代码:https://stackoverflow.com/questions/16416217/wordpress-orderby-last-word-in-title
但它似乎不起作用。
add_action( \'init\', \'create_post_type\' );
function create_post_type() {
register_post_type( \'event\',
array(
\'labels\' => array(
\'name\' => __( \'Conferences\' ),
\'singular_name\' => __( \'Conference\' )
),
\'public\' => true,
\'has_archive\' => true,
\'supports\' => array(\'title\',\'editor\',\'thumbnail\'),
)
);
register_post_type( \'speaker\',
array(
\'labels\' => array(
\'name\' => __( \'Speakers\' ),
\'singular_name\' => __( \'Speaker\' )
),
\'public\' => true,
\'has_archive\' => true,
\'supports\' => array(\'title\',\'editor\',\'thumbnail\'),
)
);
register_post_type( \'sponsor\',
array(
\'labels\' => array(
\'name\' => __( \'Sponsors\' ),
\'singular_name\' => __( \'Sponsor\' )
),
\'public\' => true,
\'has_archive\' => true,
\'supports\' => array(\'title\',\'editor\',\'thumbnail\'),
)
);
register_post_type( \'venue\',
array(
\'labels\' => array(
\'name\' => __( \'Venues\' ),
\'singular_name\' => __( \'Venue\' )
),
\'public\' => true,
\'has_archive\' => true,
\'supports\' => array(\'title\',\'editor\',\'thumbnail\'),
)
);
register_post_type( \'session\',
array(
\'labels\' => array(
\'name\' => __( \'Sessions\' ),
\'singular_name\' => __( \'Session\' )
),
\'public\' => true,
\'has_archive\' => true,
\'supports\' => array(\'title\',\'editor\',\'thumbnail\'),
)
);
}
我调用自定义帖子类型的代码是:
<?php
// args
$args = array(
\'numberposts\' => -1,
\'post_type\' => \'speaker\',
\'meta_key\' => \'speaker-front-page\',
\'meta_value\' => \'1\',
\'orderby\' => \'speaker_last_name\',
\'order\' => \'ASC\'
);
// query
add_filter( \'posts_orderby\' , \'posts_orderby_lastname\' );
$the_query = new WP_Query( $args );
?>
<?php if( $the_query->have_posts() ): ?> <div id="speakerrow"><h1>SPEAKERS<h1><hr>
<?php while( $the_query->have_posts() ) : $the_query->the_post();
echo \'<div class="flex_column av_one_third flex_column_div">\';
echo do_shortcode("[av_image src=\'". get_field(\'speaker-photo\')."\' attachment=\'\' attachment_size=\'full\' align=\'center\' animation=\'pop-up\' styling=\'\' hover=\'av-hover-grow\' link=\'".get_the_permalink()."\' target=\'\' caption=\'\' font_size=\'\' appearance=\'\' overlay_opacity=\'0.4\' overlay_color=\'#000000\' overlay_text_color=\'#ffffff\'][/av_image]" );
echo do_shortcode("[av_heading tag=\'h2\' padding=\'10\' heading=\'". get_the_title()."\' color=\'\' style=\'blockquote modern-quote modern-centered\' subheading_active=\'subheading_below\' subheading_size=\'15\']". get_field(\'speaker-company\')."[/av_heading]");
echo \'</div>\';
?>
我所能想到的最好方法是添加一个名为last name的自定义元字段,并以此排序,如果可能的话,我喜欢不必键入两次说话者的姓氏。
如何添加order by字段以按文章标题中的第二个(也是最后一个)单词排序?
最合适的回答,由SO网友:birgire 整理而成
按文章标题中的最后一个单词排序要按说话者的姓氏排序,可以使用以下设置(PHP 5.4+):
// args
$args = [
\'posts_per_page\' => 10,
\'post_type\' => \'speaker\',
\'meta_key\' => \'speaker-front-page\',
\'meta_value\' => \'1\',
\'orderby\' => \'wpse_last_word\', //<-- Our custom ordering!
\'order\' => \'ASC\'
];
// query
$the_query = new WP_Query( $args );
其中
\'wpse_last_word\'
以下各项支持输入:
/**
* Order posts by the last word in the post_title.
* Activated when orderby is \'wpse_last_word\'
* @link https://wordpress.stackexchange.com/a/198624/26350
*/
add_filter( \'posts_orderby\', function( $orderby, \\WP_Query $q )
{
if( \'wpse_last_word\' === $q->get( \'orderby\' ) && $get_order = $q->get( \'order\' ) )
{
if( in_array( strtoupper( $get_order ), [\'ASC\', \'DESC\'] ) )
{
global $wpdb;
$orderby = " SUBSTRING_INDEX( {$wpdb->posts}.post_title, \' \', -1 ) " . $get_order;
}
}
return $orderby;
}, PHP_INT_MAX, 2 );
这是基于
my answer here 按最后一个词排序。
SO网友:Dalin
The accepted answer is pretty brittle and won\'t be able to handle the many variations of the order by parameters.
Here\'s a filter that should be a little more robust:
/**
* Order posts by the last word in the post_title.
* Activated when orderby is \'wpse_last_word\'
* @link http://wordpress.stackexchange.com/a/198624/26350
*/
add_filter(\'posts_orderby\', function($orderby_sql, \\WP_Query $q) {
$orderbys = $q->get(\'orderby\');
if (!$orderbys) {
return;
}
if ($orderby_sql) {
$orderby_sql_array = [$orderby_sql];
}
else {
$orderby_sql_array = [];
}
if (!is_array($orderbys)) {
$words = explode(\' \', $orderbys);
$orderbys = [];
foreach ($words as $word) {
$orderbys[$word] = $q->get(\'order\');
}
}
global $wpdb;
foreach ($orderbys as $orderby => $direction) {
if ($orderby == \'wpse_last_word\') {
if (!$direction || !in_array(strtoupper($direction), [\'ASC\', \'DESC\'])) {
$direction = \'DESC\';
}
$orderby_sql_array[] = "SUBSTRING_INDEX({$wpdb->posts}.post_title, \' \', -1) $direction";
}
}
return implode(\', \', $orderby_sql_array);
}, 100, 2);
The basic usage is (but it will accept more complex variations of the order by parameters):
$args = [
\'posts_per_page\' => 10,
\'post_type\' => \'speaker\',
\'meta_key\' => \'speaker-front-page\',
\'meta_value\' => \'1\',
\'orderby\' => \'wpse_last_word\',
\'order\' => \'ASC\'
];
$the_query = new WP_Query( $args );