Search code examples
javascriptjekylljekyll-extensions

Search by 2D position (distance) in Jekyll blog


I have a Jekyll site for which I use the Simple-Jekyll-Search library to provide searching.

The site is a catalogue composed of many entries characterized, among other things, by their (x, y) position. This is what my search.md file looks like:

---
layout: page
title: Search
permalink: /search/
---

<div id="search-container">
    <input type="text" id="search-input" placeholder="Search the catalogue...">
    <ul id="results-container"></ul>
</div>

<script src="{{ site.baseurl }}/assets/simple-jekyll-search.min.js" type="text/javascript"></script>

<script>
    SimpleJekyllSearch({
    searchInput: document.getElementById('search-input'),
    resultsContainer: document.getElementById('results-container'),
    searchResultTemplate: '<div style="text-align: left !important;"><a href="{url}"><h1 style="text-align:left !important;">{title}</h1></a></div>',
    json: '{{ site.baseurl }}/search.json'
    });
</script>

This works perfectly for word-based searches, but I need a way to also search by distance, i.e.:

  • the user gives a 2D position (x, y)
  • the library displays all the entries in the catalogue whose position (stored in a file somewhere) is within this region that is defined by the (x, y) coordinates plus a fixed search radius.

This site is a great example of what I'm after. Can this be done with some off-the-shelf library? (I can't code in JS)


Solution

  • Simple-Jekyll-Search is made for text-based searches and cannot handle spatial searches by (x, y) coordinates. You can add custom JavaScript, for example:

    // Load the catalogue entries from a JSON file
    var catalogueEntries;
    $.getJSON('{{ site.baseurl }}/catalogue.json', function(data) {
        catalogueEntries = data;
    });
    
    // Function to perform the spatial search
    function searchByDistance(x, y, radius) {
        var results = [];
        for (var i = 0; i < catalogueEntries.length; i++) {
            var entry = catalogueEntries[i];
            var distance = Math.sqrt(Math.pow(x - entry.x, 2) + Math.pow(y - entry.y, 2));
            if (distance <= radius) {
                results.push(entry);
            }
        }
        return results;
    }
    
    // Example usage: search for all entries within a 10-unit radius of (3, 4)
    var results = searchByDistance(3, 4, 10);
    console.log(results);
    

    Another alternative search library could be https://github.com/DavidJVitale/jekyll-leaflet

    The above example uses jQuery, learn more about getJSON and how you add jQuery: