Hi,

How can we change the wording of this Search related text. We want examples other than "blue smurfs". more company specific, although they are cute, smurfs...... : }

"Your search yielded no results
• Check if your spelling is correct.
• Remove quotes around phrases to match each word individually: "blue smurf" will match less than blue smurf.
• Consider loosening your query with OR: blue smurf will match less than blue OR smurf.

thanx,
Doug
FOB, Inc.

Comments

nisguy’s picture

easy, just enable the core Locale module and create a new 'language'. Then, search for the text 'blue smurf' and edit the corresponding string. more info at http://drupal.org/handbook/modules/locale

papile’s picture

Yeah enabling a translation adds a lot of overhead to just change one line, but unfortunately it is the only way it can be done without editing search.module. A noresult search calls the search_help implentation of hook help directly. There is no way to override it as it is not given a custom theme function or form.

The search module really needs the ability to be customized a lot more. For instance, I seek the ability to index only nodes of a certain type so I am not filling the search index with things that I do not need indexed. Also the ability to make your own no results field seems like a feature that should be in there as it is trivial.

skelly’s picture

Here's the patch I used to easily modify the text displayed when no search results are returned. It does involve a patch to core but if you are not adverse to such things or can easily track them with source control (as I do) then it's a bit neater than trying to trick the theme into doing it for you.

Index: /public_html/modules/search/search.module
===================================================================
--- /public_html/modules/search/search.module	(revision 314)
+++ /public_html/modules/search/search.module	(working copy)
@@ -91,6 +91,15 @@
 '\x{4e00}-\x{9fbb}\x{f900}-\x{fad9}');
 
 /**
+ * Default text to display when no search match found
+ */
+define('SEARCH_NO_RESULT_DEFAULT', '<ul>
+  <li>Check if your spelling is correct.</li>
+  <li>Remove quotes around phrases to match each word individually: <em>"blue smurf"</em> will match less than <em>blue smurf</em>.</li>
+  <li>Consider loosening your query with <em>OR</em>: <em>blue smurf</em> will match less than <em>blue OR smurf</em>.</li>
+</ul>');
+
+/**
  * Implementation of hook_help().
  */
 function search_help($section) {
@@ -103,11 +112,7 @@
     case 'admin/settings/search':
       return '<p>'. t('The search engine works by maintaining an index of the words in your site\'s content. You can adjust the settings below to tweak the indexing behaviour. Note that the search requires cron to be set up correctly.') .'</p>';
     case 'search#noresults':
-      return t('<ul>
-<li>Check if your spelling is correct.</li>
-<li>Remove quotes around phrases to match each word individually: <em>"blue smurf"</em> will match less than <em>blue smurf</em>.</li>
-<li>Consider loosening your query with <em>OR</em>: <em>blue smurf</em> will match less than <em>blue OR smurf</em>.</li>
-</ul>');
+      return variable_get('search_no_result_text', t(SEARCH_NO_RESULT_DEFAULT));
   }
 }
 
@@ -228,6 +233,10 @@
   $form['indexing_settings']['minimum_word_size'] = array('#type' => 'textfield', '#title' => t('Minimum word length to index'), '#default_value' => variable_get('minimum_word_size', 3), '#size' => 5, '#maxlength' => 3, '#description' => t('The number of characters a word has to be to be indexed. A lower setting means better search result ranking, but also a larger database. Each search query must contain at least one keyword that is this size (or longer).'));
   $form['indexing_settings']['overlap_cjk'] = array('#type' => 'checkbox', '#title' => t('Simple CJK handling'), '#default_value' => variable_get('overlap_cjk', TRUE), '#description' => t('Whether to apply a simple Chinese/Japanese/Korean tokenizer based on overlapping sequences. Turn this off if you want to use an external preprocessor for this instead. Does not affect other languages.'));
 
+  // No result text:
+  $form['no_results'] = array('#type' => 'fieldset', '#title' => t('No Results Text'));
+  $form['no_results']['search_no_result_text'] = array('#type' => 'textarea', '#title' => t('No results message'), '#default_value' => t(variable_get('search_no_result_text', SEARCH_NO_RESULT_DEFAULT)), '#description' => t('Text to display when no results returned for search'));
+  
   // Per module settings
   $form = array_merge($form, module_invoke_all('search', 'admin'));
andjsmit’s picture

One simple approach is to use templates. You can created a template called page-search.tpl.php. Then check if the page contains no results. If so, do some replacing. For example:

$check = '<li>Check if your spelling is correct.</li>';
if(strpos($content,$check){
  $content = str_replace('blue','physics',$content);
  $content = str_replace('smurf','journals',$content);
}
DerekAhmedzai’s picture

I find it easiest to do this in template.php
For this example, I want to replace "blue smurf" with "asset management" :-

function _phptemplate_variables($hook, $vars = array()) {
  if ($hook == 'page') {
    //annihilate smurfs :)
    if (false !== strpos($vars['content'], "blue smurf"))
      {
        $vars['content'] = str_replace("blue smurf", "asset management", $vars['content']);
        $vars['content'] = str_replace("blue OR smurf", "asset OR management", $vars['content']);
      }
  }
  return $vars;
} 

This results in:

  • Check if your spelling is correct.
  • Remove quotes around phrases to match each word individually: "asset management" will match less than asset management.
  • Consider loosening your query with OR: asset management will match less than asset OR management.
CrookedNumber’s picture

Thanks, Derek. Easy, simple, flexible solution. Though when I implemented it, I tweaked one line -- for efficiency.

From:

if ($hook == 'page') {

to:

if ($hook == 'page' && arg(0)=='search') {

NB: assumes that you haven't changed search's standard path.

danieltome’s picture

Instead of hacking the _phptemplate_variables function:

You can create a function in your template: MYTHEME_box($title, $content, $region = 'main')
And check if $title equals "Your search yielded no results"
And update the $content to show whatever you prefer.

This is definitly much more efficient then having the if check in the _phptemplate_variables function.

cheers,

thatpatguy’s picture

Just to help others like me who are still newbs to drupal (and potentially even newbs to php) I've added an example of what this function would look like so people can copy and paste at their desire. This function goes into the template.php file:

<?php

function MYTHEME_box($title, $content, $region = 'main') {
  if ($title == 'Your search yielded no results')
  {
    $content = '<ul>';
    $content .= '<li>Check if your spelling is correct.</li>';
    $content .= '<li>Remove quotes around phrases to match each word individually: <em>"asset management"</em> will match less than <em>asset management</em>.</li>';
    $content .= '<li>Consider loosening your query with <em>OR</em>: <em>asset management</em> will match less than <em>asset OR management</em>.</li>';
    $content .= '</ul>';
  }
  $output = '<h2 class="title">'. $title .'</h2><div>'. $content .'</div>';
  return $output;
}

?>
johlin23’s picture

Does this work for Drupal 6 as well?

And also, is it the template.php found in themes?

tatude’s picture

Yes, and yes :)

Didn't quite figure out where the function name comes from (the _box in the end)... But I guess that's relatively easy to find out somewhere.

John Bickar’s picture

Thanks, this was a really helpful tip.

(It comes from theme_box().)

Yuki’s picture

subscribing

eff_shaped’s picture

this was just what I needed :) .... At 5pm... now I want more!

How can I add to this function to change the title also?

My bumbling php attempts have not helped.

rschwab’s picture

Change this:

<?php
  if ($title == 'Your search yielded no results')
  {
    $content = '<ul>';
    $content .= '<li>Check if your spelling is correct.</li>';

?>

To this:

<?php
  if ($title == 'Your search yielded no results')
  {
    $title = 'My new title';
    $content = '<ul>';
    $content .= '<li>Check if your spelling is correct.</li>';

?>

- Ryan

eff_shaped’s picture

Cheers Ryan!

That worked.
(I tried something like it, but got an 'unexpected title' error with what I coded.)

For others' information:
I also worked out that I could change the title string with 'string overides' module.
In this case I had to change the title referenced in the php function to match 'My new title'; so that the function still works:

Option using string overides

<?php
  if ($title == 'My new title')
  {
    $content = '<ul>';
    $content .= '<li>Check if your spelling is correct.</li>';
    $content .= '<li>My new content.</li>';

?>

In the end, I'm using the function in template.php only, to keep the changes all in one place.

cacaf8’s picture

Been working on trying to change the search results title for hours. Thanks so much for this!

l-r’s picture

Hi,
this worked wonders, but I have another question...How would I got about inserting the search keywords in there? I've been looking around to print $_GET["keys"] or an equivalent in order to have a personalized "Your search XXXXXXXXXXX yielded no results, etc." ?

Thanks!

rschwab’s picture

Check the contents of $form_state:

<?php
$content .= "<pre>";
$content .= print_r($form_state);
$content .= "</pre>";

?>

- Ryan

l-r’s picture

Thanks Ryan, though I can't get anything except "1" printed...I went to check out the doc about it, and although it seems pretty straightforward, I can't get the values, form_id or anything from there. What am I missing?

rschwab’s picture

That stuff needs to be in a function that has access to $form_state, like the forms submit or validation functions. I would then store your words in session variables so they're easily available to other pages.

It might look something like

<?php
$words = explode(' ', $form_state['values']['search_field']);
$_SESSION['my_search_terms'] = $words;
?>

- Ryan

bwv’s picture

@ thatpatguy

Thank you for this snippet, it worked great. To get the new results on the page, I needed to clear all my caches.

Hope that small bit of information helps someone.

TGReaver’s picture

Did anyone else encounter any issues when getting this to work?

I've pasted the following into my template.php file:

<?php

function MYTHEME_box($title, $content, $region = 'main') {
  if ($title == 'Your search yielded no results')
  {
    $content = '<ul>';
    $content .= '<li>Check if your spelling is correct.</li>';
    $content .= '<li>Remove quotes around phrases to match each word individually: <em>"asset management"</em> will match less than <em>asset management</em>.</li>';
    $content .= '<li>Consider loosening your query with <em>OR</em>: <em>asset management</em> will match less than <em>asset OR management</em>.</li>';
    $content .= '</ul>';
  }
  $output = '<h2 class="title">'. $title .'</h2><div>'. $content .'</div>';
  return $output;
}

?>

However no changes are made, even after clearing Drupals cache.

TravisCarden’s picture

Did you replace "MYTHEME" in the function name with the actual machine name of your theme?

TGReaver’s picture

Sorry I should of mentioned that, yes I did.

SweeneyTodd’s picture

There isn't anything wrong with the code but it relies on the title of the page. If you change the title to "Uh Oh! Couldn't find it!" (I've just checked your site) then it won't work. I've changed your code to work with your modified title and it works ok.

epmD’s picture

This worked out for me after clearing the cache.

dmf7’s picture

I've pasted this coding above and it brings an error when refreshing my site: Notice I changed the title of MYtheme to reflect my theme's name? is that correct? I also need to change the blue smurf text..

If I change to a custom title such as Sorry, or something of that sort, how does that reflect in the php below? I put this into my theme's folder in the template.php

sorry not a php expert..


function acquia_propser_box($title, $content, $region = 'main') {
  if ($title == 'Your search yielded no results')
  {
    $content = '<ul>';
    $content .= '<li>Check if your spelling is correct.</li>';
    $content .= '<li>Remove quotes around phrases to match each word individually: <em>"asset management"</em> will match less than <em>asset management</em>.</li>';
    $content .= '<li>Consider loosening your query with <em>OR</em>: <em>asset management</em> will match less than <em>asset OR management</em>.</li>';
    $content .= '</ul>';
  }
  $output = '<h2 class="title">'. $title .'</h2><div>'. $content .'</div>';
  return $output;
}

TravisCarden’s picture

Is that your exact code? Because the theme name is misspelled: "acquia_propser_box".

dmf7’s picture

I did have a typo thanks for catching, but even after I fixed that, I'm getting this error

Parse error: syntax error, unexpected---

any ideas?

dmf7’s picture

In my acquia_prosper theme, my template.php shows this now:

// $Id: template.php,v 1.5 2010/09/17 21:36:06 eternalistic Exp $

/**
 * Changed breadcrumb separator
 */
function acquia_prosper_breadcrumb($breadcrumb) {
  if (!empty($breadcrumb)) {
    return '<div class="breadcrumb">'. implode(' &rarr; ', $breadcrumb) .'</div>';
  }
}
function acquia_prosper_box($title, $content, $region = 'main') {
  if ($title == 'Your search yielded no results')
  {
    $content = '<ul>';
    $content .= '<li>Check if your spelling is correct.</li>';
    $content .= '<li>Remove quotes around phrases to match each word individually: <em>"asset management"</em> will match less than <em>asset management</em>.</li>';
    $content .= '<li>Consider loosening your query with <em>OR</em>: <em>asset management</em> will match less than <em>asset OR management</em>.</li>';
    $content .= '</ul>';
  }
  $output = '<h2 class="title">'. $title .'</h2><div>'. $content .'</div>';
  return $output;
}

Is something missing? It should just read the template file in my theme folder correct. I got the error message to go away, but now it's not displaying any changes...

rschwab’s picture

If you changed your page title like you mentioned a couple posts above, you'll want to change if ($title == 'Your search yielded no results') to have whatever your new title is between the single-quotes.

Also try clearing your cache so that your system knows you're using those hooks.

dmf7’s picture

thanks, I changed the title as you mentioned and got the error message to go away. but it's still not changing the blue smurf text.

I changed asset management to bronze statue, but it's still not changing the text and now I am getting an error when trying to view any page:

* warning: Cannot modify header information - headers already sent by (output started at /home/.../public_html/.../themes/acquia_prosper/template.php:14) in /home/.../public_html/test/includes/common.inc on line 148.
* warning: Cannot modify header information - headers already sent by (output started at /home/.../public_html/.../themes/acquia_prosper/template.php:14) in /home/.../public_html/.../includes/common.inc on line 148.

What does that mean? and why is it displaying> i've also cleared the cache.

The weird thing is there is no line 148

dmf7’s picture

This is not working, another idea would be to just remove that search result text altogether
Is that possible?

Search results

* Check if your spelling is correct.
* Remove quotes around phrases to match each word individually: "blue smurf" will match less than blue smurf.
* Consider loosening your query with OR: blue smurf will match less than blue OR smurf.

rschwab’s picture

I think I've heard that have the closing php tag "?>" at the end of your template.php can cause problems. Its not clear why your theme function override isn't working. Maybe paste the whole template.php into a code block here for us (or provide a link to pastebin or something).

dmf7’s picture

basically the php I have above is the only coding in my template.php that is located in my acquia_propser theme folder...???

dmf7’s picture

// $Id: template.php,v 1.5 2010/09/17 21:36:06 eternalistic Exp $

/**
* Changed breadcrumb separator
*/
function acquia_prosper_breadcrumb($breadcrumb) {
  if (!empty($breadcrumb)) {
    return '<div class="breadcrumb">'. implode(' &rarr; ', $breadcrumb) .'</div>';
  }
}
function acquia_prosper_box($title, $content, $region = 'main') {
  if ($title == 'Sorry,')
  {
    $content = '<ul>';
    $content .= '<li>Check if your spelling is correct.</li>';
    $content .= '<li>Remove quotes around phrases to match each word individually: <em>"asset management"</em> will match less than <em>asset management</em>.</li>';
    $content .= '<li>Consider loosening your query with <em>OR</em>: <em>asset management</em> will match less than <em>asset OR management</em>.</li>';
    $content .= '</ul>';
  }
  $output = '<h2 class="title">'. $title .'</h2><div>'. $content .'</div>';
  return $output;
}
monalisab’s picture

I tried on D7.
Seems its not working.
Is there any other way for Drupal 7 ?

jojo86’s picture

I have used this code so I can change the title and content that comes back if there are no results but it is duplicating it - the default content that sits in search.module (with blue smurf) and my edited version underneath it. The title doesn't repeat though, just the content - can anyone help?

function link2_box($title, $content, $region = 'main') {
  if ($title == 'Your search yielded no results')
  {
    $title = 'Sorry, we couldn\'t find what you were looking for';
    $content .= '<p>Check if your spelling is correct.</p>';
    $content .= '<p>Remove quotes around phrases to match each word individually: for example <em>"green energy"</em> will match less than <em>green energy</em>.</p>';
    $content .= '<p>Consider loosening your query with <em>OR</em>: for example <em>green energy</em> will match less than <em>green OR energy</em>.</p>';
  }
  $output = '<div style="margin:10px"><h3>'. $title .'</h3>'. $content .'</div>';
  return $output;
}

results:

Sorry, we couldn't find what you were looking for

    * Check if your spelling is correct.
    * Remove quotes around phrases to match each word individually: "blue smurf" will match less than blue smurf.
    * Consider loosening your query with OR: blue smurf will match less than blue OR smurf.

Check if your spelling is correct.

Remove quotes around phrases to match each word individually: for example "green energy" will match less than green energy.

Consider loosening your query with OR: for example green energy will match less than green OR energy.
jojo86’s picture

I have figured out why this doesn't work - there is a concatenation operator on the first $content - the code should be:

function link2_box($title, $content, $region = 'main') {
  if ($title == 'Your search yielded no results')
  {
    $title = 'Sorry, we couldn\'t find what you were looking for';
    $content = '<p>Check if your spelling is correct.</p>';
    $content .= '<p>Remove quotes around phrases to match each word individually: for example <em>"green energy"</em> will match less than <em>green energy</em>.</p>';
    $content .= '<p>Consider loosening your query with <em>OR</em>: for example <em>green energy</em> will match less than <em>green OR energy</em>.</p>';
  }
  $output = '<div style="margin:10px"><h3>'. $title .'</h3>'. $content .'</div>';
  return $output;
}
acidpotato’s picture

Thanks! I am trying to figure out how to customize the no search results on D7 but havent found a solution that works from above examples.

woop_light’s picture

looking for a Drupal 7 solution as well

DerekAhmedzai’s picture

You can use String Overrides to change this text in D7.
http://drupal.org/project/stringoverrides

soulston’s picture

Just copy search-result.tpl.php and search-results.tpl.php from /modules/search into your own theme, clear cache and you are away.

search-result.tpl.php - individual results
search-results.tpl.php - the wrapper for each result with the no results text too.

I realise the question goes on to ask about the smurf part but google is ranking this highly for: How to Change "Search Yields no Result Text"

dariogcode’s picture

Thanks for all contributions to this. I finally used preprocess function because this doesn't alter the theme function itself, it change the text before it is passes to theme.

/**
* Modify search result text
*/
function MYTHEME_preprocess_box(&$vars) {
  if ($vars['title'] == t('Your search yielded no results')) {
	$vars['content'] = '<ul>';
    $vars['content'] .= '<li>Check if your spelling is correct.</li>';
    $vars['content'] .= '<li>Remove any quotes around phrases</li>';
    $vars['content'] .= '<li>Add "or" as in "restaurant OR cafe"</li>';
    $vars['content'] .= '</ul>';
  }
}

?>

Drupal experts in Argentina! www.tilon.com.ar

timwhelan’s picture

I was trying to solve the same problem and found this...

hmartens’s picture

How would the D7 preprocess code look for this?

Thanks

Living life in a grande way.

diamondsea’s picture

To make this work in D8 without modifying core code or writing preproccess functions, modify your base theme's item-list--search-results.html.twig file in your /theme/ThemeName/templates/* folder (or subfolder) to add the following code to override the empty message:

{% set empty = empty|merge({'#markup': 'Your No Results message HTML Goes Here'}) %}

For example, if you a using Classy as your base theme, your new /themes/MyTheme/templates/overrides/item-list--search-results.html.twig file would look like :

{% extends "item-list.html.twig" %}
{#
/**
 * @file
 * Theme override for an item list of search results.
 *
 * Available variables:
 * - items: A list of items. Each item contains:
 *   - attributes: HTML attributes to be applied to each list item.
 *   - value: The content of the list element.
 * - title: The title of the list.
 * - list_type: The tag for list element ("ul" or "ol").
 * - attributes: HTML attributes to be applied to the list.
 * - empty: A message to display when there are no items. Allowed value is a
 *   string or render array.
 * - context: An list of contextual data associated with the list. For search
 *   results, the following data is set:
 *   - plugin: The search plugin ID, for example "node_search".
 *
 * @see template_preprocess_item_list()
 */
#}
{%
  set classes = [
    'search-results',
    context.plugin ~ '-results',
  ]
%}
{% set attributes = attributes.addClass(classes) %}
{% set empty = empty|merge({'#markup':
"
<h2 class='no-search-results'>Your search yielded no results</h2>
<ul>
<li>Check if your spelling is correct.</li>
<li>Remove quotes around phrases to search for each word individually. <em>bike shed</em> will often show more results than <em>'bike shed'</em>.</li>
<li>Consider loosening your query with <em>OR</em>. <em>bike OR shed</em> will often show more results than <em>bike shed</em>.</li>
</ul>
"
}) %}

websiteworkspace’s picture

Thanks @diamondsea for your solution above to this problem.

Based on the code provided in 2018 by diamondsea, below is an updated version that works for Drupal 10 (running on 10.2.0).

This template needs to be placed in the templates directory for the theme one's drupal site is using.

for example in a folder much like the following:

{site base directory}/themes/custom/snazzycustomdrupaltheme/templates

where {snazzycustomdrupaltheme} would be replace with the name of your drupal site's theme.

The relative file path would be the following:

{site base directory}/themes/custom/snazzycustomdrupaltheme/templates/item-list.html.twig

{% extends "item-list.html.twig" %}
{#
/**
 * @file
 * Theme override for an item list of search results.
 *
 * Available variables:
 * - items: A list of items. Each item contains:
 *   - attributes: HTML attributes to be applied to each list item.
 *   - value: The content of the list element.
 * - title: The title of the list.
 * - list_type: The tag for list element ("ul" or "ol").
 * - attributes: HTML attributes to be applied to the list.
 * - empty: A message to display when there are no items. Allowed value is a
 *   string or render array.
 * - context: An list of contextual data associated with the list. For search
 *   results, the following data is set:
 *   - plugin: The search plugin ID, for example "node_search".



 *
 * @see template_preprocess_item_list()
 */
#}

{%
  set classes = [
    'search-results',
    context.plugin ~ '-results',
  ]
%}

{% set attributes = attributes.addClass(classes) %}
{% set empty = empty|merge({'#value':
"
<h4 class='no-search-results'>Your search didn't yield any results</h4>
<ul>
<li>Check that your spelling is correct.</li>
<li>Try removing  quotes around phrases to search for each word individually. <em>bike shed</em> will often show more results than <em>'bike shed'</em>.</li>
<li>Consider loosening your query with <em>OR</em>. <em>bike OR shed</em> will often show more results than <em>bike shed</em>.</li>
</ul>
"
}) 

%}

Note that the template code change just above is based on the following code in the current SearchController.php code, where the array that needs modification is now named #value:

    $build['search_results'] = [
      '#theme' => ['item_list__search_results__' . $plugin->getPluginId(), 'item_list__search_results'],
      '#items' => $results,
      '#empty' => [
        '#type' => 'html_tag',
        '#tag' => 'em',
        '#value' => $this->t('Your search yielded no results.'),
      ],
      '#list_type' => 'ol',
      '#context' => [
        'plugin' => $plugin->getPluginId(),
      ],
    ];

Lanni91’s picture

Is it possible to add a block instead of plain text if the search does not produce results? I tried entering with this:

'search # noresults': return echo views_embed_view ('view_candidature', 'block_177');

but it does not work. Can someone help me?