0

Background: I'm working on a gaming blog, and I've created a custom taxonomy for Games.

I've added a Game List page which will (unsurprisingly) list all the non-empty terms within that taxonomy. Knowing that this list could get rather large in the future, I want to sort and group terms by their first character with a quick access bar at the top of the page and a "back to top" link at the end of each section.

I've come up with the following function to retrieve the sorted list, and it works perfectly, but I'm wondering if there is a more efficient way to pull this off (like some core option I haven't discovered yet).

function bmg_getGameList() {
    $games = get_terms(BMG_GAME_SLUG, true);

    if ($games && !is_wp_error($games)) {
        $gameList = array(
            "#" =>  array(),    "A" =>  array(),    "B" =>  array(),
            "C" =>  array(),    "D" =>  array(),    "E" =>  array(),
            "F" =>  array(),    "G" =>  array(),    "H" =>  array(),
            "I" =>  array(),    "J" =>  array(),    "K" =>  array(),
            "L" =>  array(),    "M" =>  array(),    "N" =>  array(),
            "O" =>  array(),    "P" =>  array(),    "Q" =>  array(),
            "R" =>  array(),    "S" =>  array(),    "T" =>  array(),
            "U" =>  array(),    "V" =>  array(),    "W" =>  array(),
            "X" =>  array(),    "Y" =>  array(),    "Z" =>  array(),
        );

        foreach($games as $game) {
            $normalizedTitle = strtoupper($game->name);
            $normalizedTitle = preg_replace("/^THE ",'', $normalizedTitle,1);

            /* NOTE:    strncmp returns 0 if the comparison is EQUAL. 
                        We want equality in this case since we're 
                        sorting games into buckets based on first 
                        characters */
            if (strncmp($normalizedTitle, "A", 1) === 0) {
                $gameList["A"][$normalizedTitle] = $game;
            } else if (strncmp($normalizedTitle, "B", 1) === 0) {
                $gameList["B"][$normalizedTitle] = $game;
            } else if (strncmp($normalizedTitle, "C", 1) === 0) {
                $gameList["C"][$normalizedTitle] = $game;
            } else if (strncmp($normalizedTitle, "D", 1) === 0) {
                $gameList["D"][$normalizedTitle] = $game;
            } else if (strncmp($normalizedTitle, "E", 1) === 0) {
                $gameList["E"][$normalizedTitle] = $game;
            } else if (strncmp($normalizedTitle, "F", 1) === 0) {
                $gameList["F"][$normalizedTitle] = $game;
            } else if (strncmp($normalizedTitle, "G", 1) === 0) {
                $gameList["G"][$normalizedTitle] = $game;
            } else if (strncmp($normalizedTitle, "H", 1) === 0) {
                $gameList["H"][$normalizedTitle] = $game;
            } else if (strncmp($normalizedTitle, "I", 1) === 0) {
                $gameList["I"][$normalizedTitle] = $game;
            } else if (strncmp($normalizedTitle, "J", 1) === 0) {
                $gameList["J"][$normalizedTitle] = $game;
            } else if (strncmp($normalizedTitle, "K", 1) === 0) {
                $gameList["K"][$normalizedTitle] = $game;
            } else if (strncmp($normalizedTitle, "L", 1) === 0) {
                $gameList["L"][$normalizedTitle] = $game;
            } else if (strncmp($normalizedTitle, "M", 1) === 0) {
                $gameList["M"][$normalizedTitle] = $game;
            } else if (strncmp($normalizedTitle, "N", 1) === 0) {
                $gameList["N"][$normalizedTitle] = $game;
            } else if (strncmp($normalizedTitle, "O", 1) === 0) {
                $gameList["O"][$normalizedTitle] = $game;
            } else if (strncmp($normalizedTitle, "P", 1) === 0) {
                $gameList["P"][$normalizedTitle] = $game;
            } else if (strncmp($normalizedTitle, "Q", 1) === 0) {
                $gameList["Q"][$normalizedTitle] = $game;
            } else if (strncmp($normalizedTitle, "R", 1) === 0) {
                $gameList["R"][$normalizedTitle] = $game;
            } else if (strncmp($normalizedTitle, "S", 1) === 0) {
                $gameList["S"][$normalizedTitle] = $game;
            } else if (strncmp($normalizedTitle, "T", 1) === 0) {
                $gameList["T"][$normalizedTitle] = $game;
            } else if (strncmp($normalizedTitle, "U", 1) === 0) {
                $gameList["U"][$normalizedTitle] = $game;
            } else if (strncmp($normalizedTitle, "V", 1) === 0) {
                $gameList["V"][$normalizedTitle] = $game;
            } else if (strncmp($normalizedTitle, "W", 1) === 0) {
                $gameList["W"][$normalizedTitle] = $game;
            } else if (strncmp($normalizedTitle, "X", 1) === 0) {
                $gameList["X"][$normalizedTitle] = $game;
            } else if (strncmp($normalizedTitle, "Y", 1) === 0) {
                $gameList["Y"][$normalizedTitle] = $game;
            } else if (strncmp($normalizedTitle, "Z", 1) === 0) {
                $gameList["Z"][$normalizedTitle] = $game;
            } else {
                $gameList["#"][$normalizedTitle] = $game;
            }
        }

        /*  Sort each letter bucket by the NORMALIZED titles
            (case insensitive, ignoring "THE" - The Division 
            sorts under D) */
        foreach ($gameList as $group) {
            ksort($group);
        }

        return $gameList;
    } else {
        return false;
    }
}

1 Answer 1

0

Here is the way I did it,

add_action('the_content', 'lm_alpha_order');

function lm_alpha_order($content){


if(is_page('alphabetique')){

    $args = array(
        'taxonomy' => 'media_tag',
        'hide_empty' => true,
        'orderby' => 'name',
        'order'   => 'ASC'
    );

    $terms = get_terms('media_tag', $args);

    $azRange = range('A', 'Z');

    echo '<div class="half left" style="float:left;padding-left: 2em;">';

    foreach ($azRange as $letter)
    {
        $letter_outputs = '';
        $the_letter =false;
        //print("$letter\n");
        $count = 0;
        $ul = '<ul class="alpha">';
        foreach ( $terms as $term ) {
            if ( preg_match("/^$letter/i", $term->name) ) {
                $the_letter = true;

                $args_post = array(
                    'posts_per_page'   => -1,
                    'tax_query' => array(
                        'relation'=> 'AND',
                        array(
                            'taxonomy' => 'media_tag',
                            'field'    => 'term_id',
                            'terms'    => $term->term_id,
                        ),
                        array(
                            'taxonomy' => 'media_category',
                            'field'    => 'slug',
                            'terms'    => 'audio',

                        ),
                    ),
                    'post_type'        => 'post',
                    'post_status'      => 'publish',
                    'suppress_filters' => true
                );

                $posts_array = new WP_Query( $args_post );
                $inner_letter_outputs ='';
                $letter_outputs .= $ul;
                $ul = '';  // only display once
                $letter_outputs .= '<li><h3><a href="javascript:void(0);" data-toggle="collapse" data-target="#media_'.$term->slug.'">'. $term->name . '</a></h3>
                <div id="media_'.$term->slug.'" class="collapse" style="color:#000035;">';
                    foreach($posts_array->posts as $post) {
                        if ($post->ID != null) {
                            if(has_shortcode($post->post_content, 'audio')){
                               $media_url = get_mp3_url($post->post_content);
                                foreach($media_url[0] as $k=>$url){
                                    if($k == 'mp3'){
                                        $url = str_replace('"', '',$url);
                                        $media_link = $url;
                                    }
                                }
                            }

                            $inner_letter_outputs .= '
                        <span class="media_'.$post->ID.' media-title"><a href="'.get_permalink($post->ID).'">' . $post->post_title . '</a></span><br/>
                        <span class="media-button"><a href="javascript:void(0):" class="btn-play-sound" data-item="'.$post->ID.'" data-guid="'.$media_link.'" data-title="'.$post->post_title.'">
                        <i class="fa fa-play" aria-hidden="true"></i></a>  <a href="javascript:void(0):" class="btn-play-pause" data-item="'.$post->ID.'" data-guid="'.$media_link.'"><i class="fa fa-pause" aria-hidden="true"></i></a>  
                        <a href="'.home_url().'/download.php?file='.$media_link.'" target="_blank" title="'.__('Download files', 'laura-marine').'"><i class="fa fa-download" aria-hidden="true"></i></a>
                        </span>
                        <br/>';
                        }
                    }
                $letter_outputs .= $inner_letter_outputs;
                $letter_outputs .='</div></li>';

                $count += sizeof($posts_array->posts);
            }
        }
        if ( $ul == '') {
            $letter_outputs .= '</ul>';
        }
        if($the_letter == true){
            echo '<h2>'.$letter . ' <small>('.$count.')</small></h2>';
        }
        echo $letter_outputs;
    }

    echo '</div>';
    $audio_shortcode = do_shortcode('[audio mp3="http://www.example.com/wp-content/uploads/2016/05/sound.mp3"][/audio]');
    echo '<div class="half right" style="position:relative; ">
            <div class="lm-sound-player" style="">
                <div class="hidden-player" style="display:none;">
                '.$audio_shortcode.'
                </div>
                <div class="player-tweet">
                    <i class="fa fa-spinner fa-pulse fa-4x fa-fw"></i><br/>
                        <span class="sr-only sound-title">Choose sound to listen...</span>
                </div>
            </div>
          </div>';

}

return $content;
}
2
  • I don't think this does what I need. Anything beginning with "The" would sort under "T", so if I used this, I'd hit "Destiny", then "Pokemon" before "The Division". I'd have already closed out my "D" section. I'm about 90% sure that I need to loop through once and re-key the results based on a normalized name. The only question is whether it's faster to normalize and sort the entire list or the grouped subsets of that list.
    – Mike
    Sep 29, 2016 at 17:17
  • Ok, eventually, you can apply a str_replace() on the THE of the term to make as you want.
    – Benoti
    Sep 29, 2016 at 17:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.