# Advanced markdown table layout renderer

**URL:** <https://discourse.gohugo.io/t/advanced-markdown-table-layout-renderer/56829>\
**Category:** tips & tricks\
**Tags:** markdown-attributes\
**Created:** [March 9, 2026, 8:06am UTC](https://discourse.gohugo.io/t/advanced-markdown-table-layout-renderer/56829 "2026-03-09T08:06:38Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![djibe](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/djibe/32/11341_2.png) [@djibe](https://discourse.gohugo.io/u/djibe)\
**Post date:** [March 9, 2026, 8:06am UTC](https://discourse.gohugo.io/t/advanced-markdown-table-layout-renderer/56829/1 "2026-03-09T08:06:38Z")

</div>

Hi, inspired by awesome @jmooring , here is an advanced `render-table.html` with the following features for advanced markdown tables, with a single line of parameters under the table

## Features

- Default markdown tables (heading, alignment)
- Automatic table counting (Table 1, Table 2, 3, …)
- HTML5 header `scope="col"`
- Custom HTML `id`
- Custom CSS class
- Table wrapper for better design (border radius, responsive, a11y)
- Table `caption`
- Structured data (JSON+LD)

## Table example

```auto
| Month | Savings |
| ----- | ------- |
| January | $250 |
| February | $80 |
| March | $420 |
{caption="Table title" id="table-hero" class="table-wrap"}

```

## Table renderer

and the `layouts/_default/_markup/render-table.html` renderer

```html
{{ $tnumber := add 1 $.Ordinal }}
{{- $userClass := .Attributes.class | default “” }}
{{ with .Attributes.caption }}{“@context”: “https://schema.org","@type”: “Table”,“about”: “{{ . | markdownify }}”}{{ end }}
<div class="data-table" role="region" tabindex="0" {{ with .Attributes.caption }}aria-labelledby="caption-{{ $tnumber }}" {{ end }}>
<table class="table {{ if $userClass }} {{ $userClass }}{{ end }}"
    {{- range $k, $v := .Attributes }}
      {{- if and $v (ne $k "caption") (ne $k "class") }}
        {{- printf " %s=%q" $k $v | safeHTMLAttr }}
      {{- end }}
    {{- end }}>
  {{- with .Attributes.caption }}
  <caption id="caption-{{ $tnumber }}">
    <strong>Tableau {{ $tnumber }}.</strong> {{ . | $.Page.RenderString }}.
  </caption>
  {{- end }}
  <thead>
    {{- range .THead }}
      <tr>
        {{- range . }}
          <th scope="col"
            {{- with .Alignment }}
              {{- printf " style=%q" (printf "text-align: %s" .) | safeHTMLAttr }}
            {{- end -}}
          >
            {{- .Text -}}
          </th>
        {{- end }}
      </tr>
    {{- end }}
  </thead>
  <tbody>
    {{- range .TBody }}
      <tr>
        {{- range first 1 . }}
          <th scope="row"
            {{- with .Alignment }}
              {{- printf " style=%q" (printf "text-align: %s" .) | safeHTMLAttr }}
            {{- end -}}
          >
            {{- .Text -}}
          </th>
        {{- end }}
        {{- range after 1 . }}
          <td
            {{- with .Alignment }}
              {{- printf " style=%q" (printf "text-align: %s" .) | safeHTMLAttr }}
            {{- end -}}
          >
            {{- .Text -}}
          </td>
        {{- end }}
      </tr>
    {{- end }}
  </tbody>
</table>
</div>

```

---

<div class="post-metadata">

**Author:** ![frjo](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/frjo/32/18626_2.png) [@frjo](https://discourse.gohugo.io/u/frjo)\
**Post date:** [March 10, 2026, 10:59am UTC](https://discourse.gohugo.io/t/advanced-markdown-table-layout-renderer/56829/2 "2026-03-10T10:59:11Z")

</div>

This is nice! Will likely add this to my Zen theme collection of example render hooks.

One really minor thing, you could replace the wrapper div with a section-tag. If the section tag is named, e.g. with a “aria-labelledby”, it will automatically get a role of “region”.

I also think “markdownify” can be replaced with “.Page.RenderString”.

---

<div class="post-metadata">

**Author:** ![djibe](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/djibe/32/11341_2.png) [@djibe](https://discourse.gohugo.io/u/djibe)\
**Post date:** [March 16, 2026, 8:37am UTC](https://discourse.gohugo.io/t/advanced-markdown-table-layout-renderer/56829/3 "2026-03-16T08:37:47Z")

</div>

Thanks.

Improved table render is:

```html
{{ $tnumber := add 1 $.Ordinal }}
{{- $userClass := .Attributes.class | default "" }}
{{ with .Attributes.caption }}<script type="application/ld+json">{"@context": "https://schema.org","@type": "Table","about": "{{ . | $.Page.RenderString }}"}</script>{{ end }}
<section class="data-table" tabindex="0" {{ with .Attributes.caption }}aria-labelledby="caption-{{ $tnumber }}" {{ end }}>
<table class="table {{ if $userClass }} {{ $userClass }}{{ end }}"
    {{- range $k, $v := .Attributes }}
      {{- if and $v (ne $k "caption") (ne $k "class") }}
        {{- printf " %s=%q" $k $v | safeHTMLAttr }}
      {{- end }}
    {{- end }}>
  {{- with .Attributes.caption }}
  <caption id="caption-{{ $tnumber }}">
    <strong>Tableau {{ $tnumber }}.</strong> {{ . | $.Page.RenderString }}.
  </caption>
  {{- end }}
  <thead>
    {{- range .THead }}
      <tr>
        {{- range . }}
          <th scope="col"
            {{- with .Alignment }}
              {{- printf " style=%q" (printf "text-align: %s" .) | safeHTMLAttr }}
            {{- end -}}
          >
            {{- .Text -}}
          </th>
        {{- end }}
      </tr>
    {{- end }}
  </thead>
  <tbody>
    {{- range .TBody }}
      <tr>
        {{- range first 1 . }}
          <th scope="row"
            {{- with .Alignment }}
              {{- printf " style=%q" (printf "text-align: %s" .) | safeHTMLAttr }}
            {{- end -}}
          >
            {{- .Text -}}
          </th>
        {{- end }}
        {{- range after 1 . }}
          <td
            {{- with .Alignment }}
              {{- printf " style=%q" (printf "text-align: %s" .) | safeHTMLAttr }}
            {{- end -}}
          >
            {{- .Text -}}
          </td>
        {{- end }}
      </tr>
    {{- end }}
  </tbody>
</table>
</section>

```

---

<div class="post-metadata">

**Author:** ![djibe](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/djibe/32/11341_2.png) [@djibe](https://discourse.gohugo.io/u/djibe)\
**Post date:** [May 3, 2026, 9:23pm UTC](https://discourse.gohugo.io/t/advanced-markdown-table-layout-renderer/56829/4 "2026-05-03T21:23:27Z")

</div>

Hi.

Wrapping with a section tag leads to a HTML lint warning: “Section lacks heading. Consider using “h2”-“h6” elements to add identifying headings to all sections, or else use a “div” element instead for any cases where no heading is needed.”

What do you think ?

---

<div class="post-metadata">

**Author:** ![frjo](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/frjo/32/18626_2.png) [@frjo](https://discourse.gohugo.io/u/frjo)\
**Post date:** [May 4, 2026, 6:29am UTC](https://discourse.gohugo.io/t/advanced-markdown-table-layout-renderer/56829/5 "2026-05-04T06:29:21Z")

</div>

Section does not have to have a heading, but it is recommended. Switching back to a div is an easy solution.

---

<div class="post-metadata">

**Author:** ![djibe](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/djibe/32/11341_2.png) [@djibe](https://discourse.gohugo.io/u/djibe)\
**Post date:** [May 4, 2026, 5:53pm UTC](https://discourse.gohugo.io/t/advanced-markdown-table-layout-renderer/56829/6 "2026-05-04T17:53:27Z")

</div>

I’ll stick to section then.  
Thank you very much.

---

<div class="post-metadata">

**Author:** ![system](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/system/32/1_2.png) [@system](https://discourse.gohugo.io/u/system)\
**Post date:** [May 6, 2026, 5:54pm UTC](https://discourse.gohugo.io/t/advanced-markdown-table-layout-renderer/56829/7 "2026-05-06T17:54:18Z")

</div>

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.
