Skip to main content

Search in a theme

The search engine is chosen in the layout's Search settings: Nexus Search, Algolia or Coveo. Your theme provides the search box, and Paligo provides everything else: the index, the scripts that run the search, and a search results page. The theme works with every search engine without changes.

Add the search box

Place paligo_search_box() where the search box goes:

{{ paligo_search_box() }}

By default, results drop down under the box as the reader types, with a link to see all results. For the search results page, use paligo_search_box('page'), which lists the results on the page, keeps the search in the page address, and shows taxonomy filters when the layout has them turned on.

{# templates/search.html.twig #}
{% extends 'base.html.twig' %}
{% block content %}
    <main>
        <h1>{{ page.title }}</h1>
        {{ paligo_search_box('page') }}
    </main>
{% endblock %}

When the layout has no search engine, paligo_search_box() produces nothing and no search page is published.

Style the search box

The search box and its results use these classes:

Class

Element

site-search

The whole search box. data-search-mode is dropdown or page.

site-search__form

The form.

site-search__input

The text field.

site-search__clear

The button that clears the text field.

site-search__panel

The area that holds the results.

site-search__status

The line that says how many results there are.

site-search__results

The list of results.

site-search__result, site-search__result-link, site-search__result-title, site-search__result-excerpt

One result, its link, title and excerpt. The search words in the excerpt are in <mark>.

site-search__sub, site-search__sub-link

Matching headings within a result.

site-search__all

The link to all results, in a dropdown.

site-search__more

The button that loads more results, on the search page.

site-search__facets

The taxonomy filters, on the search page.

The highlighted result has the class is-active.

Write your own search box

You can write the search box's HTML yourself, for example to add your own icon or button, or to put it in a different structure. Paligo's search script finds every element with the class site-search on the page, connects it to the layout's search engine and fills in the results. Your markup only has to use the class names the script looks for.

This example writes the search box once, as a macro, and uses it in two places: as a dropdown in the header of every page, and as a full search on the search results page.

templates/partials/search-box.html.twig:

{% macro box(mode, id, placeholder, strings) %}
<div class="site-search" data-search-mode="{{ mode }}">
  <form class="site-search__form" role="search" method="get" action="search.html">
    <input class="site-search__input" type="search" name="q" autocomplete="off"
        placeholder="{{ placeholder }}" aria-label="{{ placeholder }}"
        {%- if mode == 'dropdown' %} role="combobox" aria-expanded="false" aria-controls="{{ id }}-panel" aria-autocomplete="list"{% endif %}>
    <button type="button" class="site-search__clear" hidden aria-label="{{ strings.clearSearch|default('Clear search') }}">&times;</button>
  </form>
  <div class="site-search__panel" id="{{ id }}-panel"{% if mode == 'dropdown' %} hidden{% endif %}>
    <p class="site-search__status" role="status" aria-live="polite"></p>
    <ul class="site-search__results"></ul>
    {% if mode == 'dropdown' %}
      <a class="site-search__all" hidden></a>
    {% else %}
      <button type="button" class="site-search__more" hidden>{{ strings.searchMore|default('Load more results') }}</button>
    {% endif %}
  </div>
  {% if mode == 'page' %}
    <div class="site-search__facets" hidden></div>
  {% endif %}
</div>
{% endmacro %}

The macro takes the mode (dropdown or page), an ID that is unique on the page, the placeholder text and the theme's texts. The ID connects the text field to its results, so that screen readers can announce them.

templates/base.html.twig, with the header search in a block of its own:

{% import 'partials/search-box.html.twig' as search %}
<!doctype html>
<html lang="{{ site.lang }}"{% if site.dir %} dir="{{ site.dir }}"{% endif %}>
<head>
    <meta charset="utf-8">
    <title>{% block title %}{{ page.title }} | {{ site.title }}{% endblock %}</title>
    {{ paligo.head }}
</head>
<body>
    <header>
        {% block header_search %}
            {% if site.search.backend|default('none') != 'none' %}
                {{ search.box('dropdown', 'header-search', site.strings.searchPlaceholder|default('Search'), theme.strings) }}
            {% endif %}
        {% endblock %}
        {% include 'partials/language-menu.html.twig' %}
    </header>
    {% block content %}{% endblock %}
    {{ paligo.foot }}
</body>
</html>

templates/search.html.twig, which empties the header search, because the page has its own:

{% extends 'base.html.twig' %}
{% import 'partials/search-box.html.twig' as search %}
{% block header_search %}{% endblock %}

{% block content %}
    <main>
        <h1>{{ page.title }}</h1>
        {{ search.box('page', 'search-page', site.strings.searchPlaceholder|default('Search'), theme.strings) }}
    </main>
{% endblock %}

The search results page uses the address search.html, which is the action of the form. If the reader can't run scripts, the form still opens the search results page.

Paligo checks a theme's search box when the theme is uploaded:

  • These parts are required, and a missing one is an error: a <form class="site-search__form"> with an action, a site-search__input field named q, a site-search__panel and a site-search__results.

  • These parts are recommended, and a missing one is a warning: data-search-mode set to dropdown or page, a site-search__status and a site-search__clear, a site-search__all in a dropdown, and a site-search__more and site-search__facets on the search page.

Translate the search texts

The search texts are in English unless your theme's translation files provide these keys. See Translate a theme.

Key

Text

clearSearch

The name of the clear button.

searchMore

The button that loads more results.

searchAll

The link to all results. [COUNT] is replaced by the number of results.

searchPage

The name of the search results page.

searchNone, searchOne, searchMany

The result count. [COUNT] is the number and [SEARCH_TERM] the search.

searchFilters

The heading of the filters.

searchUnavailable

Shown when search can't be loaded.

searchError

Shown when a search fails.

Keep page furniture out of the index

Nexus Search indexes the whole page. To leave a part of the page out of the index, such as a navigation menu or a footer, add data-pagefind-ignore to it:

<nav class="sidebar" data-pagefind-ignore>…</nav>