0

For Drupal 7 I found a workaround to a similar situation here, when combining Core search block forms and search api contextual filters. This "workaround" won't work when using Search API, if you don't want the Contextual Filter in your view.

My current setup:
I am using Search API, with a database server, and displaying the results with a Views page. I am using Search: Fulltext search (exposed) and Exposed form in block:Yes for the search block form.

What I am trying to achive:
I would like to put what was searched for in the Header of the view, and also at the top of No Results Behavior like this:

"You searched for bananas"

The problem:
When using Search: Fulltext search (exposed), the replacement patterns for the input value are not available in the Global Text Area. They are only available by adding a Fulltext Search Contextual Filter. There is an issue for this with a patch for Drupal 8 here.

My question:
Is there a views_pre_render or some other hook that can be used for the Header or No Results region to output the value that was input into the Search: Fulltext search (exposed) form?

There is a dev module to create a token, but it only works for the Results Summary.

2 Answers 2

1

Maybe not exactly what you're asking for, but the one way to approach this is to use hook_preprocess_views_view(&$variables) and modify the contents of the header, or add a variable containing the string you want and then it in above/below the header in a views-view.tpl.php template override. If the search string isn't available through $variables, you can probably grab it from the url since it's likely included as a query string.

To get the query string from the url and add it to the template variables you'd do something like the following in your module or theme:

/**
 * Implements hook_preprocess_hook()
 */
function my_module_preprocess_views_view(&$variables) {
  // Get the query string from the url.
  // it will be on something like ?the_search_string=big+banana.
  $search_string_raw = $_GET['the_search_string'];
  
  // Decode the url to remove special chars
  $search_string_decoded = urldecode($search_string_raw);

  // Add it to $variables so it's available in views-view.tpl.php
  $variables['search_string'] = $search_string_decoded;
}

This will make the search_string available in views-view.tpl.php. You can then print it in there with

<?php if($search_string): ?> 
  <?php print $search_string ?>
<?php endif; ?>

// or

<?php

if($search_string) {
  print $search_string;
}

To clarify how hook_preprocess_hook works -- the first "hook" is your module name, and the second is the name of the template that you're targeting. Since we are targeting views-view.tpl.php, we use hook_preprocess_views_view.

In general, the easiest way to get started inspecting php variables is to dump them to the screen. For Drupal 7, I'd recommend installing https://www.drupal.org/project/kint on your site. This will let you print variables to the screen to help you dig into their values and see what's in there. You'd do like:

function my_module_preprocess_views_view(&$variables) {
  kint($variables);
  // or
  kpr($variables['header'])
}

Then you can see what's actually inside of $variables and grab/modify the values in there.

11
  • Thanks for chiming in! If I provided you with better information, could you spin up an example hook to try? Nov 29, 2020 at 2:21
  • Also, if I grab it from the URL it will have + signs in it. ie "you searched for banana+bread+muffins" Nov 29, 2020 at 2:22
  • Unfortunately I don't really have a good way to set up a dummy Search API instance on D7 at the moment so that'd be tough. The header element should be in $variables['header'] so that's what you'd tweak to print it out without a template override. With the override you could add like $variables['search_string'] then print $search_string in the template. You're right that the search string would have things like + signs -- you'd can use urldecode() (php.net/manual/en/function.urldecode.php) to deal with that, then maybe ucwords() or ucfirst() for capitalization.
    – Mrweiner
    Nov 29, 2020 at 2:43
  • 1
    $search_string and $search_string_raw are arbitrary -- they don't exist at all before they are set to equal something. You could rename them to absolutely anything and the snippet would work exactly the same. In $_GET['foo'] you'd replace foo with whatever is directly to the right of the question mark in the URL. So on site.com/search?whatever=something, $_GET['whatever'] would be equal to something. You could kint($_GET) to see what's in there if you'd like. w3schools.com/PHP/php_superglobals_get.asp
    – Mrweiner
    Nov 29, 2020 at 4:16
  • 1
    Very helpful. 👍 Nov 29, 2020 at 4:20
0

I am accepting the above answer, but adding this as it's helpful for anyone trying to accomplish the same type of thing. This preprocess function is for the general views-view.tpl.php file which will affect all views.

  function MY_MODULE_preprocess_views_view(&$variables) {
  // Get the query string from the url.
  // it will be on something like ?THE_SEARCH_STRING=big+banana.
  $search_string_raw = $_GET['THE_SEARCH_STRING'];
  
  // Decode the url to remove special chars
  $search_string_decoded = urldecode($search_string_raw);

  // Add it to $variables so it's available in views-view.tpl.php
  $variables['search_string'] = $search_string_decoded;
}

Since this is trying to get THE_SEARCH_STRING on all views, this will result in an undefined index messages in the log on all view pages except the one where the search string exists.

I found if you want to write a preprocess function for a specific view, the preprocess function would look like this:
function MY_MODULE_preprocess_views_view__MY_VIEW__page(&$variables)

There is a problem though... in Drupal 7 there is an issue where Specific preprocess functions for theme hook suggestions are not invoked. There is a workaround for it here which should allow you to write view specific preprocess functions for any views_view.tpl.php templates:

function MY_MODULE_preprocess_views_view(&$vars) {
  if (isset($vars['view']->name)) {
    $function = 'MY_MODULE_preprocess_views_view__' . $vars['view']->name . '__' . $vars['view']->current_display;
    
    if (function_exists($function)) {
      $function($vars);
    }
  }
}

I wonder if the set of variables in the initial answer could be simply parented under some thing like:
if ($view->name == 'my_view_name' && $view->current_display == 'my_display_id')

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.