How to create tables more simpler without markdown

I need to make tables which can be fully bendable from the content files.

I don’t want to use the regular markdown tables since they are really limited in design.
So firstly what I thought was to use {{ range }}

This is kinda my concept of what I’d like it to look like in the content page:

[[ Table ]]
  Title = "1"
  Title = "2"
 [[ Table Row ]]
   data = "A1"
   data = "B2"
 [[ Table Row ]]
   data = "C1"
   data = "D2"

In markdown this would show up like this:

1 2
A1 B2
C1 D2

My first efforts was the header section done like this :

 <tr>
	 {{ range .Params.table }}
			<th>
				{{ .title }}
	        	</th>
		{{ end }}
</tr>

But this means I would have to call out [[ table ]] for every title I need.

as for the table-Datarows, it’s even more confusing since essentially
I need the freedom of adding how many rows I need AND also inside those rows have the freedom of adding how many data points I need so a .range inside a .range?

How would I go by doing this most efficiently?

   Name | Age
--------|------
    Bob | 27
  Alice | 23

I specifically mentioned I want to create a table input form where I would use the hugo lang instead of markdown, mainly since wiriting out :
seems to be a lot more of a hassle than just adding variables.

Name | Age
--------|------
    Bob | 27
  Alice | 23

You could create a table data file at data/table.toml:

[table]
  [[row]]
  data = ["Animal", "Sound"]
  [[row]]
  data = ["Cat", "Meow"]
  [[row]]
  data = ["Dog", "Woof"]

Then in your template:

{{ $.Scratch.Set "count" 0 }}
<table>
{{ range $table := .Site.Data.table }}  
  {{ range $row := $table }}
    <tr>
    {{ range $datas := $row }}
      {{ range $data := $datas }}
        {{ if eq 0 ($.Scratch.Get "count") }}
        <th> 
          {{ . }}
        </th>
        {{ else }}
        <td> 
          {{ . }}
        </td>
        {{ end }}
      {{ end }}
    {{ end }}
    </tr>
    {{ $.Scratch.Add "count" 1 }}
  {{ end }}
{{ end }}
</table>

Which would output this:

Animal Sound
Cat Meow
Dog Woof
2 Likes

This is good, but say I would have multiple pages, each page would have different data in the table fields, one option i guess would have multiple tables in my Data folder but how would i call them out on each page separately?

You could use a shortcode, and move the template logic within the shortcode.


For example, say the shortcode is named layouts/shortcodes/table.html.

Define it like:

{{ $arg := .Get 0 }}
{{ $dataFile := index .Site.Data $arg }}
{{ $.Scratch.Set "count" 0 }}

<table>
{{ range $table := $dataFile }}  
  {{ range $row := $table }}
    <tr>
    {{ range $datas := $row }}
      {{ range $data := $datas }}
        {{ if eq 0 ($.Scratch.Get "count") }}
        <th> 
          {{ . }}
        </th>
        {{ else }}
        <td> 
          {{ . }}
        </td>
        {{ end }}
      {{ end }}
    {{ end }}
    </tr>
    {{ $.Scratch.Add "count" 1 }}
  {{ end }}
{{ end }}
</table>

Then use it like:

{{< table "sample" >}}

Where "sample" is the name of your table data file, e.g. data/sample.toml.

6 Likes

Switch fom markup to CSV or JSON
Store it under /assets

I used it like this

{{ $file := .Params.datafile}}{{ $data := getJSON $file }}
   {{ range sort $data.items "title"}}
   <!-- generate the table here -->
   {{end}}
{{ end }} 

definition in frontmatter

datafile = "/assets/data/table1.json"

CSV work in the same way
Best to create a shortcode to render a table

1 Like

@ju52 – Besides user preference, what is the advantage of storing the table data file as CSV or JSON, vs TOML as per the initial question?

So after a little bit of fiddling around I figured what i could do.

I’m gonna go for @zwbetz suggestion of shortcodes.
So I can make as many table data-structures as I want, all i need to do is
from the front matter call the shortcode and pass the table data I want like this:

{{< table “table1” >}}

This means I need to edit this line :

{{ range $table := .Site.Data.table1 }}

I need to catch an argument and add it to what right now is the tables place.
I understand I have to use positional parameters inside the .md file the question is how would I translate this into the .html file?

@EricTalv – I’ve edited my reply above with an example shortcode definition.

1 Like

no big differences, to process use getJSON or getCSV
I like the more clean data formats:

JSON

{
  "items": [
    {
	"animal" : "Cat",
	"sound": "Meow"
	},
	{
	"animal" : "Dog",
	"sound": "Woof"
	}
  ]
}

CSV

Animal;Sound
Cat; Meow
Dog;Woof

I see. Yeah CSV is much more terse.