web-dev-qa-db-ja.com

カスタム投稿の姓でフィルタリングする方法

私はカスタムの投稿タイプ(講演者)を持っていて、姓でソートされた講演者のリストをロードしたいと思います。理解できないようです。私はこの記事からコードを試してみました: 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>';
?>

私が考えることができる最善は姓と呼ばれるカスタムメタフィールドを追加することであり、それによってソートしています、私は可能であればスピーカーの姓を2回入力する必要はありません。

投稿タイトルの2番目(そして最後)のWordで並べ替えるにはどうすればいいのですか?

3
rudtek

投稿タイトルの最後のWordで並べ替え

講演者の姓 で並べるには、次の設定を使用できます(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 );

これは 私のここでの答え /最後のWordによる用語の順序付けに基づいています。

7
birgire

受け入れられた答えはかなり脆くて、パラメータによる 順序の多くのバリエーションを扱うことができないでしょう

これはもう少し堅牢なフィルタです。

/**
 * 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);

基本的な使用法は次のとおりです(ただし、 パラメータによる/ - の順序のより複雑なバリエーションを受け入れます )。

$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 );
3
Dalin