jekyllliquid

Display images one at a time in a Jekyll website


I want to display several images one at a time in a sequential manner in a Jekyll based website. However, I am able to display the first image of the list only with the following code.

<script>
function showNextImage() {
  var totalImages = {{ site.image_urls | size }};
  var currentIndex = {{ current_image_index }};
  
  if (currentIndex < totalImages - 1) {
    currentIndex++;
  } else {
    currentIndex = 0;  
  }
  document.querySelector('img').src = '{{ site.image_urls[current_index] }}';
  document.getElementById('current_image_index').value = currentIndex;
  return currentIndex;
}
</script>

{% assign current_image_index = 0 %}
{% if site.image_urls.size > 0 %}
  <img src="{{ site.image_urls[current_image_index] }}" alt="Image" width="100%">
  <button onclick="showNextImage()">Next</button>
  <input type="hidden" id="current_image_index" value="{{ current_image_index }}">
{% endif %}

I have stored the images in _config.yml as follows

image_urls:
  - /images/pic1.jpeg
  - /images/pic2.jpg
  - /images/pic3.jpg

It seems the Next button of the code is not working. I would appreciate any help in detecting the bug in the mentioned code.


Solution

  • Liquid is a template engine used by Jekyll and it processes the code on the server before it is sent to the browser. When the page is loaded in the browser, Liquid does not execute again, and the value {{ site.image_urls[current_index] }} cannot be dynamically updated by JavaScript.

    JavaScript needs to be able to handle the dynamic parts entirely on the client.

    1. Create a JavaScript array imageUrls that contains all image URLs.
    2. Change the function to use the JavaScript array for cycling through the images.
    <script>
    var imageUrls = [
      {% for image_url in site.image_urls %}
        "{{ image_url }}",
      {% endfor %}
    ];
    
    function showNextImage() {
      var totalImages = imageUrls.length;
      var currentIndex = parseInt(document.getElementById('current_image_index').value, 10);
      
      if (currentIndex < totalImages - 1) {
        currentIndex++;
      } else {
        currentIndex = 0;
      }
    
      document.querySelector('img').src = imageUrls[currentIndex];
      document.getElementById('current_image_index').value = currentIndex;
    }
    
    </script>
    
    {% assign current_image_index = 0 %}
    {% if site.image_urls.size > 0 %}
      <img src="{{ site.image_urls.first }}" alt="Image" width="100%">
      <button onclick="showNextImage()">Next</button>
      <input type="hidden" id="current_image_index" value="{{ current_image_index }}">
    {% endif %}