Kristian Nordestgaard Kristian Nordestgaard - 1 month ago 5
HTML Question

Intelligent way to generate tables with Liquid from a CSV file?

Okay, I'll try to make it short.

I got an XML file from Musicbrainz. Then I converted it to CSV and replaced the

.
's with
_
's to make it work with Liquid.

I put
music.csv
in
_data
and call it with:

{% include music.html %}


_includes/music.html
looks (in part) like:

<table border="1" style="width:100%">
<tr>
<td>Artist</td>
<td>Track title</td>
</tr>
<tr>
{% if member.release_medium-list_medium_track-list_track_0_recording_artist-credit_name-credit_artist_name %}
<td>{{ member.release_medium-list_medium_track-list_track_0_recording_artist-credit_name-credit_artist_name }}</td>
{% endif %}

{% if member.release_medium-list_medium_track-list_track_0_recording_title %}
<td>{{ member.release_medium-list_medium_track-list_track_0_recording_title }}</td>
{% endif %}
</tr>

<tr>
{% if member.release_medium-list_medium_track-list_track_1_recording_artist-credit_name-credit_artist_name %}
<td>{{ member.release_medium-list_medium_track-list_track_1_recording_artist-credit_name-credit_artist_name }}</td>
{% endif %}

{% if member.release_medium-list_medium_track-list_track_1_recording_title %}
<td>{{ member.release_medium-list_medium_track-list_track_1_recording_title }}</td>
{% endif %}
</tr>
<tr>
{% if member.release_medium-list_medium_track-list_track_2_recording_artist-credit_name-credit_artist_name %}
<td>{{ member.release_medium-list_medium_track-list_track_2_recording_artist-credit_name-credit_artist_name }}</td>
{% endif %}

{% if member.release_medium-list_medium_track-list_track_2_recording_title %}
<td>{{ member.release_medium-list_medium_track-list_track_2_recording_title }}</td>
{% endif %}
</tr>


Now, clearly, this is not the best way to do it. What I'm after is something that:


  1. Looks for the relevant data

  2. If the data is there, creates the cells and fills them out.



I'm pretty sure this can be done with Liquid, but I have no idea how. Can someone here help?

EDIT: Turns out I forgot the CSV file -- here it is, on Pastebin.

EDIT 2: This Cheat Sheet might be of help!

Answer

The format of a CSV file inherently does not support repeated sections so I think it would be a bad fit for the variable length data format you are trying to use. I feel JSON is more appropriate for this use case as it can handle the structure of the source data you are trying to work with.

As a quick example I put the XML file you supplied through this converter to create a JSON version of the output. This was saved as "_data/music.json".

This liquid code was then used to parse this:

{% for item in site.data.music %}

    <h2> {{ item[1].release.title }}</h2>

    {% for medium in item[1].release.medium-list %}

    <h3> {{ medium[1].format }} </h3>

    <table border="1" style="width:100%">
        <tr>
            <td>Artist</td>
            <td>Track title</td>
        </tr>
        {% for track in medium[1].track-list.track %}
            <tr>
                <td>{{ track.recording.artist-credit.name-credit.artist.name }}</td>
                <td>{{ track.recording.title }}</td>
            </tr>
        {% endfor %}
    </table>
    {% endfor %}
{% endfor %}

This produces HTML like this (trimmed):

<h2> The Quatermass Film Music Collection</h2>    
<h3> CD </h3>
<table border="1" style="width:100%">
    <tr>
        <td>Artist</td>
        <td>Track title</td>
    </tr>
    <tr>
        <td>Tristram Cary</td>
        <td>Quatermass and the Pit: Opening Credits</td>
    </tr>    
    <tr>
        <td>Tristram Cary</td>
        <td>Quatermass and the Pit: Bones</td>
    </tr>
</table>

Based on this you should be able to produce the format you ultimately want.

Comments