I'd like to use the same results template for all of my search functions so I'm wondering if it's possible to limit the search to a specific channel i.e. news or calendar in the form rather than in the results template.
Thanks!
You'd do it just like querying for any other element in Craft. i.e.
{% set results = craft.entries({
search: query,
section: 'news'
}) %}
Totally possible. Easy way to do it, is to add a hidden input field to the form for whatever section you want to search – the input field can be named anything, e.g. s
:
<form action="{{ url('search/results') }}">
<input type="search" name="q" placeholder="Search">
<input type="hidden" name="s" value="vegetables"/>
<input type="submit" value="Go">
</form>
The above would add an additional GET variable to the search request, named s
. Just like with the q
parameter, you can use craft.request
to pick up that parameter's value in your search results template, and add it to the the ElementCriteriaModel (i.e. craft.entries
, in this case):
{% set query = craft.request.getParam('q') %}
{% set section = craft.request.getParam('s')|default('news') %}
{% set entries = craft.entries.section(section).search(query).order('score') %}
...
Note that it's wise to use the |default
filter to add a default value to the section
variable, in case the s
GET parameter is missing or empty, for some reason – if you don't pass a section handle to the ECM, Craft searches all sections, which is probably not what you want.
Further: If you wanted to search multiple sections, you could do something like this:
<form action="{{ url('search/results') }}">
<input type="hidden" name="s[]" value="vegetables"/>
<input type="hidden" name="s[]" value="fruits"/>
<input type="hidden" name="s[]" value="berries"/>
<input type="submit" value="Go">
</form>
...and if you wanted to give the user control over which sections to search, you could opt for an input type other than hidden, e.g. checkboxes:
<input type="checkbox" name="s[]" value="vegetables"/>Vegetables
<input type="checkbox" name="s[]" value="fruits"/>Fruits
<input type="checkbox" name="s[]" value="berries"/>Berries
And finally, the same strategy would, of course, work fine for any other parameter/field value you can pass to an ElementCriteriaModel. You could, for instance, add a dropdown field enabling the user to filter search results by author:
<form action="{{ url('search/results') }}">
<input type="search" name="q" placeholder="Search">
<select name="a">
<option value="">All authors</option>
<option value="3">Julia</option>
<option value="53">Gary</option>
<option value="13">Susie</option>
</select>
<input type="submit" value="Go">
</form>
In this case, it'd probably make sense to default to null
, which would give you results for all authors:
{% set query = craft.request.getParam('q') %}
{% set authorId = craft.request.getParam('a')|default(null) %}
{% set entries = craft.entries.authorId(author).search(query).order('score') %}
...