Using Search V1 in your templates

Table of contents

So recently we've added a new search engine; You can read here how to enable it on your site.

After that you can create a fairly easy search page.

In this blog I will show you how to use this using a simple form get request.

  • Using dedicated 'search' posttype with only index.
  • Using request object to read url query params.
  • Using search_results tag
  • Using a couple of includes
  • Using translate filter for UI translations.
    • Singular result
    • Plurar result
  • Using simple form tag to send simple get request at Plate
  • Using paginate tag
An bare example of html output.

Features

This implementation includes several advanced features:

  1. Post Type Filtering: Users can filter results by content type (articles, pages, job postings)
  2. Pagination: Results are paginated with configurable posts per page
  3. Rich Result Cards Each result shows title, excerpt, and content type
  4. Translation Support All UI elements use translation keys
  5. Clean URLs: Uses GET parameters for search queries and filters

Implementation

Let's look at how to implement a search page using the actual theme structure:

theme/
  ├── posts/
  │   └── search/
  │       └── index.plate
  └── includes/
      └── modules/
          └── search/
              ├── search_form.plate
              ├── search_index.plate
              └── search_card.plate
Theme file structure

The Main Search Page

Create a search page template at `theme/posts/search/index.plate`:

{%- content_for search -%}
    <div class="search-index-page plate--container">
        <search>
            {% include 'includes/modules/search/search_form' %}
        </search>
    
        {% include 'includes/modules/search/search_index' %}
    </div>

    {% render_content %}
{%- endcontent_for -%}
theme/posts/search/index.plate

Advanced Search Form with Filters

The search form (`includes/modules/search/search_form.plate`) includes post type filtering:

<form action="{{ site.search.index.url }}" method="get" class="search-form {{ classes }}">
  <div class="search-form-input-wrapper">
    <label for="search_form_input" class="search-form-input-label">
      {{ "search.search_what" | translate }}
    </label>
    <input 
      class="search-form-input" 
      id="search_form_input" 
      type="search" 
      name="q" 
      value="{{ request.query_object.q | escape }}" 
      placeholder="{{ "search.search_placeholder" | translate }}"
    >

    {% assign filters = 'article,page,job_posting' | split: ',' %}
    <fieldset>
      <legend>Filters</legend>
      {% for filter in filters %}
        <input 
          type="checkbox" 
          id="posttype_{{ filter }}" 
          name="searchPostTypes[]" 
          value="{{ filter }}" 
          {% if request.query_object.searchPostTypes contains filter %}checked{% endif %}
        >
        <label for="posttype_{{ filter }}">
          {{ filter | prepend: 'post_type.' | translate }}
        </label>
      {% endfor %}
    </fieldset>

    <button type="submit" class="search-form-button" title="{{ "search.search" | translate }}">
      <span>{{ "search.search" | translate }}</span>
    </button>
  </div>
</form>
theme/includes/modules/search/search_form.plate

Search Results with Pagination

The search index (`includes/modules/search/search_index.plate`) handles results display and pagination:

<div class="search-index-page-results">
  {%- assign search_string = request.query_object.q | escape -%}
  {%- assign searchPostTypes = false -%}
  {% if request.query_object.searchPostTypes != blank %}
    {%- assign searchPostTypes = request.query_object.searchPostTypes -%}
  {% endif %}

  {%- capture searchFilters -%}
    [
      {%- if searchPostTypes != false -%}
        {
          "field": "post.content_type_name",
          "operator": "in",
          "value": [{%- for filter in searchPostTypes -%}
          "{{filter}}"{% unless forloop.last %},{% endunless %}
          {%- endfor -%}]
        }
      {%- endif -%}
    ]
  {%- endcapture -%}

  {% search_results search_string, filters: searchFilters %}
    {%- if search_results != blank -%}
      {% if search_results.size == 1 %}
        <p class="filtered-results-item">
          <span class="count">{{ search_results.size }}</span> 
          {{ "search.results_found_singular" | translate }}
        </p>
      {% else %}
        <p class="filtered-results-item">
          <span class="count">{{ search_results.size }}</span> 
          {{ "search.results_found_plural" | translate }}
        </p>
      {% endif %}

      {%- assign postsPerPage = site.search.index.posts_per_page | default: site.posts_per_page | times: 1 -%}
      {% paginate object_array: search_results, per_page: postsPerPage, window_size: 5 %}
        {% for p in paginate.items %}
          {% include 'includes/modules/search/search_card', search_card: p %}
        {% endfor %}

        {% if search_results.size != 0 %}
          {%- include 'includes/modules/search/search_pagination_buttons' -%}
        {% endif %}
      {% endpaginate %}
    {% else %}
      {% if request.query_object.q != blank %}
        <div class="no-results">
          <h2>{{ "search.no_results" | translate }}</h2>
          <p>{{ "search.try_again" | translate }}</p>
        </div>
      {% endif %}
    {%- endif -%}
  {% endsearch_results %}
</div>
theme/includes/modules/search/search_index.plate

Search Result Card

Each search result is displayed using a card template (`includes/modules/search/search_card.plate`):

<a href="{{ search_card.url }}" class="search-card {% if item.image != blank %}has-image{% endif %}">
  <div class="search-card-content">
    <h2>{{ search_card.title | strip_html }}</h2>
    {% if search_card.index_text != blank %}
      <div class="index-text paragraph">
        {{ search_card.index_text }}
      </div>
    {% endif %}
    <p>{{ search_card.content_type.name | prepend: 'post_type.' | translate }}</p>
  </div>
</a>
theme/includes/modules/search/search_card.plate

Required Translations

Make sure to add these translations to your language files:

search:
  search_what: "Search"
  search_placeholder: "Enter your search terms..."
  search: "Search"
  results_found_singular: "result found"
  results_found_plural: "results found"
  no_results: "No results found"
  try_again: "Please try different search terms"
post_type:
  article: "Article"
  page: "Page"
  job_posting: "Job Posting"
en.yml

Bonus: SCSS Styling the Pagination

Add these styles for the pagination, which includes WCAG-compliant touch targets and proper visual styling. Here is an example scss file:

.search-pagination {
  display: flex;
  color: black;

  .list-pagination {
    margin: 2rem auto;
    display: flex;
    flex-wrap: wrap;
    gap: 0;
    justify-content: center;
  }

  .pagination__item {
    display: flex;
    align-items: center;
    justify-content: center;
    position: relative;

    a,
    button {
      @include buttonReset;
      text-decoration: none;
      color: inherit;

      // WCAG-compliant touch target size
      width: 4.8rem;
      height: 4.8rem;

      display: flex;
      align-items: center;
      justify-content: center;
      padding: 0;
      z-index: 1;
      position: relative;

      span {
        font-weight: 600;
        font-size: 2rem;
        line-height: 1;
        font-family: sans-serif;
      }

      &::before {
        z-index: -1;
        content: '';
        display: flex;
        position: absolute;
        width: 90%;
        height: 90%;
        border-radius: 50%;
        background-color: lightgray;
        outline: none;
        transition: all .3s ease-in-out;
      }

      &[disabled] {
        opacity: 0.5;
        cursor: initial;
      }

      &:not([disabled]) {
        cursor: pointer;

        &:focus-visible,
        &:hover {
          color: white;
          &::before {
            background-color: black;
          }
        }
      }
    }

    &--active {
      a,
      button {
        font-size: 2.2rem;
        font-weight: 700;
        color: white;
        &::before {
          background-color: black;
        }
      }
    }
  }
}
search-pagination.scss

Conclusion

This implementation provides a clean and user-friendly search experience with:- Responsive search form- Clear results display- Proper handling of no results- Internationalization support- Clean separation of concerns using includes.

Remember to customize the styling to match your theme's design system. You can also extend the search functionality by adding filters, categories, or other advanced features using the new search engine capabilities.

Need help?

Do you have any question which is not answered in this knowledge base? Contact us. We are here to help you.