How do I display custom fields in WordPress in alphabetical order?

I need to display a custom field on a WP page that contains only values beginning with the letter A, without duplicates. Currently, I am using the code that was given earlier by Soju. This sorts alphabetically, but I can’t get it to display only values beginning with one letter:

    <?php
    $movie_reviews = get_posts( 
    'numberposts=-1&order=ASC&orderby=meta_value&meta_key=LAST%20NAME' );
    $directors = array();
    foreach( $movie_reviews as $post ) {
        $director = get_post_meta( $post->ID, 'LAST NAME', true );
    }
    $directors = array_unique($directors);
    foreach( $movie_reviews as $post ) : setup_postdata( $post );
    foreach ($directors as $director) {
    }
    if (strtolower($director[0])=='') {
        // display what you want
    }
    ?>
    <span><li>
    <?php $director = get_post_meta( $post->ID, "LAST NAME", $single = true );
    if( $director !== '' ) {
    echo $director;
    } ?></br></li>
    </span>
    <?php endforeach; ?>

Related posts

Leave a Reply

1 comment

  1. I think you’ll be better off handling this in the database query rather than with PHP. With your current code you will make dozens of database calls which is inefficient.

    Pulling the Records

    WordPress stores all the custom fields in the wp_postmeta table and can be retrieved as follows.

    mysql> SELECT post_id, meta_value FROM wp_postmeta WHERE meta_key = 'LAST NAME';
    +---------+-------------------+
    | post_id | meta_value        |
    +---------+-------------------+
    |       4 | Spielberg         |
    |       6 | AveryTiredman     | <-- in the list twice
    |       8 | bLanguage         |
    |      10 | aWakeMahn         |
    |      12 | dScreensAreBrukin |
    |      14 | Aluloby           |
    |      16 | AaLetterC         |
    |      19 | AveryTiredman     | <-- 
    +---------+-------------------+
    8 rows in set (0.00 sec)
    

    I’ve created multiple posts with the custom field of LAST NAME to replicate your website. As you can see the query above pulls all the last names that I’ve entered as custom fields.

    You can filter and sort the results with the following.

    mysql> SELECT meta_value AS last_name FROM wp_postmeta
           WHERE meta_key = 'LAST NAME' and meta_value LIKE 'a%'
           GROUP BY meta_value
           ORDER BY meta_value;
    +---------------+
    | last_name     |
    +---------------+
    | AaLetterC     |
    | Aluloby       |
    | AveryTiredman | <-- only shown once
    | aWakeMahn     |
    +---------------+
    4 rows in set (0.00 sec)
    

    As you can see the above query only pulls unique records, that start with the letter "a", and it orders them by name.

    Note: I changed the column name to be more relevant with SELECT meta_value AS last_name.

    Using with WordPress

    WordPress has its own database class with a method called get_results() that let’s you run your own query. The method will return an array of objects that will let you access the column names.

    <?php $directors = $wpdb->get_results("SELECT meta_value AS last_name FROM wp_postmeta WHERE meta_key = 'LAST NAME' and meta_value LIKE 'a%' GROUP BY meta_value ORDER BY meta_value") ?>
    <ol>
      <?php foreach( $directors as $director ) : ?>
        <li><?php echo $director->last_name ?></li>
      <?php endforeach ?>
    </ol>
    

    I know that you’re new to this and I tried to lay it out so you can understand what’s going on. If you have any questions just let me know and I’ll try to help you out.


    Update

    The easiest way to make a page with links to filter through directors is with a custom page template. Basically, create a file named page-directors.php with the following content. Then add a new page and set the template to "Directors Page".

    <?php
    /**
     * Template Name: Directors Page
     */
    
    // get a distinct set of the first letters available
    $letters = $wpdb->get_results("SELECT DISTINCT substring(meta_value, 1, 1) as letters FROM wp_postmeta WHERE meta_key = 'LAST NAME' ORDER BY meta_value", ARRAY_N); 
    
    // get the letter from the URL
    // and make sure there is only a single letter
    $director_letter = filter_input(INPUT_GET, 'director', FILTER_VALIDATE_REGEXP, array('options' => array('regexp' => '/^[a-z]$/i')));
    
    // set a default if none is available
    if( $director_letter == false ) {
      $director_letter = 'a';
    }else {
      $director_letter = strtolower($director_letter);
    }
    
    // don't trust user's input
    $director_letter = mysql_real_escape_string($director_letter);
    
    // same query as before but includes letter from user
    $directors = $wpdb->get_results("SELECT meta_value AS last_name FROM wp_postmeta WHERE meta_key = 'LAST NAME' and meta_value LIKE '$director_letter%' GROUP BY meta_value ORDER BY meta_value");
    
    get_header();
    ?>
    <div id="primary">
        <div id="content" role="main">
            <?php while ( have_posts() ) : the_post(); ?>
    
          <!-- 
            CSS:
            #director_letters li {
              list-style: none;
              display: inline;
            }
          -->
          <ol id="director_letters">
            <?php foreach( $letters AS $letter ) : ?>
              <li><a href="<?php echo add_query_arg('director', strtolower($letter[0])) ?>"><?php echo strtoupper($letter[0]) ?></a></li>
            <?php endforeach ?>
          </ol>
    
          <h2>Directors</h2>
    
          <ol>
            <?php foreach( $directors AS $director ) : ?>
              <li><?php echo $director->last_name ?></li>
            <?php endforeach ?>
          </ol>
    
            <?php endwhile; // end of the loop. ?>
        </div>
    </div>
    <?php get_footer() ?>
    

    Update #2

    If you take the code and SQL queries I’ve written for you already you should be able to figure it out. I don’t want to just give you the answer because you won’t learn that way. So here’s what I’ll do instead. I’m going to give you the steps that you need to take to accomplish it and let you figure it out. If you have any questions or you get stuck, post a comment and I’ll help you out.

    1. You’ll need to create another custom page template that will take the director’s last name as a GET parameter. It will be exactly the same as what that I’ve used to show the first letters of the directors last names.

    2. Next, you will need to query the wp_postmeta table and select the post_id WHERE the meta_value equals the director’s last name.

    3. You will need to loop over the post ids and display the post’s title.

    Everything I’ve shown you so far can be used to answer your question. But, as I said before, if you run into a problem that you can’t figure out let me know.

    Also, once you’ve completed this feature please add the code back to your original question. There’s a good chance that we can greatly improve the efficiency of it 🙂

    P.S. If you have don’t understand some of the code that I’ve supplied you, please let me know. It won’t do you any good to have code that you don’t understand 🙂

    Update #3

    I made a video explaining all the steps from the beginning. It starts with pulling out the director’s last names, then showing all the letters, and finally showing all WordPress posts with the director.