Keep the same number of posts if a category is excluded from a list

Trying to migrate from Jekyll to Hugo.I am trying to exclude posts from one category from the homepage, but this is affecting the number of paginated posts defined in the config.toml file. I am using this code to filter out the category

{{ $paginator := .Paginate (where .Pages "Type" "posts") }} 
{{ range $i, $e := (where ($paginator.Pages) ".Params.Frontpage" "!=" "nil") }}

I have defined 12 posts per page, but some pages show less number of posts leaving gaps. I created a collection in Jekyll (outside _posts folder) to get around this, but I am not sure how to do ensure the number of posts remains the same per page in Hugo. I would appreciate any help to solve this?

Build the page collection, then paginate.

{{ $p := where (where site.RegularPages "Type" "posts") "Params.frontpage" "!=" nil }}
{{ range (.Paginate $p).Pages }}
  <h2><a href="{{ .RelPermalink }}">{{ .Title }}</a></h2>
{{ end }}

Notes:

  • Do not quote nil in your where statement
  • Get into the habit of using referring to your parameters (site and page) using lowercase (Params.foo instead of Params.Foo).

It seems that is not working. I have the frontpage: nil set as frontmatter in some posts in the same folder named “views”. My structure is content/posts/folder-name (about six folders).

You are using nil as a string, which is unwise because it is also a keyword. It will confuse you and anyone who looks at your code later on.

If you want to set a string front matter param to a falsey value, set it to an empty string.

If you must use nil as a string, change your where clause.

Do you mean I leave the front matter as frontpage: and not add anything after it? (I am just creating a simple blog and I really want this to work out).

If its a string:

frontpage: ''

If is a number:

frontpage: 0

If is a boolean:

frontpage: false

Or you can omit the value completely, as long you defend against its absence in your code.

Maybe I am doing something wrong, but I used this frontpage: '' with your code above and it did not work either. I am using custom pagination if that affects the buildup in any way, then I am not sure.

Edit: Perhaps this has something to do with it?

If you are going to set the value to an empty string, then query for the (not) empty string…

{{ $p := where (where site.RegularPages "Type" "posts") "Params.frontpage" "ne" "" }}
{{ range (.Paginate $p).Pages }}
  <h2><a href="{{ .RelPermalink }}">{{ .Title }}</a></h2>
{{ end }}

Didn’t work either. Is there somewhere I can share my current repo privately?

Send me a direct message, or invite me via GitHub/whatever.

I sent you a message.

You set frontpage to ' ' instead of ''.

I was using Notepad to Bulk replace. Might have been a typing issue. It worked! Thanks. Perhaps mark this as the solution.

Sorry. I was looking at my main site instead of localhost. I don’t know why it is not working locally.

Your site configuration file has several problems. Some material, some bad habits.

  1. Do not quote numbers.
    paginate = 12 not paginate = "12"

  2. Do not quote booleans.
    pluralizeListTitles = false not pluralizeListTitles = "false"

  3. Elements belonging to root table must appear before other tables. You have defined ignorefiles after another table.

  4. To disable a particular taxonomy, remove it from the taxonomies table. Your current configuration will produce indeterminate output. This is wrong:

    [taxonomies]
    category = "category"
    tags = ""
    

Most of those I got from the docs online when researching. I have corrected them, as per your guidelines, still, it does not work.

Edit: Could you kindly suggest a way to use the frontpage: false instead? I think maybe the quotes are not helping.

See https://gohugo.io/templates/pagination/

If you call .Paginator or .Paginate multiple times on the same page, you should ensure all the calls are identical. Once either .Paginator or .Paginate is called while generating a page, its result is cached, and any subsequent similar call will reuse the cached result. This means that any such calls which do not match the first one will not behave as written.

That’s the root of your problem. Once you fix that, you won’t need a frontpage param, because you’ve already set the ‘type’ on your view items to “views”.

These docs are not beginner-friendly at all. Lots of google searching on this issue also returned nothing. I can make it work without paginating, but I need paginate and the “params” fails to work unless used inside render, after the .Pages.

So what I am getting at is Hugo has no way to disable cache once it is set?

Rework your code. Do not paginate (with either .Paginator or .Paginate) more than once on a page.

I am lost now. Thanks for the effort though. The docs are not user friendly and I have been on this issue for more than three days.

Remove these lines from home-head:

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

And change your query to:

{{ $p := where site.RegularPages "Type" "posts" }}
{{ range (.Paginate $p).Pages }}
  ...
{{ end }}

Test this:

git clone https://github.com/jmooring/foo
cd foo
hugo server

I reduced the number of content pages to 12 (2 in each category), and reduced the number of pages per pager from 12 to 4. You should see 3 pagers with 10 pages total (the 2 views are omitted).