Amy Westlake

< Back to blog

Using Jekyll Data and jQuery for tabbed content

Jekyll Data

For the pub website I am currently working on I need a way of storing main menu information with item descriptions and prices.

For easy content management I wanted to store menu items in the form of a data file. I have multiple menu sections (main menu, breakfast menu, desserts etc) so in my data folder I created a new menus folder and inside multiple data files named a-breakfast.yml, b-light-meals.yml etc. The lettering at the beginning is to ensure that the menus are output in the order I wish, I did try to use an order liquid tag for this but couldn’t get it working. Not sure if this is even possible so I’m happy to stick with my lettering work around for now.

In each data folder we have basic info and the data itself, as demonstrated below.

title: "Breakfast"
info: "Served between 9am - 11am"
items:
  - item: "Big Breakfast"
    desc: "kljadfhsg"
    price: "£6.95"
  - item: "Big Veggie Breakfast"
    desc: "kljadfhsg"
    price: "£6.95"
  - item: "Small Breakfast"
    desc: "kljadfhsg"
    price: "£5.95"
  - item: "Small Veggie Breakfast"
    desc: "kljadfhsg"
    price: "£5.95"

Liquid Templating

For the design I want to use a jQuery tab implementation. A list of menus at the top and when clicked (active) the menu content is shown below. This requires two for loops, one for the menu titles (the tabs along the top) and one for the menu items (the content underneath).


<ul class="tabs">
  {% for menu in site.data.menus %}
    {% assign tab = menu[1]%}
      <li class="tab-link {% if {{forloop.index}} == 1 %}current{% endif %}" data-tab="tab{{forloop.index}}">
          {{ tab.title }}
      </li>
  {% endfor %}
</ul>

The forloop.index is needed to give the tab a unique number, basically a counter, which will connect each tab to its content.

Then to get the menu description and underneath each item and its price:


  {% for menuinfo in site.data.menus %}
    {% assign tabs = menuinfo[1] %}
    <div id="tab{{forloop.index}}" class="tab-content {% if {{forloop.index}} == 1 %}current{% endif %}">
        {{tabs.info}}
        <br/>
        {% for item in tabs.items %}
          <p class="menu-item">{{item.item}}</p>
        {% endfor %}
    </div>
  {% endfor %}

The if statement {% if {{forloop.index}} == 1 %}current{% endif %} is required so that the first tab is active/visible when first loaded, and the other tabs are hidden.

jQuery

The jQuery is pretty straight forward for this. Get the number of the selected tab then toggle the classes on the tab title and the tab content.

$('ul.tabs li').click(function(){
  var tab_id = $(this).attr('data-tab');
  $('ul.tabs li').removeClass('current');
  $('.tab-content').removeClass('current');

  $(this).addClass('current');
  $("#"+tab_id).addClass('current');
});

That’s pretty much it! It will obviously require styling but that is dependent on each project and not really worth documenting here. All you basically need is for the .current class to be display:block and the default tabs.li to be display:none.


< Back to blog