Working with pairs of pages


#1

I need to work with two list elements at a time, treating the first and second of each pair differently. Specifically, I want to output the data from one page to the left and the data from the second in the pair to the right in an HTML table. How can I accomplish this in a hugo template?

Here is a “pseudo-code” example of what I’m trying to achieve:

<table>

{{ range $i, $pair := .Pages.SplitIntoPairs }}

  <tr>
    <td>{{ $pair.first.Title }}</td>
    <td>{{ $pair.second.Title }}</td>
  </tr>

{{ end }}

</table>

#2

What exactly are you trying to achieve with this - what data are you outputting?

If it’s some sort of custom data, you probably want to use data files. Otherwise, if you’re displaying page metadata, I’d recommend using something a little more responsive than plain tables, which look terrible on mobile devices.

If you instead used floating divs or, even better, flex boxes, you could create an identical element for every page, then with CSS configure them to fit however many to a row as you like. That number can then change depending on the screen size, so you never take up too much or too little space.

I do this with taxonomy terms in my own theme, BluestNight:

<ul id="taxonomy-list" class="row">
      {{- $data := .Data -}}
      {{ range $key, $val := .Data.Terms.Alphabetical }}
      <div class="row-item small-full medium-half large-third">
        <li class="taxonomy-item">
          {{- $.Scratch.Set "link" "/" -}}
          {{- $.Scratch.Add "link" $data.Plural -}}
          {{- $.Scratch.Add "link" "/" -}}
          {{- ($.Scratch.Add "link" $val.Name) -}}
          <a href="{{ $.Scratch.Get "link" | urlize | absLangURL }}">{{ $val.Name }}</a> ({{ $val.Count }})
        </li>
      </div>
      {{ end }}
    </ul>
.row, .menu {
  display: -webkit-flex;
	display: flex;
	-webkit-flex-direction: row;
	flex-direction: row;
  flex-wrap: wrap;
  justify-content: flex-start;
  align-items: stretch;
}
.row-item {
  padding: 0 5px;
  display: block;
}
.taxonomy-item {
  list-style-type: none;
}
.small-full {
  flex: 0 0 100%;
  width: 100%;
  max-width: 100%;
}
@media only screen and (min-width: 640px) {
  .medium-half {
    flex: 0 0 50%;
    width: 50%;
    max-width: 50%;
  }
}
@media only screen and (min-width: 1024px) {
  .large-third {
    flex:  0 0 33.33333%;
    width: 33.33333%;
    max-width: 33.33333%;
  }
}

The CSS classes operate basically the same as the Bootstrap ones, but without having to include Bootstrap in your site. You can see an example of this code in action here