Support » Developing with WordPress » Related articles using a search query

  • matt-tyas

    (@matt-tyas)


    Hello there. I hope the wordpress hive mind can help.

    I am creating a business directory (custom post type) that is filtered using the search and filter pro plugin. All is working well. However, I have a problem getting good matches on related articles from the default post type. These are articles about or mentioning the business in question as seen in this example:

    http://staging.manchestersfinest.com/directory/bay-horse-tavern/

    I have tried related post plugins but the results were not relevant enough. Ideally for the venue ‘bay horse tavern’ I want to return only articles specifically about the ‘bay horse tavern’. As you can see from the link the results I get do not to a user seem that related…

    I decided to use a query based on a search term to achieve this. The author can add a search term into a custom meta box on the directory that is then used in the template to build the query like so. It might be wrong – I am not the best with these things…

    <?php
    $search_term = get_field('directory_related_posts_search_term');
    $args1 = array(
    'posts_per_page' => 3,
    's'              => $search_term,
    'post_type'      => 'post'
    );
    $myposts1 = get_posts( $args1 );
    foreach ( $myposts1 as $post ) : setup_postdata( $post ); ?>
    <a href="<?php the_permalink() ?>" rel="bookmark" class="post-tile-link">
    <article <?php post_class('post-tile post-tile--grid'); ?>>
    <?php    						                      the_post_thumbnail('big-post-thumb');
    ?>
    <h3><?php echo wp_trim_words ( the_title ( '', '', false ), 12 , '&hellip;'); ?></h3>
    </article>
    </a>
    <?php endforeach; wp_reset_postdata();?>

    This does not return particularly relevant results and interestingly does not return the same results as if I use the site search – which I find very odd.

    Does anyone know a) what the hell is going on? b) Should I search just on the post title perhaps, and how do I do this? c) Is there a better way to get to where I want to be?

    Thank you in advance!

    • This topic was modified 2 months ago by  matt-tyas.
Viewing 15 replies - 1 through 15 (of 16 total)
  • Moderator bcworkz

    (@bcworkz)

    In theory, the values passed as the s argument should return the exact same results as a site search using the same terms. I requested staging.manchestersfinest.com/?s=bay horse tavern and the results appear to be pretty relevant. The first 3 should be the same as returned by your code, provided the field retrieved is also “bay horse tavern”. Insert var_dump( $search_term ); within <pre> tags to be sure you are getting what you think. Passing “bay%20horse%20tavern” could yield different results than passing “bay horse tavern”

    BTW, when you use setup_postdata( $post );, you need to also declare global $post; before the foreach line.

    It’s possible your theme or a plugin is altering how searches are managed. As a debugging exercise, hook the “posts_request” filter and output the passed SQL query. Compare the site search query with your custom search query. s argument searches using the same terms should yield nearly identical SQL queries. The final LIMIT clause should be the only difference.

    Usually, examining the SQL will indicate why the query not acting as expected. It’s then a matter of tracking down the cause. How the SQL is wrong is often a good clue towards finding the cause.

    matt-tyas

    (@matt-tyas)

    Hi,

    Thank you for this. On further investigation based on what you told me – these are the queries I’m getting. It looks to me like the ‘bay horse tavern’ string is not even being passed to the query by advanced custom fields. I can only assume I have implemented it incorrectly. The question is… what have I done wrong…

    Output screenshots
    Related articles:
    https://www.dropbox.com/s/5f2mg5itsnqlt62/Screen%20%202018-03-20%20at%2008.52.32.png?dl=0

    Search query:
    https://www.dropbox.com/s/p5rvik79dm7j450/The%20Bay%20Horse%20Tavern%20search%20SQL.jpg?dl=0

    Getting there… cheers.

    matt-tyas

    (@matt-tyas)

    I think the related query was incorrect… Here’s another go.
    https://www.dropbox.com/s/lcvnurowi8wslqc/The%20Bay%20Horse%20Tavern%20related%20SQL.jpg?dl=0

    Moderator bcworkz

    (@bcworkz)

    Yikes!!! 🙂 I’m not sure what all the hexadecimal stuff is. Apparently getting the search term field contains much more info than expected. I’m not familiar with ACF, so I’m not sure precisely how data is normally stored. Try var_dumping $search_term to see what we are really getting from get_field(). You probably need to extract out a specific value out of all the returned data for use as the s argument.

    matt-tyas

    (@matt-tyas)

    Well after much, much messing about I got it working. Well sort of and probably not in the best way…
    So. Now I have…

    `<?php
    $user_search_term = get_field(‘directory_related_posts_search_term’);
    $search_term = str_replace(“+”, ” “, $user_search_term);
    global $wpdb;
    $myposts = $wpdb->get_results
    ( $wpdb->prepare(”
    SELECT
    * FROM $wpdb->posts
    WHERE
    post_title LIKE ‘%s’ LIMIT 3″, ‘%’. $wpdb->esc_like( $search_term ) . ‘%’
    )
    );
    foreach ( $myposts as $mypost ) {
    $post = get_post( $mypost );
    echo “<a href='”;
    the_permalink();
    echo “‘ class=’post-tile-link’>”;
    echo “<article class=’post-tile post-tile–grid’>”;
    the_post_thumbnail(‘big-post-thumb’);
    echo “<h3>”;
    echo wp_trim_words ( the_title ( ”, ”, false ), 12 , ‘…’);
    echo “</h3>”;
    echo “</article>”;
    echo ““;
    }
    ?>

    get_posts, wp-query etc just would not bring back relevant results this does but, it also brings back attachment post results – the question is how do I exclude these and posts from the directory post type?

    Seen here with attachment posts…
    http://staging.manchestersfinest.com/directory/takk/

    And here the original page I posted – with good results.
    http://staging.manchestersfinest.com/directory/bay-horse-tavern/

    Cheers

    Moderator bcworkz

    (@bcworkz)

    So if $search_terms works in your SQL but with get_posts() you end up with that huge long SQL, I was wrong about extra data being in the ACF field. I’ve no idea why get_posts() ends up with such a long SQL. No matter if you can get your own SQL to work for you.

    To query only for post post_types, add the following between WHERE and post_title:
    post_type = 'post' AND

    Hey thank you.

    About to try this. As what I hope will be my last request. How do I get the as newest post first as well.

    A bit out of my depth with the SQL stuff…

    Thank you for the post type help. Looks like thats worked. I tried to get the newest post also by adding ORDER BY post_date DESC but this has not worked properly… Taking this example:

    What I want as the top three would be the top three here:
    http://staging.manchestersfinest.com/?s=crazy+pedros

    What I get
    http://staging.manchestersfinest.com/directory/crazy-pedros/

    It basically feels like they’re being somewhat picked at random…
    My query as is…

    
    <?php
    $user_search_term = get_field('directory_related_posts_search_term');
    $search_term = str_replace("+", " ", $user_search_term);
    global $wpdb;
    $myposts = $wpdb->get_results
         ( $wpdb->prepare("
             SELECT
             * FROM $wpdb->posts
             WHERE
             post_type = 'post'
             AND
             post_title LIKE '%s' ORDER BY post_date DESC LIMIT 3", '%'. $wpdb->esc_like( $search_term ) . '%'
         )
     );
    foreach ( $myposts as $mypost ) {
    $post = get_post( $mypost );
    echo "<a href='";
    the_permalink();
    echo "' class='post-tile-link'>";
    echo "<article class='post-tile post-tile--grid'>";
    the_post_thumbnail('big-post-thumb');
    echo "<h3>";
    echo wp_trim_words ( the_title ( '', '', false ), 12 , '&hellip;');
    echo "</h3>";
    echo "</article>";
    echo "</a>";
        }
    ?>
    

    Thank you as ever.

    Moderator bcworkz

    (@bcworkz)

    ORDER BY post_date should do it. I cannot imagine how you could get random results.

    Your output loop needs a little help. The SQL is fine, but alter the part afterwards like so:

    global $post;
    $save = $post;
    foreach ( $myposts as $post ) {
      setup_postdata( $post );
      echo "<a href='";
      the_permalink();
      // the rest is fine...
      // ...up to
      echo "</a>";
    }
    $post = $save;

    Your code, modified as shown, works fine on my site. I get the same posts every time. Note that for the search term I just did $search_term = 'test'; because I don’t use ACF. It’s a test site, so the word “test” comes up a lot. If something is still not right for your site, try a similar assignment, taking get_field() out of the mix. If a direct assignment works for you, then we are back to get_field() not returning what you think it does.

    Hi again.

    Still no luck – thank you for the help with loop though. I was hoping somehow it might magically fix it…

    Anyway. Staging now has $search_term = "Crazy Pedro's"; hard coded and the results are still different from the search query…

    http://staging.manchestersfinest.com/directory/crazy-pedros/

    http://staging.manchestersfinest.com/?s=Crazy+Pedro%27s

    I am pretty sure that soon I will go quite, quite mad…

    Moderator bcworkz

    (@bcworkz)

    Yeah, that would have been magic 🙂 I was hoping the hard coded search term would reveal something. Mainly because ACF is the only part I don’t fully understand. Taking it out of the picture removes that shortcoming.

    While using a SQL query takes a lot of possible undue influence out of the picture, there is still an influence possibility from other plugin or theme code. $wpdb still has filters they can hook to bollix up the query. Please install the health-check plugin and activate troubleshooting mode.

    Temporarily place your code on a twentyseventeen template. The bottom of header.php would be a good choice. Don’t forget to include a <?php tag before your code, as that part of the template is HTML. Your code should work correctly in troubleshooting mode. Use the troubleshooting admin bar item to restore your normal theme and plugins, each one at a time, testing after each change. When the strange behavior returns, the last activated module is the culprit. You could then take up the issue with the module’s author.

    Hi there.

    I thought it might be getting to the ‘turn the plugins off one by one’ thing.

    That does seem like the last thing to try. I’ll let you know when I find out what’s going on.

    Cheers for persisting with this.

    Hello,

    It gets odder and odder. I have followed your advice above. My query remains as the last few comments above. Twenty Seventeen active, all plugin disabled and I still get the same results from the query…

    https://www.dropbox.com/s/1vpgnls9p58mh2e/Screen%20%202018-03-29%20at%2011.14.30.png?dl=0

    It is so very odd.

    Moderator bcworkz

    (@bcworkz)

    Are you sure the query you are trying to match is really the 3 latest search term posts? Could it be you ARE seeing the 3 latest posts? Kinda running out of possible explanations 🙁

    Update on this.

    So I never got to the bottom of it… In the end I used ajax to scrape the search results page to get the listings I was after. A hacky solution for a weird problem.

    Scraping my own website for content?! I’ve seen everything now :/

    Anyhoo – it works: http://staging.manchestersfinest.com/directory/bay-horse-tavern/

    Thank you for your help on this.

    • This reply was modified 1 month, 2 weeks ago by  matt-tyas.
Viewing 15 replies - 1 through 15 (of 16 total)
  • You must be logged in to reply to this topic.