Hugo

How to Customise Tables

Hello.

I’m wondering if it’s possible to customise the table code generated by Hugo via CSS?

I’ve tried the path of going with shortcodes and while doing so, I’ve used .Inner but I couldn’t really achieve what I wanted and seems a bit like a hack.

Content:

{{< table >}}
| Disk 0 | Disk 1 | Disk 2 | Disk 3 |
|:------:|:------:|:------:|:-------:|
|   A1   |   A2   |   A3   | Ap(1-3) |
|   A4   |   A5   |   A6   | Ap(4-6) |
|   B1   |   B2   |   B3   | Bp(1-3) |
|   B4   |   B5   |   B6   | Bp(4-6) |
{{< table />}}

table.html:

<div class="table">
	  {{ .Inner }}
</div>

When I performed the above, the markdown table code was still present in the generated static web page and moreover, the above doesn’t give me granular control over the table.

Am I missing something or currently Hugo doesn’t support such a thing?

I don’t know what “granular control” means in this context, but you might try {{ .Inner | markdownify }}. More info at https://gohugo.io/functions/markdownify/.

If all you need is a class, you can add markup: mmark in frontmatter and use the following:

{.table}
| Disk 0 | Disk 1 | Disk 2 | Disk 3 |
|:------:|:------:|:------:|:-------:|
|   A1   |   A2   |   A3   | Ap(1-3) |
|   A4   |   A5   |   A6   | Ap(4-6) |
|   B1   |   B2   |   B3   | Bp(1-3) |
|   B4   |   B5   |   B6   | Bp(4-6) |

Need a div around it?

<div class="table">

| Disk 0 | Disk 1 | Disk 2 | Disk 3 |
|:------:|:------:|:------:|:-------:|
|   A1   |   A2   |   A3   | Ap(1-3) |
|   A4   |   A5   |   A6   | Ap(4-6) |
|   B1   |   B2   |   B3   | Bp(1-3) |
|   B4   |   B5   |   B6   | Bp(4-6) |

</div>

Should work.

Another option is to build your table from a data file.
For an example, see How to create tables more simpler without markdown

Sorry for the late reply, been busy.

With granular control over a table, I meant being able to style each and every table element: <table>, <tr>, <th>, etc. Is there a way to do so?

In order to solve the problem with my shortcode, I could do @maiki 's advise but I still don’t get granular control over the table.

@zwbetz raises a good point, however, I don’t want to store my tables in separate files when I can have them inline with the content in the first place. IMHO, it greatly messes my file/folder structure and reduces my efficiency as I have to move around different files when I could be working with just a single one.

Currently @brunoamaral 's solution of using mmark is a good temporary solution.

Since my theme makes use of Bootstrap CSS, initially, I want to make use of their table styling. Hence, as their documentation suggests, the below code should style a table with their styling:

<!-- Table -->
<table class="table">
  ...
</table>

That’s why I mentioned wrapping the table with the style table in my question. However, I made the mistake of wrapping it in a <div> instead of a <table>. Although, currently, when I wrap my tables in <table>s as I suggested above, the MD table inside doesn’t get rendered as @brunoamaral suggests. I’ve also tried wrapping them inside <div>s. Why is that?

Just curious, why is mmark temporary? I am using the code below and it render a nice stripped table in bootstrap:

{.table .table-striped}
|            PATREON PLEDGE            | 1€   | 5€   | 7€   |
|:------------------------------------ |:----:|:----:|:----:|
| Early Access to Articles             | ✓    | ✓    | ✓    |
| Hints for CryptoNovel Puzzles        | ✓    | ✓    | ✓    |
| Access to Patreon Feed               | ✓    | ✓    | ✓    |
| Small Listing On The Site As A Patron|      | ✓    | ✓    |
| Suggestions of New Content           |      | ✓    | ✓    |
| Request of a Research Article        |      |      | ✓    |
| Listed As A Full Sponsor             |      |      | ✓    |

Not a deal breaker but I don’t want to depend on mmark and have to add additional code to style my tables even though it’s just a small piece of code.

I want Hugo to be able to directly retrieve my custom styling. And if I want a different styling for a specific table, I want to define it as a Hugo shortcode since I find that’s more convenient.

Since you guys are using Bootstrap to style your tables, this shortcode should work. Write your table in markdown, then pass the desired classes as an arg.

Usage:

{{< table "table table-striped" >}}
| Animal  | Sounds |
|---------|--------|
| Cat     | Meow   |
| Dog     | Woof   |
| Cricket | Chirp  |
{{</ table >}}

Definition:

{{ $htmlTable := .Inner | markdownify }}
{{ $class := .Get 0 }}
{{ $old := "<table>" }}
{{ $new := printf "<table class=\"%s\">" $class }}
{{ $htmlTable := replace $htmlTable $old $new }}
{{ $htmlTable | safeHTML }}

Threw a little write-up on the blog too

2 Likes

@ju52 This would “double up” the <table> tags. So if I’m understanding you correctly, the output would be:

<table class="tabclass">
<table>
...
</table>
</table>

Thanks for your effort @zwbetz , that’s great to have!

Although, I still want to be able to style the default rendering of Hugo generated HTML tables without any additional stuff but I’ll settle for now.

At some point, additional code is needed to style your tables, no?


Another way to do this is using a front matter param and JS. You may feel this method is less intrusive.

Let’s say your content looked like this:

---
tableClasses: ["table", "table-striped", "table-dark"]
---

| Animal  | Sounds |
|---------|--------|
| Cat     | Meow   |
| Dog     | Woof   |
| Cricket | Chirp  |

Then in your template, check if the param has a value, then loop through the table classes and use JS (jQuery in this case) to add each class to the table:

{{ with .Params.tableClasses }}
<script>
  var table = $("table");
  {{ range . }}
  table.addClass("{{ . }}");
  {{ end }}
</script>
{{ end }}

Note, this assumes you only have one table in your content. Smarter logic would need to be added to handle multiple tables.

@can please clarify what you mean.

The thing I’m trying to say is that once there is a table in a post or another content, without any other styling option(whether it be mmark or a shortcode), Hugo fits it with a default styling of it’s own which can’t be touched.

Whereas in my opinion, I should be able to change Hugo’s default styling by merely providing the table styling inside the theme. I should use mmark or shortcodes for additional styling options.

Of course additional styling is required to style your tables :slight_smile: but I should provide a default to Hugo.

Give an example of what you mean by this. Because to me, style in this context is dependent on the CSS library being used.

1 Like

Sample Post Content:

Donec id elit non mi porta gravida at eget metus. Aenean lacinia bibendum nulla sed consectetur. Nullam quis risus eget urna mollis ornare vel ePreformatted textu leo. Nulla vitae elit libero, a pharetra augue. Cras justo odio, dapibus ac facilisis in, egestas eget quam.

Donec id elit non mi porta gravida at eget metus. Aenean lacinia bibendum nulla sed consectetur. Nullam quis risus eget urna mollis ornare vel eu leo. Nulla vitae elit libero, a pharetra augue. Cras justo odio, dapibus ac facilisis in, egestas eget quam.

[A_TABLE]

Donec id elit non mi porta gravida at eget metus. Aenean lacinia bibendum nulla sed consectetur. Nullam quis risus eget urna mollis ornare vel eu leo. Nulla vitae elit libero, a pharetra augue. Cras justo odio, dapibus ac facilisis in, egestas eget quam.

[ANOTHER_TABLE]

Donec id elit non mi porta gravida at eget metus. Aenean lacinia bibendum nulla sed consectetur. Nullam quis risus eget urna mollis ornare vel eu leo. Nulla vitae elit libero, a pharetra augue. Cras justo odio, dapibus ac facilisis in, egestas eget quam.

{{< table “table table-striped” >}}
| Animal | Sounds |
|---------|--------|
| Cat | Meow |
| Dog | Woof |
| Cricket | Chirp |
{{</ table >}}

Sample Hugo Directory:

  • Hugo_dir
    • themes
      • [THEME_NAME]
        • assets
          • table.css

Explanation:
Because of the filing structure, Hugo would automatically retrieve the above table.css styling(due to it’s location and naming) and apply it to [A_TABLE] and [ANOTHER_TABLE]. However, because the third table above uses @zwbetz 's solution, it would retrieve the custom classes defined rather than the default. In that case, @zwbetz 's solution could also be integrated into Hugo itself.

Reasoning:
IMHO, it seems a bit weird to me that Hugo allows the modification of every aspect of a theme but the tables. Hence, the tables require one of the above solutions.

Especially @zwbetz 's last solution is pretty sweet but I think by default I should be able to style my tables without getting into shortcodes or other stuff.

You can change the shortcode to add an ID for the table and use this ID in CSS.

https://www.w3schools.com/csSref/sel_id.asp

I’m confused what you mean here. What is stopping you from using the assets/table.css that you mentioned?

Nothing.

When I first asked this question, I had such a CSS file, BUT once my I generated my website, the styles for the tables weren’t being read and the tables were being displayed with their browser default styling. Hence I had to ask this question and resort to your shortcode solution.

I see. This is a CSS related issue then. Because that should work fine. (Bootstrap uses CSS to style tables too)

1 Like