Drupal - Adding Author Name Search to Main Search Results Page

Posted March 17th @ 7:58 am  |  Filed in: Drupal    

Perhaps you typed an author’s name into Drupal’s search box, looking for content from that particular author. But for all Drupal knows, you’re just looking for content that matches the search phrase you just entered and could care less about who wrote it.

What do to?

Note: This page assumes some familiarity with how Drupal works.

The answer is the following sequence:

  1. Alongside the regular data query, query the user database for a username using a LIKE query, and if one is found, grab the user id too (uid).
  2. Perform a search for published content that matches that user id.
  3. Count the total pieces of content found.
  4. Spit out a link on the search result page that says something like, “Looking for posts written by Joe Author? (# found)”

I was hoping I could use the Views module for this, but I couldn’t figure out how to do a “LIKE” query with it. Besides, rather than loading a huge view object, why not to write a couple simple functions to do this? They can be efficient, and still take advantage of Drupal’s nifty (and secure) database functionality. The finished search page will look something like this:

include-user-name-search.png

Step 1: Build the query function

First things first - open up your theme’s template.php file. This is the place we store functions that we want to make available to the theme you are using. We’re going to add the following function to it - I’ve commented it pretty heavily:

/**
  * This function will search the database for an
  * aurhor's name, if it finds a match, will
  * count how many published stories and forum topics
  * they have
  * @param $name - the user name being searched for
  */
function get_user_content_total($name) {
  // this is the placeholder for the output link we're building
  $output = '';

  // build a user name search query with a string placeholder
  $sql = "SELECT name, uid FROM {users} WHERE name LIKE '%%%s%%'";
  $result = db_query(db_rewrite_sql($sql), $name);

  // build a count query with a digit placeholder for the user_id (uid from last query)
  $sql_count = "SELECT COUNT(node.uid) as count
  FROM {node} WHERE ({node}.status <> 0) AND ({node}.type in ('forum', 'story')) AND ({node}.uid = %d)";

  // iterate over the results
  while ($data = db_fetch_object($result)) {
    $result_count = db_query(db_rewrite_sql($sql_count), $data->uid);
    $data_count = db_fetch_object($result_count);

    // if we found any stories or forum topics, generate the text and link
    if ($data_count->count > 0) {
      $link_text = t('» Looking for content written by %author (%count)?', array('%author' => $data->name, '%count' => $data_count->count));
      $link = l($link_text, 'user/' . $data->uid . '/recent', array('html' => TRUE));
      $output .= '<p>' . $link . '</p>' . "\n";
    }
  }
  return $output;
}

You might be wondering about my link. Basically, I have a view already setup to fetch content written by a specific user. More on that over here. Ok, now we have some data to work with, so on to displaying it.

Step 2: Override the Search Results Template

The search module has a template file name search-results.tpl.php - we’re going to override that template file simply by making a file of the same name in our theme’s directory. So, your theme’s directory, create a file called search-results.tpl.php and put this into it:

<?php
print get_user_content_total(arg(2));
?>
<dl class="search-results <?php print $type; ?>-results">
  <?php print $search_results; ?>
</dl>
<?php print $pager; ?>

Now, the only difference between the search module’s search-results.tpl.php and ours is that ours calls our function at the top - the rest is exactly the same. And the nice thing about overriding it in this manner is that the next time we upgrade Drupal, our custom template here won’t get overridden because we’re not touching any core files.

After you create this file, you’ll need to visit admin/build/modules, which will rebuild the template files and let Drupal know that we are overriding something.

The last thing you may be asking is what’s with the arg(2) thing. That is just Drupal’s way of fetching things from the current URL. When you search with the search module, the URL is something like:

http://www.your-drupal.com/search/node/search words

The counting starts at 0, and does not include the domain. So ’search’ is 0, ‘node’ is 1, and ’search words’ is 2. Since this URL is always structured this way for a search result page, we can just pull the search query words directly from it, and rely on Drupal’s database functions to clean them up for safe querying.

This may not be the best way to do this - so I’m all ears if there’s a better way, cheers!

 

 

 

No Comments Yet

You can be the first to comment!

Leave a comment

OpenID Login

Standard Login

Options:

Size

Colors