web-dev-qa-db-ja.com

現在のカテゴリが値の場合に選択されたオプション

私はこのサイトのカテゴリリストを作りたいです: https://premium.wpmudev.org/blog/

だから私はこのコードを作る:

<select class="select">
    <?php
    $args = array(
        'orderby' => 'name',
        'order'   => 'ASC'
    );
    $categories = get_categories($args);
    foreach ($categories as $cat) {
         echo '<option value="'.esc_url( get_category_link( $cat->term_id ) ).'" '.selected( esc_url( get_category_link( $cat->term_id ) ) ).'>'.$cat->name.'</option>';
    }
    ?>
</select>

コードは機能しており、選択したカテゴリリンクにリダイレクトされますが、カテゴリにリダイレクトした後でカテゴリ選択リスト内のカテゴリオプションが現在のカテゴリに変更されないという問題があります。

問題はここにあります:selected( esc_url( get_category_link( $cat->term_id ) )

しかし、私はそれを解決することはできません。

1
John

問題はselected()の使い方です。最初の引数が2番目の引数と一致する場合、その関数はselected="selected"を出力します。

それで、あなたがしていることは、次の場合にオプションを選択済みとしてマークすることです。

(string) 'https://premium.wpmudev.org/blog/category/news-community/' === (string) true

これは、値が文字列としてキャストされ、===と比較されるためです。URLが表示しているカテゴリと同じであっても、正しいことはありません。 関数 を見てください。これは、フードの下で使われています。

それで、あなたがする必要があるのは、現在のオプションが現在見られているカテゴリと同じであるかどうか調べることができるこの関数に値を渡すことです。比較を行うためのオプションとして、実際には実際のvalue属性を使用する必要はありません。各オプションはを表すなので、そのオプションのIDと現在表示されているカテゴリのIDを比較するだけで済みます。

したがって、現在のオプションのIDには$cat->term_idを、現在表示されているカテゴリのIDを取得するにはget_queried_object_id()を使用できます。ただし、重要な注意点の1つは、投稿を表示している場合はget_queried_object_id()が投稿IDも返すことです。投稿と用語は別々に保存されるため、カテゴリを表示していなくても一致する可能性があります。ですから、get_queried_object_id()を使う前に、自分がカテゴリを見ていることさえ確認してください。

これらすべてを適用すると、コードは次のようになります。

$categories = get_categories( array(
    'orderby' => 'name',
    'order'   => 'ASC'
) );

$current_category = is_category() ? get_queried_object_id() : false;

foreach ( $categories as $category ) {   
    printf(
        '<option value="%s" %s>%s</option>',
        esc_url( get_category_link( $category ) ),
        selected( $category->term_id, $current_category, false ),
        esc_html( $category->name )
    );
}

この行は、カテゴリを表示している限り、現在のカテゴリのIDを取得しています。

$current_category = is_category() ? get_queried_object_id() : false;

この行はselected()関数がどのように機能しているかです。

selected( $category->term_id, $current_category, false ),

上で定義したように、foreachループ内のカテゴリのIDを現在表示しているカテゴリと比較しています。最後の引数はfalseです。すでにエコーしているので、属性のテキストをreturnだけにします。

私があなたが使用する必要がないことを私が行ったいくつかの様式上の変更もあります、しかし私は私が説明するべきであると感じます:

  • 私は$categoryの代わりに$catを使いました。コードの略語は好きではありません。あなたがやりたいことができます。
  • 文字列を連結する代わりにprintf()を使いました。 <option>タグをこれらすべての値と連結すると、非常に長いコード行になる可能性があります。 printf()を使うことで、よりコンパクトで読みやすくなります(私の意見では)。
  • これをあなたはするべきですする:私はesc_html()でカテゴリの名前をエスケープしました。これは、カテゴリの名前が作成中のoptionタグのHTMLを壊すことができないようにするためです。
0
Jacob Peattie