質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.13%

WordPress:50音順に見出し付きで表示させたい(固定ページに)

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 250

score 4

WPのカスタム投稿で、会社名リスト一覧を固定ページで出力し
50音順に見出し付きで表示させたいのですが、うまくいきません。。

参考
http://creatornote.nakweb.com/title_abc/
https://hp-maruwakari.com/wp-aiueo/

上記のような例です。
PHP、WP初学者で、教えていただけると大変ありがたいです。

<article id="article" class="clearfix">

            <?php
            $furigana = 'kana'; // acfのフィールド名

            $en_abcd = "/[abcd]/";
            $en_efgh = "/[efgh]/";
            $en_ijkl = "/[ijkl]/";
            $en_mnop = "/[mnop]/";
            $en_qrst = "/[qrst]/";
            $en_uvwxyz = "/[uvwxyz]/";

            $jp_agyo = "/[あいうえお]/";
            $jp_kagyo = "/[かきくけこがぎぐげご]/";
            $jp_sagyo = "/[さしすせそざじずぜぞじゃじゅじょ]/";
            $jp_tagyo = "/[たちつてとだぢづでど]/";
            $jp_nagyo = "/[なにぬねの]/";
            $jp_hagyo = "/[はひふへほばびぶべぼぱぴぷぺぽびゅ]/";
            $jp_magyo = "/[まみむめも]/";
            $jp_yagyo = "/[やゆよ]/";
            $jp_ragyo = "/[らりるれろ]/";
            $jp_wagyo = "/[わをん]/";

            $mojilist = array($en_abcd,$en_efgh,$en_ijkl,$en_mnop,$en_qrst,$en_uvwxyz,$jp_agyo,$jp_kagyo,$jp_sagyo,$jp_tagyo,$jp_nagyo,$jp_hagyo,$jp_magyo,$jp_yagyo,$jp_ragyo,$jp_wagyo);
            $mojilabel = array("A-D","E-H","I-L","M-P","Q-T","U-Z","あ行","か行","さ行","た行","な行","は行","ま行","や行","ら行","わ行");

            $args = array(
            'post_type' => 'suppliers', //カスタム投稿タイプ名
            'posts_per_page' => -1, // 表示件数
            'meta_key' => $furigana, // カスタムフィールドキー
            'orderby' => 'meta_value', // meta_valueの値で並べる
            'order' => 'ASC', // 昇順で順序付け
            ); 

            $wp_query = new WP_Query($args);

            $i = 0;

            if( $wp_query->have_posts()): while ( $wp_query->have_posts() ): $wp_query->the_post();

            $first_word = the_field($furigana);
            $first_word = mb_substr($first_word, 0, 1);
            foreach ($mojilist as $value):
                if(strpos($value, $first_word)):
                //見出しをつける
                $arrayindex = array_search($value, $mojilist);
                if($i == 0){
                    //最初のみ
                    echo  '<h2>'. $mojilabel[$arrayindex] .'</h2><ul>';
                    ${"count".$arrayindex} = ${"count".$arrayindex} + 1;
                    $i = $i + 1;
                }else{
                    if(${"count".$arrayindex} == 0){
                    echo  '</ul><h2>'. $mojilabel[$arrayindex] .'</h2><ul>';
        }
        ${"count".$arrayindex} = ${"count".$arrayindex} + 1;
      }
            ?>
            <ul>
                <li><a href="<?php the_field('url'); ?>"><?php the_title(); ?></a><span><?php the_field($furigana) ?></span></li>
                <?php endif; endforeach;  endwhile; ?>
            </ul><?php if ( $wp_query->have_posts() ): ?></ul><?php endif; ?>            
<?php endif; ?>

        </article><!-- END #article -->
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • CHERRY

    2021/01/07 06:48

    > うまくいきません。

    では、状況がわかりませんので、

    - 画面に何かメッセージは表示されますか? 
    - Webブラウザのデベロッパーツールには何か表示されていますか?
    - WebサーバーやPHPのログには何か記録されていますか?
    等々
    発生している内容を具体的に記載して、どのような状態になっているのかを具体的に書いていただけないでしょうか。

    キャンセル

  • nddf

    2021/01/07 11:48

    すみません。
    <article>...</article>が表示されないです。

    キャンセル

  • nddf

    2021/01/09 16:17

    ```ここに言語を入力
    コード
    ```

    キャンセル

回答 2

+1

$jp_agyo = "/[あいうえお]/";みたいに正規表現で各条件を書いてるのに
if(strpos($value, $first_word)):と単純な文字列検索で判定してる
使うならpreg_matchです

ついでにリファクタリング的なこと

わざわざarray_searchしなくてもforeachでインデックスは取れます

foreach ($mojilist as $value):
                ...略
                $arrayindex = array_search($value, $mojilist);
↓
foreach ($mojilist as $arrayindex=>$value):
                ...略

投稿がソートされているなら既に出力済みの行の判定は必要ないはずです
「現在出力中の行とマッチしているか」を判定し
「マッチしなかったら次の行の条件で判定」というやり方の方が
${"count".$arrayindex}みたいな変数を作る必要もなく
シンプルで処理が少なく済むはずです

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2021/01/07 12:15

    KazuhiroHatanoさま

    ありがとうございます。
    書き方がわかっておらず、苦労してます。
    preg_matchを調べてみました。


    https://deco8.net/web/how-to-list-custom-posts-in-alphabetical-order/
    こちらの書き方がそうなのかなと思うんですが、
    こちらはアルファベットA-Zで並べてるので
    これの50音順版をつくりたいです。
    そもそもがわかっていないのでどうカスタマイズしていいのか。。。すみません。

    キャンセル

  • 2021/01/07 12:43

    正規表現は読めないなら使わない方がいいですし
    preg_matchは公式のヒントでも書いてますが
    使わないでできることなら使わない方がいいです

    https://www.php.net/manual/ja/function.preg-match.php

    やろうとしてることは正規表現を使わなくてもできるので
    $mojilistを正規表現パターンにせず普通の文字列にして
    strposで判定する形にしましょう

    公式に書かれている通りstrposは0を返すことがあるので
    判定は!==falseで厳密にしなくてはダメです

    https://www.php.net/manual/ja/function.strpos.php

    キャンセル

  • 2021/01/09 16:24

    ありがとうございます!
    参考になりました。まだまだ全然書けないので
    もっと勉強してみます。

    キャンセル

check解決した方法

0

ありがとうございました。
色々と調べて、functions.phpに書いてショートコードで出力する方法で
なんとかなりました。

function yomilistFunc($atts)
{
  // インデックス(行)
  $indexes_parents = array(
    "あ行" => "[ア-オ]",
    "か行" => "[カ-コ]",
    "さ行" => "[サ-ソ]",
    "た行" => "[タ-ト]",
    "な行" => "[ナ-ノ]",
    "は行" => "[ハ-ホ]",
    "ま行" => "[マ-モ]",
    "や行" => "[ヤ-ヨ]",
    "ら行" => "[ラ-ロ]",
    "わ行" => "[ワ-ン]",
    "その他" => ".*"
  );
  // インデックス(50音)
  $indexes = array(
    "ア" => "[ア]", "イ" => "[イ]", "ウ" => "[ウ]", "エ" => "[エ]", "オ" => "[オ]",
    "カ" => "[カ]", "キ" => "[キ]", "ク" => "[ク]", "ケ" => "[ケ]", "コ" => "[コ]",
    "サ" => "[サ]", "シ" => "[シ]", "ス" => "[ス]", "セ" => "[セ]", "ソ" => "[ソ]",
    "タ" => "[タ]", "チ" => "[チ]", "ツ" => "[ツ]", "テ" => "[テ]", "ト" => "[ト]",
    "ナ" => "[ナ]", "ニ" => "[ニ]", "ヌ" => "[ヌ]", "ネ" => "[ネ]", "ノ" => "[ノ]",
    "ハ" => "[ハ]", "ヒ" => "[ヒ]", "フ" => "[フ]", "ヘ" => "[ヘ]", "ホ" => "[ホ]",
    "マ" => "[マ]", "ミ" => "[ミ]", "ム" => "[ム]", "メ" => "[メ]", "モ" => "[モ]",
    "ヤ" => "[ヤ]", "ユ" => "[ユ]", "ヨ" => "[ヨ]",
    "ラ" => "[ラ]", "リ" => "[リ]", "ル" => "[ル]", "レ" => "[レ]", "ロ" => "[ロ]",
    "ワ" => "[ワ]", "ン" => "[ン]",
    "その他" => ".*"
  );
  global $post;
  // 記事データを取得
  // 記事の取得条件
  $args = array(
    'posts_per_page' => '-1', // 取得記事数無制限
    'post_type' => 'suppliers',
    'post_status' => 'publish', // 公開中
    'meta_key' => 'yomi', // カスタムフィールドyomiを持っている記事
    'meta_value' => '', // カスタムフィールドyomiの値は指定しない
    'orderby' => 'meta_value', // カスタムフィールドyomiの値を基準に並び替え
    'order' => 'asc' // 昇順に並び替え
  );
  $my_posts = get_posts($args); // 上記条件で記事を取得
  $post_data_set = array(); // 配列$post_data_setを用意
  // 上記条件の投稿があるなら
  if ($my_posts) {
    foreach ($my_posts as $post) : // ループスタート
      setup_postdata($post); // get_the_title() などのテンプレートタグを使えるようにする
      // ヨミガナの1文字目を取得する(濁点、半濁点は分離)
      $yomi = get_post_meta($post->ID, 'yomi', true); // カスタムフィールドyomiの値を取得
      $yomi_conv = mb_convert_kana($yomi, 'k', 'UTF-8'); // 全角カタカナを半角カタカナに変換(濁点、半濁点を分離)
      $yomi_conv = mb_convert_kana($yomi_conv, 'K', 'UTF-8'); // 半角カタカナを全角カタカナに変換
      $yomi_first = mb_substr($yomi_conv, 0, 1); // 先頭の1文字を取得
      // 配列に格納する
      $posts['title'] = get_the_title(); // タイトル
      $posts['permalink'] = get_permalink(); // URL
      $posts['yomi'] = $yomi; // ヨミガナ
      $posts['yomi_first'] = $yomi_first; // ヨミガナ1文字目
      $post_data_set[] = $posts; // 配列に格納
    endforeach; // ループ終わり
  }
  // インデックス(50音)ごとの配列に格納する
  $post_data_set_index = array();
  foreach ($post_data_set as $key => $val) {
    $char = mb_substr($val['yomi_first'], 0, 1);
    foreach ($indexes as $index => $pattern) {
      if (preg_match("/^" . $pattern . "/u", $char)) {
        $post_data_set_index[$index][] = $post_data_set[$key];
        break;
      }
    }
  }
  // インデックス(行)ごとの配列に格納する
  $post_data_set_index_parent = array();
  foreach ($post_data_set_index as $key => $val) {
    foreach ($indexes_parents as $indexes_parent => $patterns) {
      if (preg_match("/^" . $patterns . "/u", $key)) {
        $post_data_set_index_parent[$indexes_parent][$key] = $post_data_set_index[$key];
        break;
      }
    }
  }
  // HTML出力
  $output = "";
  if ($post_data_set_index_parent) {
    // 行ごとに展開
    foreach ($post_data_set_index_parent as $indexes_parent => $posts) : // ループスタート
      $output .= '<h2>' . $indexes_parent . '</h2>';
      // 50音ごとに展開
      foreach ($posts as $index => $post) : // ループスタート
        $output .= '<h3>' . $index . '</h3>';
        $output .= '<ul>' . "\n";
        foreach ($post as $key => $val) {
          $output .= '<li>';
          $output .= '<a href="' . $val['permalink'] . '">' . $val['title'] . '</a>';
          $output .= '</li>' . "\n";
        }
        $output .= '</ul>' . "\n";
      endforeach; // ループ終わり
    endforeach; // ループ終わり
  }
  // クエリのリセット
  wp_reset_postdata();
  return $output;
}
add_shortcode('yomilist', 'yomilistFunc');

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.13%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る