WordPress.org

Ready to get started?Download WordPress

Forums

[resolved] WP_Query with RegEx: Is it possible? Custom Fields better? (21 posts)

  1. stevechatterton
    Member
    Posted 4 years ago #

    Hey, it's me, the guy with the book site again: http://www.thelitreview.com

    We use Exec-PHP extention a lot on the site, and we have a few pages that use custom WP_Query functions, many of which have had invaluable help from people in these forums, to do things like listing best rated books in a certain genre (category):
    http://www.thelitreview.com/the-lit-reviews-top-10-list

    Here's the latest thing we want to do and I have no idea if it's possible => We want to be able to have alphabetized listings of all book reviews by either book title or author's name, but the only way I can think to do it is by forcing regular expressions into the $args array in WP_Query() to sift through the titles of the posts to display the relevant lists.

    We're already using custom fields to display ratings on landing pages & search results, so that's out unless there's an easy way to have multiple custom fields where only a select few display (right now we use the_meta() which I believe doesn't accept any arguments - would we be better off exploring get_post_meta()?).

  2. MichaelH
    Member
    Posted 4 years ago #

    alphabetized listings of all book reviews by either book title or author's name,

    The alphabetized by title would be a query_posts with arguments like:

    $args=array(
      'orderby' => 'title',
      'order' => 'ASC',
      'post_type' => 'post',
      'post_status' => 'publish',
      'posts_per_page' => -1,
      'caller_get_posts'=> 1
    );
    $my_query = null;
    $my_query = new WP_Query($args);

    The by author would require sorting the users alphabetically, then cycling through each user and retrieving and displaying that author's posts.

  3. stevechatterton
    Member
    Posted 4 years ago #

    Hi MichaelH,

    Very helpful as always, but I guess I didn't elaborate enough on my problem.

    When we list a book review, the title of the post goes like this:
    “A Reliable Wife” by Robert Goolrick

    I was thinking RegEx because I would need this one under R by title. So I'd have to write a regular expression that ignored 'a' & 'the' at
    the beginning of a title. Then there's all the problems with isolating the author's last name, especially when there are multiple authors, as in:
    “A Patriot’s History of the United States” by Larry Schweikart and Michael Allen

    I think I need to play with custom fields a bit. If I can set some up that don't get displayed on the landing pages but can be used to sort alphabetically I think all would be golden.

    Is it possible to set fields like:

    Title: Patriot’s History of the United States A
    Author: Schweikart Larry
    Author: Allen Michael

    That would allow me to get that book on the alphabetical pages for titles beginning with P and authors beginning with A & S?

    I'm going to browse the Codex & see what I can piece together that way & check back here in a bit. Thanks.

  4. stevechatterton
    Member
    Posted 4 years ago #

    I opted to go for Custom Fields. I spent a whole day updating all of our posts. Then I discovered the limitations of comparing custom fields.

    So far I can only make the thing work to display books where the author's last name begins with A:

    $args = array(
    'category__not_in' => array(11, 12),
    'orderby' => 'meta_value',
    'meta_key' => 'var',
    'meta_compare' => '<',
    'meta_value' => 'B',
    'order' => 'ASC',
    'post_type' => 'post',
    'post_status' => 'publish',
    'posts_per_page' => 20,
    'caller_get_posts'=> 1
     );
    
    $my_query1 = new WP_Query($args);

    But when I try a second compare statement to get authors starting with B my second statement cancels out the first. Therefore:

    'meta_compare' => '>',
    'meta_value' => 'B','
    meta_compare' => '<',
    'meta_value' => 'C',

    will return A & B authors.

    Is there no simple way to make this happen? Even a mildly complicated one?

    I tried the CF Taxonomies plug-in, but that wasn't living up to it's expectations to say the least.

  5. MichaelH
    Member
    Posted 4 years ago #

    What's the goal there? List all posts in order by custom field value?

  6. Mark / t31os
    Moderator
    Posted 4 years ago #

    And for additional clarification, are you looking to get all posts with this custom field key at once, then sort by starting letter, or page them, ie. Those starting with A on one page, then B on another, and so on..

  7. stevechatterton
    Member
    Posted 4 years ago #

    Yes, we want posts listed in order by a custom field, but grouped & separated alphabetically.

    We want to have A-Z navigation across the top:

    A - B - C - D - etc.

    Clicking on A would give you any author with a last name beginning with A, and so on down the line.

    It'd be a really handy way for users to browse a bunch of books.

  8. MichaelH
    Member
    Posted 4 years ago #

    In that case it might be easier to use wpdb to get the post ids from the postmeta table WHERE meta_key = 'var' AND meta_value > 'A' AND meta_value < 'B' then use those post id values to get your posts.

    [edit fixed wpdb link ]

  9. Mark / t31os
    Moderator
    Posted 4 years ago #

    Hi Steve,

    Just want to restate one of the original queries i made above, is the intention to list all these entries on one single page, or split them across multiple pages? It wasn't quite clear in your last response..

    If they're all going onto a singular page, then you'd only need to query for all entries with that meta_key and then do the sorting when it comes to putting/displaying the entries on the page.

    Michael's suggestion is a good one, you'd probably be better off with a custom written query, so you can tailor it to suit exactly what you need rather then needing to fiddle around with the supported query parameters in WP_Query or query_posts.

  10. stevechatterton
    Member
    Posted 4 years ago #

    t31os_

    The intention is to have 1 letter per page when it displays, and there will likely be some pagination involved when we get more titles.

    Ideally I'd like to do it all in one page that passes variables, likely through the URL - /books?start=A&end=B or something like that.

    MichaelH - I'll look into that wpdb stuff - it looks mighty complicated to my eyes, but maybe if I start at the beginning & read every word it'll start coming together. I'm a little rusty on coding DB calls, and have virtually no experience with inner joins, but I'll give it a whirl.

  11. MichaelH
    Member
    Posted 4 years ago #

    No join necessary:

    <?php
    $meta_key = 'var';
    $start_value = 'A';
    $end_value = 'B'; 
    
    $postids = $wpdb->get_col($wpdb->prepare("
    SELECT DISTINCT post_id
    FROM        $wpdb->postmeta
    WHERE       (meta_key = %s)
                AND (UPPER(meta_value) >= %s AND UPPER(meta_value) < %s)",$meta_key, $start_value, $end_value)); 
    
    if ($postids) {
      $args=array(
        'post__in' => $postids,
        'post_type' => 'post',
        'post_status' => 'publish',
        'posts_per_page' => -1,
        'caller_get_posts'=> 1
      );
      $my_query = null;
      $my_query = new WP_Query($args);
      if( $my_query->have_posts() ) {
        echo 'List of Posts';
        while ($my_query->have_posts()) : $my_query->the_post(); ?>
          <p><a href="<?php the_permalink() ?>" rel="bookmark" title="Permanent Link to <?php the_title_attribute(); ?>"><?php the_title(); ?></a></p>
          <?php
        endwhile;
      }
      wp_reset_query();  // Restore global post data stomped by the_post().
    }
    ?>
  12. stevechatterton
    Member
    Posted 4 years ago #

    I know we're getting closer to a solution, but I'm getting one of those pesky fatal errors:

    Fatal error: Call to a member function get_col() on a non-object in /***/wp-content/plugins/exec-php/includes/runtime.php(42) : eval()'d code on line 7

    Do I need to globalize something somewhere first perhaps?

  13. MichaelH
    Member
    Posted 4 years ago #

    Might need a global $wpdb;

  14. stevechatterton
    Member
    Posted 4 years ago #

    Here's the error msg when we try that:

    Parse error: syntax error, unexpected T_GLOBAL in /***/wp-content/plugins/exec-php/includes/runtime.php(42) : eval()’d code on line 6

    Maybe globalization isn't the issue.

  15. MichaelH
    Member
    Posted 4 years ago #

    I can duplicate that but not sure why that plugin exec-php is doing that.

    Code works fine with Otto's PHP code widget and works fine in a Template so you might need to resort to putting that in a template.

  16. MichaelH
    Member
    Posted 4 years ago #

    Actually after I added the global $wpdb; to the post it worked for me using the exec-php code plugin.

  17. stevechatterton
    Member
    Posted 4 years ago #

    Any chance I could coax you into posting your revised code, because I seem to get an error with everything I try.

    By the way, I do really appreciate all the help. Something's just not clicking here.

  18. MichaelH
    Member
    Posted 4 years ago #

    Of course I use different values ...

    <?php
    global $wpdb;
    $meta_key = 'cf1';
    $start_value = 'C';
    $end_value = 'D'; 
    
    $postids = $wpdb->get_col($wpdb->prepare("
    SELECT DISTINCT post_id
    FROM        $wpdb->postmeta
    WHERE       (meta_key = %s)
                AND (UPPER(meta_value) >= %s AND UPPER(meta_value) < %s)",$meta_key, $start_value, $end_value)); 
    
    if ($postids) {
      $args=array(
        'post__in' => $postids,
        'post_type' => 'post',
        'post_status' => 'publish',
        'posts_per_page' => -1,
        'caller_get_posts'=> 1
      );
      $my_query = null;
      $my_query = new WP_Query($args);
      if( $my_query->have_posts() ) {
        echo 'List of Posts';
        while ($my_query->have_posts()) : $my_query->the_post(); ?>
          <p><a href="<?php the_permalink() ?>" rel="bookmark" title="Permanent Link to <?php the_title_attribute(); ?>"><?php the_title(); ?></a></p>
          <?php
        endwhile;
      }
      wp_reset_query();  // Restore global post data stomped by the_post().
    }
    ?>
  19. stevechatterton
    Member
    Posted 4 years ago #

    Whatever they're paying you, it's not enough!

    I was trying to declare it within the function (at the advice of a rather old book). But that, indeed, does work, and now I'm going to stop bothering you for a good long while. Know that I'm eternally grateful & have yourself a great weekend.

  20. MichaelH
    Member
    Posted 4 years ago #

    You are welcome. Marking resolved.

    Note: all volunteers in these forums!

  21. stevechatterton
    Member
    Posted 4 years ago #

    Well, if you write a book of your coolest WP tricks I'll be first in line to buy it.

Topic Closed

This topic has been closed to new replies.

About this Topic