What’s the background to this tutorial? We had just created a custom blog for our new site and were looking to implement search functionality. We wanted to use MODX’s SimpleSearch component, but discovered there wasn’t a simple tutorial that other people may want to follow.
So, guess what? We decided to write one! Hope it helps you, in the same way it helped inform us.
What is SimpleSearch?
In “simple” terms (excuse the pun) it enables users to enter a search term (like you would in any normal search box) and return any relevant content it finds from MODX Resources you created in your site – essentially, it does all the hard work for you.
Where do we start?
The first thing to do, if you haven’t already done so, is to download & install SimpleSearch. As with other MODX components, this can all be done within MODX Revolution manager utilising Package Management.
I’ve created a basic framework for us to work from as we go along. It’s a MODX Resource that contains a simple
HTML template, with the key elements and the accompanying code required to make everything work – but we’ll come on to that shortly.
<!doctype html> <html> <head> <meta charset="utf-8"> <title>SimpleSearch</title> <link rel="stylesheet" type="text/css" href="css/styles.css"> </head> <body> <main> <div class="headline"> <h1>Your SimpleSearch Search Bar</h1> <h2>You'll never search alone!</h2> </div> <!-- /.headline --> <div id="search"> [[SimpleSearchForm? &landing=`9` &tpl=`search-form`]] </div> <!-- /#search --> <div id="content"> <div class="container message"> [[!SimpleSearch? &ids=`5` &highlightResults=`1` &searchIndex=`search` &includeTVs=`1` &perPage=`6' &pagingSeparator=`` &tpl=`search-results` &extractLength=`200` &containerTpl=`search-results-container` &pageTpl=`search-results-page` ¤tPageTpl=`search-results-current-page` &noResultsTpl=`search-no-results` ]] </div> <!-- /.container --> </div> <!-- /#content --> </main> <!-- /main --> <footer> <div id="copyright"> <small>© copyright Karbon Designed 2015</small> </div> <!-- /#copyright --> </footer> <!-- /footer --> </body> </html>
You can see within the code two Snippets that are at the heart of SimpleSearch.
- The first one, SimpleSearchForm – displays the form that enables you to enter your search query.
- And the second, SimpleSearch – displays the consequent search results.
Let’s look at each of these in more detail.
From the outset, I would like to draw your attention to a majority of the Available Properties that SimpleSearch utilises. They incorporate a number of Defaults that you should familiarise yourself with and within this tutorial I only draw your attention to those that are relevant to our proposed framework.
Now that we’ve got that out of the way, let’s proceed.
Look at the
&landing property below, which is added to the Snippet call to stipulate which Resource is being used to display the search results. This is where the SimpleSearch snippet is located and in our case, they are both on the same page.
As a side note, you don’t have to specify a
&landing property if you’d like the search results to display on the same page (although we always like to), just make sure the SimpleSearch snippet is placed underneath.
Next up, the
&tpl property specifies the Chunk that SimpleSearchForm processes and is used to display the search form. You should create a Chunk in MODX which looks like this:
<form class="search-blog" action="[[~[[+landing:default=`[[*id]]`]]]]" method="[[+method:default=`get`]]"> <input class="search-field" type="text" name="search" value="Search here..." /> <button class="search-button" type="submit">Go</button> </form>
There are two Placeholders we need to be aware of here. Firstly:
This determines where the form-data (our search query) is sent, when the submit button is clicked. It defaults to the current Resource. Secondly:
The form method attribute specifies how to send the form-data, which defaults to GET. In both instances, it is the syntax that you need to be aware of, as both form attributes are standard.
On to the main event! We’ve set-up our search form, now we need to configure our SimpleSearch snippet so we can display the subsequent search results. This is highly customisable and there are a number of Available Properties, but ultimately it is dependent on the needs of your project.
I would suggest familiarising yourself with them in more detail, you will be surprised at what you can do. Here’s the code again:
[[!SimpleSearch? &ids=`5` &highlightResults=`1` &searchIndex=`search` &includeTVs=`1` &perPage=`6` &pagingSeparator=`` &tpl=`search-results` &extractLength=`200` &containerTpl=`search-results-container` &pageTpl=`search-results-page` ¤tPageTpl=`search-results-current-page` &noResultsTpl=`search-no-results` ]]
Let’s break this down a little now.
As I stated at the beginning, I wanted to build a small blog for this site and the first thing I had to do was create a Resource called ‘Blog’ and set that as a Container within its individual settings. See image below:
Why? Because any articles I write thereafter will/should be created as a new Resource inside the ‘Blog’ container. This is where the
&ids property comes into play. As I am telling SimpleSearch where I want to restrict my search to (in this case, everything inside Resource ID number 5) but this can also be a comma-separated list of IDs if necessary.
&highlightResults=`1` speaks for itself, you can choose whether or not to highlight the search term in the results that are displayed.
&searchIndex=`search` simply specifies the name of the REQUEST parameter to be used in the search query. In our case it is the NAME attribute in the FORM input element.
<input name="search" type="text" />
I am utilising Template Variables so have included the
&includeTVs=`1` property to ensure they are available to any Resources created.
Another straightforward property
&perPage=`6` basically determines the number of searches you want to show on each page.
&pagingSeparator=`` property defines the separator to be used between pagination links, more on that later. Leaving it blank removes the default ‘|’ (pipe symbol).
The next properties are arguably the most important, as they call the various chunks that deal with displaying the contents of any search queries performed.
Kicking us off is the
&tpl=`search-results` which is the main Chunk for displaying each search result. Simply create a new Chunk called
search-results and add the following code.
<div class="sisea-result"> <h3><a href="[[+link:is=``:then=`[[~[[+id]]]]`:else=`[[+link]]`]]" title="[[+longtitle]]">[[+pagetitle]]</a></h3> <div class="extract"> <p>[[+extract]]</p> </div> <!-- /.extract --> </div> <!-- /.sisea-result -->
It’s all self-explanatory, the anchor tag and its attributes reference each individual Resource that is returned from the search query and the
[[+extract]] placeholder, as you would expect, displays a short extract from the Resource.
Additionally, we can control the length of
[[+extract]] by implementing the
&extractLength=`200` property, which you can alter based on your needs.
Moving on to the
&containerTpl=`search-results-container` property which is used to return search results, pagination & message. Again create another Chunk named
search-results-container that looks like this:
<p>...all this from the search phrase <strong>[[+query]]</strong>.</p> <p class="sisea-results res-bold">[[+resultInfo]]</p> <div class="posts"> [[+results]] </div> <!-- /.posts --> <div class="paging search-results"> <ul> [[+paging]] </ul> </div> <!-- /.paging -->
Let’s dissect this briefly.
[[+query]] placeholder is simply the original search term the user submits. I like to implement this, as it provides a visual reference in relation to what has been entered.
As a nice little touch, we have included the
[[+resultInfo]] placeholder (which I modified slightly through MODX’s Lexicon Management – found inside the Admin System menu) which informs the user how many search terms there are.
[[+results]] placeholder returns a summary of any articles that match the search query term and displays them inside: [html]<div class=”posts”>[/html] You can target the contents with CSS to style as necessary.
Next we come on to
[[+paging]] which as the name suggests displays the number of pages that hold search results. As mentioned earlier, this can be controlled with the
&perPage=`` property and the higher the number, the lower the number of pages are returned.
The next two properties work in tandem with each other, they provide the necessary pagination required for the search results.
&pageTpl=`search-results-page` property provides anchor links for all available pages, create another Chunk called
search-results-page using the code below:
<ul> <li><a href="[[+link]]">[[+text]]</a></li> </ul>
¤tPageTpl=`search-results-current-page` property removes the anchor tag, highlighting which page the user is currently on. Here’s the code for the
search-results-current-page Chunk you need to create:
<ul> <li>[[+text]]</li> </ul>
Finally, as the name suggests, the
&noResultsTpl=`search-no-results` property provides feedback to the user, informing them no search results were available. You guessed it, create a final Chunk called
search-no-results and copy the following code:
...I'm sorry we haven't found anything for the term <strong><em>[[+query]]</em></strong>.
[[+query]] placeholder is included to show which search term was originally submitted.
— MODX (@modx) October 20, 2015
Thanks guys, much appreciated.
Wrapping it all up
There you have it, you’ve now got everything you need to complete your own, fully working, functional ‘SimpleSearch’ form.
It really isn’t that difficult once you’ve gone through the process a couple of times. It’s a powerful little tool that not only saves you time but if you take the time to investigate further, is capable of so much more.
“If you like what we’ve done, why not share?”