2

Hi I'm trying to access elements from the previous and next arrays. To be exact I want to access the previous and next url of pages. This is what I have done so far.Thanks!

{% assign page_venue = site.data.venues-array | where: "venueID",   page.venue | first %
//This outputs the current url
{{venue.url}}

This is part of the yml file:

venueID: Red-Radish
name: Red Radish
url: redradish
building: 65
neighborhood: University Union

venueID: Poly-Deli
name: Poly Deli
url: polydeli
building: 19
neighborhood: University Union

venueID: Myrons
name: Myron's
url: myrons
previous: MustangStation
building: 19
neighborhood: University Union

So let's say I'm the second venue (Poly-Deli), I would like to see this:
Current url: polydeli
Previous url: reddish
Next url: myrons
I tried using the following to output the previous and next urls but it dindn't work:

<p>{{page.next.url}}</p>
<p>{{venue.next.url}}</p>
<p>{{paginate.next.url}}</p>
<p>{{paginator.next_page}}</p>

Someone helped me, and it did work, but it outputs the whole list. I just want to output something like this because this because I have 30 arrays(30 different venues):
Current url: polydeli
Previous url: reddish
Next url: myrons

And this is the code that outputs the whole list:

{% for venue in site.data.venues-array %}

  {% assign next = forloop.index0 | plus: 1 %}
  {% assign previous = forloop.index0 | minus: 1 %}
    <div>Name: {{ venue.name }}</div>
    <div>Current URL: {{ venue.url }}</div>

    <div>Previous url:{{ site.data.venues-array[previous].url }}</div>
    <div>Next URL is:{{ site.data.venues-array[next].url }}</div>
    <hr>

{% endfor %} 
Keith Mifsud
  • 1,599
  • 1
  • 16
  • 26
Charlie805
  • 169
  • 1
  • 11
  • 2
    Good question @Charlie805 :) I looked into it in more detail earlier today and concluded that the only way to apply this without developing a plugin that paginates data collections is to use JS. Is this something you know how to do or you'd like me to help? JS will need to loop through the venues and only show the current index plus the prev and next URL.The next / prev URL will show the next / prev array item in DOM...etc... – Keith Mifsud Jul 24 '18 at 10:11
  • Thanks keith, but i don't know how I would do that with JS. Can you please help me with that ? – Charlie805 Jul 24 '18 at 18:42

1 Answers1

2

As I've mentioned in my previous comment, I was not able to find a suitable plugin to paginate a _data collection. There are a few available but all require a lot of hacking plus they are quite bloated for such a simple requirement.

You can add the following HTML and JS to the content part of your venues page. (I.e. underneath the front-matter).

HTML:

---
---
<div class="venue">

</div>

JavaScript:

<script type="text/javascript">

  /**
   * Setting for whether to keep looping or not.
   * If set to true, the first venue will show the URL of the last venue as
   * the previous venue, while the last venue will show the URL of the first
   * venue as the next one.
   *
   * If set to false, the first venue will not include a previous URL, while the last venue * * won't display the next URL.
   */
  var infinite = true

  // Gets all the venues adta and parses it as JSON.
  var venues = '{{ site.data.venues-array | jsonify }}'
  venues = JSON.parse(venues)


  // Inits the html content.
  var html = ''

  // The array index of the current venue.
  var currentVenueIndex = 0

  /**
   * Displays the current venue. Includes the previous and next links.
   *
   */
  var generateHtmlForCurrentVenue = function (venueName) {
    var venueContent = '<p>Current Venue Name: ' + venueName + '</p>' +

    getPreviousLink() + getNextLink()

    html = venueContent
  }

  /**
   * Gets the previous URL link unless we're not infinitely looping and the
   * current Venue is the first item in the array.
   */
  var getPreviousLink = function () {
    link = ''
    if (!infinite&& currentVenueIndex == 0) {
      return link
    }
    previousIndex = 0
    if (currentVenueIndex == 0) {
      previousIndex = (venues.length - 1)
    } else {
      previousIndex = (currentVenueIndex - 1)
    }

    return '<p>Previous: <a href="#" class="previous-venue">' +
      venues[previousIndex].url + '</a></p>'

  }

  /**
   * Gets the next URL link unless we're not infnitely looping and the
   * current Venue is the last item in the array.
   */
  var getNextLink = function () {
    link = ''
    if (!infinite&& currentVenueIndex >= (venues.length -1)) {
      return link
    }
    nextIndex = 0
    if (!(currentVenueIndex >= (venues.length - 1))) {
      nextIndex = (currentVenueIndex + 1)
    }
    return '<p>Next: <a href="#" class="next-venue">' +
      venues[nextIndex].url + '</a></p>'
  }


  /**
   * Shows the Previous Venue.
   */
  var showPreviousVenue = function () {
    if (currentVenueIndex == 0) {
      currentVenueIndex = (venues.length -1)
    } else {
      currentVenueIndex --
    }
    $('.venue').html('')
    generateHtmlForCurrentVenue(venues[currentVenueIndex].name)
    $('.venue').html(html)
  }

  /**
   * Shows the Next Venue.
   */
  var showNextVenue = function () {
    if (currentVenueIndex == (venues.length -1)) {
      currentVenueIndex = 0
    } else {
      currentVenueIndex ++
    }
    $('.venue').html('')
    generateHtmlForCurrentVenue(venues[currentVenueIndex].name)
    $('.venue').html(html)
  }

  /**
   * Previous venue link click event handler.
   */
  $(document.body).on('click', '.previous-venue', function (event) {
    event.preventDefault()
    showPreviousVenue()
  })


  /**
   * Next venue link click event handler.
   */
  $(document.body).on('click', '.next-venue', function (event){
    event.preventDefault()
    showNextVenue()
  })

  generateHtmlForCurrentVenue(venues[currentVenueIndex].name)

  $('.venue').html(html)

</script>

You can change whether to keep looping or not by toggling the infinite variable as explained in the code's comments.

Please note:

I have an older version of Jekyll on my system (v3.0.2) and thus the jsonify filter breaks when there are single quotes in the text values of the venues-array.yml. I.e. Myron's breaks and I could not escape it as shown below: enter image description here

If you have the Jekyll >= 3.2 then I believe you will not have this issue as Jekyll will automatically use the UTF-8 encoding in advance of running the filter. I cannot upgrade my machine due to a client's site requiring this version and without a Docker container. If you do have this issue, try:

1) Enforce UTF-8 on your yml file. or 2) Clean up single quotes in advance of the filter or 3) Don't use single quotes :)

Escaping did not work for me.

Other than that, all works perfectly as shown below:

enter image description here

Keith Mifsud
  • 1,599
  • 1
  • 16
  • 26
  • Thanks Keith, but for some reason nothing outputs :( – Charlie805 Jul 25 '18 at 19:18
  • 2
    Hi Charlie. please check your browser console for any errors or if jQuery is missing. It's also possible that you have the same issue with the single quote(s) in venues' names. If so, this will also be show in the browser console errors. I'll add a screenshot to the answer so that you know what should be outputted. – Keith Mifsud Jul 26 '18 at 02:41
  • 1
    It's works now. It wasn't working because I was calling a layout that didn't have the JQuery link. Thanks a lot Keith! :). I really appreciate it. – Charlie805 Jul 26 '18 at 05:17
  • Glad I could help :) – Keith Mifsud Jul 26 '18 at 09:22