I'm trying to make a single markdown page with Jekyll and Liquid-Shopify that displays parametric content. It's a dictionary project: there is one page with 26 links (A | B | C | ... | Y | Z), and clicking on a letter brings me on one single page but displays only the words beginning by the letter I clicked on.
It would be easy with query strings, but Jekyll doesn't handle them. I wanted to assign a Jekyll variable to a Javascript value, but Javascript is executed after Jekyll.
The main page:
---
layout: default
permalink: /main/
---
[A]({{ link_for_A }})
[B]({{ link_for_B }})
[C]({{ link_for_C }})
...
[Y]({{ link_for_Y }})
[Z]({{ link_for_Z }})
The letter page:
---
layout: default
permalink: /letter/
---
{% comment %} Here I'd like to assign a variable called letter, chosen according to which link I clicked on, i.e. if I clicked on A link on the main page, then letter = A {% endcomment %}
{% assign sorted_post = site.posts | sort: 'title' %}
{%- for post in sorted_post -%}
{% assign first_letter = post.name | slice: 0, 1 | capitalize %}
{%- if first_letter == letter -%}
Content
{% endif %}
{% endfor %}
I assume each post is for a different entry, and the name of this entry is in post.name
.
By clicking on any letter on the main page, the new page would show me only the words beginning with this letter, but the same page is used thanks to a simple if condition. This would prevent creating 26 different pages, one for each letter.
Despite my searches, I found nothing on this website or in the other Jekyll related websites.
Thank you for your help.
Depending on how many entries you're looking at, it may be more advantageous to load all of the entries into one page and filter what is actually displayed in the DOM using Javascript. So really, you'd have your main page look the same, but also have the list below it:
---
layout: default
permalink: /main/
---
<a class="letters" onclick="expand('A')">A</a>
<a class="letters" onclick="expand('B')">B</a>
<a class="letters" onclick="expand('C')">C</a>
...
<a class="letters" onclick="expand('Y')">Y</a>
<a class="letters" onclick="expand('Z')">Z</a>
{%- for post in sorted_post -%}
<a href="{{post.url}}" data-letter="{{post.name | slice: 0, 1 | capitalize}}" hidden>
{{post.title}}
</a>
{% endfor %}
You could then hide all of the sorted posts and a simple script would allow you to show and hide all entries for each letter. This is probably the easiest combination of Jekyll and JS that I can think of. Here is the script that would show and hide the words:
function expand(letter) {
const words = document.querySelectorAll('.word');
words.forEach(word =>word.style.display = (word.dataset.letter === letter) ?'inline-block' :'none');
}
Here is a working model of what the output HTML would look like:
function expand(letter) {
const words = document.querySelectorAll('.word');
words.forEach(word => word.style.display = (word.dataset.letter === letter) ? 'inline-block' : 'none');
}
.word {
display: none;
}
<div>
<a class="letters" onclick="expand('A')">A</a>
<a class="letters" onclick="expand('B')">B</a>
<a class="letters" onclick="expand('C')">C</a>
<a class="letters" onclick="">...</a>
<a class="letters" onclick="expand('Y')">Y</a>
<a class="letters" onclick="expand('Z')">Z</a>
</div>
<a href="#" class="word" data-letter="A">Apple</a>
<a href="#" class="word" data-letter="B">Banana</a>
<a href="#" class="word" data-letter="B">Boat</a>
<a href="#" class="word" data-letter="C">Cat</a>
<a href="#" class="word" data-letter="C">Car</a>
<a href="#" class="word" data-letter="C">Corral</a>
<a href="#" class="word" data-letter="Y">Yarn</a>
<a href="#" class="word" data-letter="Z">Zoo</a>