Overview

This is a short tutorial demonstrating how to add search functionality to a SilverStripe site. It is recommended that you have completed the earlier tutorials, especially the tutorial on forms, before attempting this tutorial. While this tutorial will add search functionality to the site built in the previous tutorials, it should be straight forward to follow this tutorial on any site of your own. If you are adding the search form to the tutorial site, please get this updated css file and place it in themes/tutorial/css (as layout.css) and this search file tree icon search file tree icon and place it in themes/tutorial/images/treeicons (as search-file.gif).

What are we working towards?

We are going to add a search box on the top of the page. When a user types something in the box, they are taken to a results page.

Creating the search form

The first step in implementing search on your site is to create a form for the user to type their query. Create a function named SearchForm on the Page_Controller class (mysite/code/Page.php).

class Page_Controller extends ContentController {
   function SearchForm() {
      $searchText = isset($this->Query) ? $this->Query : 'Search';
		
      $fields = new FieldSet(
         new TextField("Search", "", $searchText)
      );
 
      $actions = new FieldSet(
         new FormAction('results', 'Go')
      );
 
      return new SearchForm($this, "SearchForm", $fields, $actions);
   }
}

This is very similar to the way forms were created in the third tutorial. There are however a few differences.

$searchText = isset($this->Query) ? $this->Query : 'Search';
 
$fields = new FieldSet(
   new TextField("Search", "", $searchText)
);

Here we create a new text field, giving it an empty label. The third argument sets the text inside the text field. First we check for the presence of ‘Query’ data, which will be the text searched for if we are on the results page. Otherwise, just set the text to ‘Search’.

The only other difference is we create a SearchForm object instead of a Form object. The SearchForm class contains all the logic needed for search on the site.

We then just need to add the search form to the template. Add $SearchForm to the ‘Header’ div in themes/tutorial/templates/Page.ss.

themes/tutorial/templates/Page.ss

<div id="Header">
  $SearchForm
  <h1>$Title</h1>
</div>

Showing the results

Next we need to create the results function.

class Page_Controller extends ContentController {
   ...	
 
   function results($data, $form){
      $data = array(
         'Results' => $form->getResults(),
         'Query' => $form->getSearchQuery(),
         'Title' => 'Search Results'
      );
      $this->Query = $form->getSearchQuery();
	
      return $this->customise($data)->renderWith(array('Page_results', 'Page'));
   }
}

First we populate an array with the data we wish to pass to the template - the search results, query and title of the page. The final line is a little more complicated.

When we call a function by its url (eg http://localhost/home/results), SilverStripe will look for a template with the name PageType_function.ss. As we are implementing the results function on the Page page type, we create our results page template as Page_results.ss. Unfortunately this doesn’t work when we are using page types that are children of the Page page type. For example, if someone used the search on the homepage, it would be rendered with Homepage.ss rather than Page_results.ss. SilverStripe always looks for the template from the most specific page type first, so in this case it would use the first template it finds in this list:

  • HomePage_results.ss
  • HomePage.ss
  • Page_results.ss
  • Page.ss

We can override this list by using the renderWith function. The renderWith function takes an array of the names of the templates you wish to render the page with. Here we first add the data to the page by using the ‘customise’ function, and then attempt to render it with Page_results.ss, falling back to Page.ss if there is no Page_results.ss.

Creating the template

Lastly we need to create the template for the search page. This template uses all the same techniques used in previous tutorials. It also uses a number of pagination variables, which are provided by the DataObjectSet class.

themes/tutorial/templates/Layout/Page_results.ss

<div id="Content" class="searchResults">
  <h2>$Title</h2>
	
  <% if Query %>
    <p class="searchQuery"><strong>You searched for &quot;{$Query}&quot;</strong></p>
  <% end_if %>
		
  <% if Results %>
    <ul id="SearchResults">
      <% control Results %>
        <li>
          <a class="searchResultHeader" href="$Link">
            <% if MenuTitle %>
              $MenuTitle
            <% else %>
              $Title
            <% end_if %>
          </a>
          <p>$Content.LimitWordCountXML</p>
          <a class="readMoreLink" href="$Link" title="Read more about &quot;{$Title}&quot;">Read more about &quot;{$Title}&quot;...</a>
        </li>
      <% end_control %>
    </ul>
  <% else %>
    <p>Sorry, your search query did not return any results.</p>
  <% end_if %>
			
  <% if Results.MoreThanOnePage %>
    <div id="PageNumbers">
      <% if Results.NotLastPage %>
        <a class="next" href="$Results.NextLink" title="View the next page">Next</a>
      <% end_if %>
      <% if Results.NotFirstPage %>
        <a class="prev" href="$Results.PrevLink" title="View the previous page">Prev</a>
      <% end_if %>
      <span>
        <% control Results.Pages %>
          <% if CurrentBool %>
            $PageNum
          <% else %>
            <a href="$Link" title="View page number $PageNum">$PageNum</a>
          <% end_if %>
        <% end_control %>
      </span>
      <p>Page $Results.CurrentPage of $Results.TotalPages</p>
    </div>
  <% end_if %>
</div>

Summary

This tutorial has demonstrated how easy it is to have full text searching on your site. To add search to a SilverStripe site, only a search form and a results page need to be created.

Next Tutorial >>

 
tutorial/4-site-search.txt · Last modified: 2009/09/24 16:21 by simon_w

Please use comments for notes, tips and corrections about the described functionality.
Use the Silverstripe Forum to ask questions.

blog comments powered by Disqus
 
Creative Commons LicenseSilverStripe Documentation by SilverStripe is licensed under a Creative Commons Attribution 3.0 New Zealand License.
Based on a work at doc.silverstripe.com
Recent changes RSS feed Driven by DokuWiki