File: csv-to-table.md

package info (click to toggle)
jekyll 4.4.1%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 6,488 kB
  • sloc: ruby: 16,736; javascript: 1,455; sh: 216; xml: 29; makefile: 9
file content (213 lines) | stat: -rw-r--r-- 4,673 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
---
title: Tabulate CSV Data
author: MichaelCurrin
date: 2020-04-01 20:30:00 +0200
---

This tutorial shows how to use Jekyll to read a CSV and render the data as an HTML table.

This approach will:

- use the CSV's first row as the HTML table header.
- use remaining rows for the body of the table.
- preserve the order of the columns from the original CSV.
- be flexible enough to work with _any_ valid CSV that is referenced.

There is no need to specify what the names of the columns are, or how many columns there are.
The trick to this tutorial is that, when we iterate over the row data, we pick up the _first row_
and unpack that so we can get the header names.

Follow the steps below to convert a sample CSV of authors into an HTML table.


## 1. Create a CSV

Create a CSV file in your [Data files]({{ '/docs/datafiles/' | relative_url }}) directory so
that Jekyll will pick it up. A sample path and CSV data are shown below:

`_data/authors.csv`

```
First name,Last name,Age,Location
John,Doe,35,United States
Jane,Doe,29,France
Jack,Hill,25,Australia
```

That data file will now be available in Jekyll like this:

{% raw %}
```liquid
{{ site.data.authors }}
```
{% endraw %}


## 2. Add a table

Choose an HTML or markdown file where you want your table to be shown.

For example: `table_test.md`

```yaml
---
title: Table test
---
```

### Inspect a row

Grab the first row and see what it looks like using the `inspect` filter.

{% raw %}
```liquid
{% assign row = site.data.authors[0] %}
{{ row | inspect }}
```
{% endraw %}


The result will be a _hash_ (an object consisting of key-value pairs) which looks like this:

```ruby
{
  "First name"=>"John",
  "Last name"=>"Doe",
  "Age"=>"35",
  "Location"=>"United States"
}
```

Note that Jekyll _does_ in fact preserve the order here, based on the original CSV.


### Unpack a row

A simple solution would be to hardcode the field names when looking up the row values by key.

{% raw %}
```liquid
{{ row["First name"] }}
{{ row["Last name"] }}
```
{% endraw %}

But we prefer a solution that will work for _any_ CSV, without specifying the column names upfront.
So we iterate over the `row` object using a `for` loop:

{% raw %}
```liquid
{% assign row = site.data.authors[0] %}
{% for pair in row %}
  {{ pair | inspect }}
{% endfor %}
```
{% endraw %}

This produces the following. Note the first item in each pair is the _key_ and the second will be
the _value_.

```
["First name", "John"]
["Last name", "Doe"]
["Age", "35"]
["Location", "United States"]
```

### Create a table header row

Here we make a table with a single table row (`tr`), made up of table header (`th`) tags. We find
the header name by getting the first element (at index `0`) from `pair`. We ignore the second
element as we don't need the value yet.

{% raw %}
```liquid
<table>
  {% for row in site.data.authors %}
    {% if forloop.first %}
    <tr>
      {% for pair in row %}
        <th>{{ pair[0] }}</th>
      {% endfor %}
    </tr>
    {% endif %}
  {% endfor %}
</table>
{% endraw %}
```

For now, we do not display any content from the second row onwards. We achieve this by using
`forloop.first`, since this will return true for the _first_ row and false otherwise.


### Add table data rows

In this section we add the data rows to the table. Now, we use the second element of `pair`
to find the value.

For convenience, we render using the `tablerow` tag - this works like a `for` loop, but the inner
data will be rendered with `tr` and `td` HTML tags for us. Unfortunately, there is no equivalent for
the header row, so we must write that out in full, as in the previous section.

{% raw %}
```liquid
---
title: Table test
---

<table>
  {% for row in site.data.authors %}
    {% if forloop.first %}
    <tr>
      {% for pair in row %}
        <th>{{ pair[0] }}</th>
      {% endfor %}
    </tr>
    {% endif %}

    {% tablerow pair in row %}
      {{ pair[1] }}
    {% endtablerow %}
  {% endfor %}
</table>
```
{% endraw %}


With the code above, the complete table would look like this:

<table>
  <tr>
    <th>First name</th>
    <th>Last name</th>
    <th>Age</th>
    <th>Location</th>
  </tr>
  <tr>
    <td>John</td>
    <td>Doe</td>
    <td>35</td>
    <td>United States</td>
  </tr>
  <tr>
    <td>Jane</td>
    <td>Doe</td>
    <td>29</td>
    <td>France</td>
  </tr>
  <tr>
    <td>Jack</td>
    <td>Hill</td>
    <td>25</td>
    <td>Australia</td>
  </tr>
</table>

That's it - you can now turn a CSV into an HTML table using Jekyll.

## Next steps

- Change the field names in the CSV.
- Choose a different CSV.
- Add CSS styling to your table.
- Render the table using a JSON or YAML input file.