Crea un buscador para tu sitio web Hugo

2024-09-16

Este blog esta construido con Hugo, no todos los temas para Hugo incluyen una función de búsqueda para el propio blog, si tu tema preferido no incluye la función de buscar, en esta publicación te explicare como construir el tuyo.

En la documentación de Hugo, podemos encontrar varias herramientas, libres y de pago, en mi caso me he decido por utilizar el método explicado por https://blog.wains.be/2020/2020-06-02-hugo-search-lunr/

Fichero Configuración

Debemos de editar el fichero de configuración de Hugo config.toml y en la sección [outputs] añadimos:

[outputs]
  home = ["HTML", "RSS", "JSON"]
  page = ["HTML", "RSS"]

Plantilla

También debemos crear una plantilla JSON en ./layouts/_default/index.json con el código:

{{- $.Scratch.Add "index" slice -}}
{{- range .Site.RegularPages -}}
    {{- $.Scratch.Add "index" (dict "title" .Title "tags" .Params.tags "content" .Plain "href" .Permalink "date" ( .Date.Format "Jan 2, 2006" )) -}}
{{- end -}}
{{- $.Scratch.Get "index" | jsonify -}}

Tanto con la configuración como con la plantilla JSON, cuando construyamos nuestro sitio con Hugo se generará un fichero index.json en la raíz.

ls -lh /home/carlos/Descargas/prueba/public/index.*
-rw-r--r--. 1 carlos carlos 7,2K may 12 19:42 /home/carlos/Descargas/prueba/public/index.html
-rw-r--r--. 1 carlos carlos 1,5M may 12 19:44 /home/carlos/Descargas/prueba/public/index.json
-rw-r--r--. 1 carlos carlos 236K may 12 19:42 /home/carlos/Descargas/prueba/public/index.xml

Podemos comprobar si el fichero index.json contiene información apuntando directamente al fichero http://direccion/index.json donde direccion es la dirección ip o nombre de dominio de tu sitio web.

Página de búsqueda

Creamos la pagina de búsqueda en la ubicación content/search.md, con el código:

---
title: Buscar
---

<div>
<p><input id="search" type="text" placeholder="Introduce tu consulta"></p>

<ul id="results"></ul>

<script src="/js/jquery-2.1.3.min.js"></script>
<script src="/js/lunr.js"></script>
<script>
  var lunrIndex,
      $results,
      documents;

  function initLunr() {
    // retrieve the index file
    $.getJSON("../index.json")
      .done(function(index) {
          documents = index;

          lunrIndex = lunr(function(){
            this.ref('href')
            this.field('content')

            this.field("title", {
                boost: 10
            });

            this.field("tags", {
                boost: 5
            });

            documents.forEach(function(doc) {
              try {
                // console.log(doc.href)
                this.add(doc)
              } catch (e) {}
            }, this)
          })
      })
      .fail(function(jqxhr, textStatus, error) {
          var err = textStatus + ", " + error;
          console.error("Error getting Lunr index file:", err);
      });
  }

  function search(query) {
    return lunrIndex.search(query).map(function(result) {
      return documents.filter(function(page) {
        try {
          // console.log(page)
          return page.href === result.ref;
        } catch (e) {
          console.log('whoops')
        }
      })[0];
    });
  }

  function renderResults(results) {
    if (!results.length) {
      return;
    }

    results.slice(0, 30).forEach(function(result) {
      var $result = $("<li>");

      $result.append($("<a>", {
        href: result.href,
        text: result.title
      }));

      $result.append(" <small><time>" + result.date + "</time></small>");

      $results.append($result);
    });
  }

  function initUI() {
    $results = $("#results");

    $("#search").keyup(function(){
      // empty previous results
      $results.empty();

      // trigger search when at least two chars provided.
      var query = $(this).val();
      if (query.length < 2) {
        return;
      }

      var results = search(query);

      renderResults(results);
    });
  }

  initLunr();

  $(document).ready(function(){
    initUI();
  });
</script>
</div>

Bibliotecas javascript

Descargamos las bibliotecas javascript:

Y las guardamos en la carpeta ./static/js

ls -lh /home/carlos/Descargas/prueba/static/js/*
-rw-r--r--. 1 carlos carlos 83K may  9 22:51 /home/carlos/Descargas/prueba/static/js/jquery-2.1.3.min.js
-rw-r--r--. 1 carlos carlos 98K may  9 22:51 /home/carlos/Descargas/prueba/static/js/lunr.js

Barra de menú

Crea en el menú la entrada para la búsqueda

[[menu.main]]
name = "Buscar"
pageRef = "/search"
weight = 40

Resultado

Si ahora construimos nuestro sitio tendremos disponible nuestra página de búsqueda. A medida que vamos escribiendo en el campo de búsqueda se irán mostrando los resultados (lunr recorre el fichero json buscando el valor introducido)

Espero que te haya gustado, pasa un gran día 🐧


Ingrese la dirección de su instancia