Order posts by lastmod>date (with pagination)

I’m looking for a way to display posts ordered in such a way that if I set lastmod in frontmatter manually it will act as a date, so the post will appear higher in a loop. I don’t need to set lastmod automatically via config, just manual updates, so users can see freshly updated articles higher in the loop.

To visualize this, the order should be something like that:

  • date 01 Jan
  • date 02 Jan
  • lastmod 03 Jan (no matter what date)
  • date 04 Jan
  • date 05 Jan

Right now lastmod is not respected by the loop:

// loop
{{ $paginator := .Paginate .Site.RegularPages }}
{{ range $index, $page := $paginator.Pages }}
   // content 
{{ end }}

{{ partial "paginator" . }}

// paginator partial
{{ $pages := $.Paginator }}
{{ if gt $pages.TotalPages 1 }}
   // pagination
{{ end }}
{{ $p := site.RegularPages.ByLastmod.Reverse }}
{{ range (.Paginate $p).Pages }}
  <h2><a href="{{ .RelPermalink }}">{{ .Title }}</a></h2>
{{ end }}

I have tried that and unfortunately, it does nothing. Just in case, here is my config:

date = ["date"]
lastmod = ["lastmod"] // respect only values explicitly set via frontmatter 

With this config, if you sort by lastmod, the pages without lastmod will have an indeterminate sort.

When I tested the code above I did not change the front matter configuration from its default.

Please remove this from the configuration and try again.


Ok, that works now, but now Hugo is setting lastmod automatically for all the posts. This is something I don’t need because the business wants to pick which post to update and promote, and with this setup even changing one letter will put the post on top of the loop.

I’m thinking about some kind of arrays of merge/sort to achieve this, if it’s not possible with standard functions, but I guess I will still could use a little help with this.

I am unable to reproduce this.

Try it.

git clone --single-branch -b hugo-forum-topic-42495 https://github.com/jmooring/hugo-testing hugo-forum-topic-42495
cd hugo-forum-topic-42495
hugo server

Perhaps you have enableGitInfo = true in your site configuration, in which case the last modified date is extracted from the Git commit info. See docs.

If the purpose of this is to promote (or “pin to top”) one or more pages, have you considered simply adding promote = true to front matter?

{{ $p1 := where site.RegularPages "Params.promote" true }}
{{ $p2 := site.RegularPages | complement $p1 }}
{{ $p := $p1 | append $p2 }}
{{ range (.Paginate $p).Pages }}
  <h2><a href="{{ .RelPermalink }}">{{ .Title }}</a></h2>
{{ end }}

Now that’s awkward. Your project works just fine. But mine is not, despite the fact that I’ve deleted everything related from the config file and I am using your code:

{{ $p := site.RegularPages.ByLastmod.Reverse }}
{{ range (.Paginate $p).Pages }}
  <h2><a href="{{ .RelPermalink }}">{{ .Title }}</a></h2>
{{ end }}

It would be helpful if you shared your project, privately if you wish.

1 Like

In the process of creating a minimal working demo, I was able to locate the suspect in my header partial:

 {{ if  .Paginator }}
    <link rel="canonical" href="{{ .Paginator.URL }}">
        {{ if .Paginator.HasNext }}
        <link rel="next" href="{{ .Paginator.Next.URL }}" />
        {{ if .Paginator.HasPrev }}
        <link rel="prev" href="{{ .Paginator.Prev.URL }}" />
    {{ end }}

Removing that resolves all problems :slight_smile:
The only question right now is how to keep that prev/next functionality?

You need to paginate before referencing the .Paginator properties.

This describes the problem in a little more detail:

This describes a strategy (with example) for doing what you want to do:

1 Like

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