published on 29.08.2020

My experience with Hugo has been pretty good so far. It’s fast and flexible. Ever since I started using Hugo, I’ve been improving my website with small tweaks. In this post, I am going to share some tricks and workarounds I’ve found online while working with Hugo. Besides that, I’ll that links that I’ve found useful.

Post Summary

Hugo’s .Summary function provides an easy built-in solution for displaying post summaries. Yet, it has some flows. Hugo suggests 3 ways of generating a summary. Manual splitting and front-matter options are cumbersome. So, the summary function seems handy but it doesn’t always do well. It includes lists and headings. It can’t handle code-fences. Luckily, I’ve found a better solution created by Yihui Xie.


online but Hugo already has _internal/pagination.html. These partials are for buttons and links that create the navigation. Also, you need to paginate the Pages in a loop.

You can either use .Paginator function or .Paginate function. The first one is the result of the second one, and a shortcut is provided for convenience. .Paginator is created by Hugo, and supported on homepage and list pages since it’s using the .Pages function. On the other hand, we can tell which pages we want to gather and paginate by using the .Paginate function.

Here is the simplest form of pagination:

{{ range (.Paginate .Pages).Pages }}
      {{.Title}} //Display post info, link here.
{{ end }}

{{ partial "pagination.html" . }} // Include pagination partial.

You’ll probably use more detail about posts, include links to it, instead of .Title alone. I use another partial I’ve created.

// Another example with custom $pages
{{ $pages := where $.Site.RegularPages ".Type" "!=" "ordinary" }}
{{ $pages = where $pages ".Section" "not in" (slice "karalama" "projects") }}
{{ range (.Paginate $pages).Pages }}

// Of course, you can sort pages however you like.
{{ range (.Paginate (.Pages.ByParam "episode").Reverse).Pages }}
  1. Pagination Original Docs
  2. Pagination Partial Codepen

In Hugo, you really should use the built-in feature for gathering related posts. Because it’s easy and fast. I’m not gonna make this post longer than it should be. I display 2 sections under my posts. One is, related posts generated by Hugo, and the other one is next/previous posts in the same section. I’ll come to the latter later.

To use the related indices, you need to add these lines to your config file, it’s explained in the docs. I don’t add “category” here, because I don’t use “category” taxonomy. Since there is only one indice I use, the weight parameter becomes redundant too. Anyway…

  threshold = 10
  includeNewer = true
  toLower = true
    name = "tags"
    weight = 90

Now you need to gather the related posts on a post’s page. So, you’ll probably use this code in the single.html template.

{{ $related :=  .Site.RegularPages.RelatedIndices . "tags" | first 3 }}

You may want to filter out ordinary pages like /about /contacts and use something like this:

{{ $posts := where .Site.RegularPages "Section" "blog"}}
{{ $related := $posts.RelatedIndices . "tags" | first 3 }}

In my case, I use the code below and also added a backup strategy. It’ll display the latest posts if there is no $related found.

{{ $posts := where .Site.RegularPages "Section" "!=" "" }}
{{ $related := $posts.RelatedIndices . "tags" | first 3 }}

{{ if eq (len $related) 0 }}
      {{ $related = $posts.ByDate | first 3 }}
{{ end }}

Easy enough. Now, the second part: next/previous posts. You are probably using category taxonomy but I use sections to categorize my posts. Each post has a parameter named episode which specifies its order in the section. For example, this is the 14th post in Hugo section.

Here is how I get the previous/next episodes.

 {{ $posts := where $.Site.RegularPages ".Section" $.Section }}
 {{ $posts := where $posts ".Title" "!=" $.Title }}

  {{ $prePosts := where $posts ".Params.episode" "lt" $.Params.episode }}
  {{ $prePosts := $prePosts.ByParam "episode" | last 2 }}

  {{ $nextPosts := where $posts ".Params.episode" "gt" $.Params.episode }}
  {{ $nextPosts := $nextPosts.ByParam "episode" | first 2 }}

After that, all we need to do is loop through them.

{{ range $nextPosts }}
      <li><span>#{{ .Params.episode }}</span><a href="{{ .RelPermalink }}">{{.Title}}</a></li>
{{ end }}

Something similar can be done with category and date instead of section and episode.

You are reading the 15th of 19 episodes in Hugo.
Published on 29.08.2020 by Mert Bakır with commit de81d3f.
#hugo #pagination #static-site
Next episode:
Group by - Data Files in Hugo
published on 18.09.2020

First of all, if you don’t know about data files, you may want to start reading from data files in hugo. This post is about a solution for a very particular problem. How can we use “group by” for the data from data files? Let me clarify with an example. I was creating a single page …

published on 29.11.2020
edited on 05.12.2020

Plotly is a visualization library that allows us to write code in Python, R, or Julia and generates interactive graphs using Javascript. So, we don’t have to deal with Javascript. You can checkout Plotly gallery, there are interesting works. Anyway, last week, I’ve started learning …

published on 23.01.2021

Image processing may seem complicated at first but it’s actually easy and definitely worth implementing since it’ll help you decrease page load times. As you probably know, we don’t want to load raw images with huge sizes for small thumbnails or blog-posts. We want to load a small …

published on 10.07.2022

Previously, I’ve published a blog post about deploying static content on heroku with basic authentication. The main purpose was to get basic auth for a freely hosted static website. In that post, we hosted the source code on GitLab and configured a CI/CD pipeline to render the static content …

published on 28.05.2022

Each git commit has a field called Author which consists ‘’ and ‘’. We usually set these variables once, after installing git, with git config --global so that each repo gets the variables from the global definition. We can also set them locally for a …

published on 25.05.2022

In this post, I’ll first walk through hosting static content with basic authentication. Then, we’ll look into deploying to Heroku using GitLab Pipelines, more specifically deploying a certain sub-directory within the project instead of pushing the whole project. Also, I’ll share …

published on 17.04.2022
edited on 15.07.2022

Önceki bölümde, markdown formatını LaTeX formatına dönüştürmek için kullanılan Pandoc yazılımından bahsetmiştik. Şimdi konuyu bir adım daha ileri taşıyıp ve bookdown’a geçiyoruz. Bookdown; Rmarkdown kullanarak teknik dökümanlar, kitaplar yazabilmemizi sağlayan, Yihui Xie tarafından yazılmış …

published on 10.04.2022

I’ve been using WSL-2 on Windows for over a year. It’s very useful because some Python packages are just a headache to install on Windows. Also, docker. It’s just better on Linux. Yet, WSL-2 can also be problematic. I remember trying a dual-boot setup when things just went way too …

published on 03.03.2022

In this post, I’ll share how to install geopandas and some other gis related packages on Windows. If you are on Mac or Linux you can probably just pip install those without any issue. I usually had to do a google search every time I wanted to install these packages on Windows environment. Of …