# How to filter pages on homepage based on page params

**URL:** <https://discourse.gohugo.io/t/how-to-filter-pages-on-homepage-based-on-page-params/1369>\
**Category:** support\
**Created:** [June 26, 2015, 5:04am UTC](https://discourse.gohugo.io/t/how-to-filter-pages-on-homepage-based-on-page-params/1369 "2015-06-26T05:04:26Z")\
**Posts on this page:** 19\
**Page:** 1

<div class="post-metadata">

**Author:** ![ashishthedev](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/ashishthedev/32/518_2.png) [@ashishthedev](https://discourse.gohugo.io/u/ashishthedev)\
**Post date:** [June 26, 2015, 5:04am UTC](https://discourse.gohugo.io/t/how-to-filter-pages-on-homepage-based-on-page-params/1369/1 "2015-06-26T05:04:27Z")

</div>

I have a working layout for home page which looks like this:

```auto
{{range first 10 .Paginator.Pages}}

```

However, there are certain pages which I dont want to show up on home page. So I define a specific `notOnHomePage` flag and ideally, when set on any post, it should not be shown in the homepage.

In font matter:

```auto
+++
...
notOnHomePage = "true"
+++

```

In index.html

```auto
...
{{range first 10 (where .Paginator.Pages ".Params.notOnHomePage" "!=" "true")}}

```

But now nothing gets shown on the home page and there is no error either while compiling hugo

Any help will be greatly appreciated.

---

<div class="post-metadata">

**Author:** ![ashishthedev](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/ashishthedev/32/518_2.png) [@ashishthedev](https://discourse.gohugo.io/u/ashishthedev)\
**Post date:** [June 26, 2015, 7:31am UTC](https://discourse.gohugo.io/t/how-to-filter-pages-on-homepage-based-on-page-params/1369/2 "2015-06-26T07:31:04Z")

</div>

Couple of updates:

1. Hugo expects the parameter to be written as “notonhomepage” in index.html template even though front matter defines it as “notOnHomePage”.

2. This is working:

```auto
{{range first 10 (where .Paginator.Pages ".Params.notonhomepage" "true")}}

```

i.e the only those pages which are not supposed to be shown are being rendered.  
Point is the above logical comparision is working. But I dont know how to inverse it.

Maybe hugo is silently failing on the pages where “notOnHomePage” is not defined.

Can someone tell me **how to inverse the logical comparison in above mentioned snippet**.  
I tried following but not working:

```auto
{{range first 10 (where .Paginator.Pages ".Params.notonhomepage" "!=" "true")}}

```

Thanks.

---

<div class="post-metadata">

**Author:** ![digitalcraftsman](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/digitalcraftsman/32/4142_2.png) [@digitalcraftsman](https://discourse.gohugo.io/u/digitalcraftsman)\
**Post date:** [June 26, 2015, 10:47am UTC](https://discourse.gohugo.io/t/how-to-filter-pages-on-homepage-based-on-page-params/1369/3 "2015-06-26T10:47:21Z")

</div>

You can do this with `not ( your condition )`.

I didn’t checked if it works, but try this snippet:

```
{{range first 10 (where .Paginator.Pages not(".Params.notonhomepage" "!=" "true"))}}
```

---

<div class="post-metadata">

**Author:** ![ashishthedev](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/ashishthedev/32/518_2.png) [@ashishthedev](https://discourse.gohugo.io/u/ashishthedev)\
**Post date:** [June 26, 2015, 1:23pm UTC](https://discourse.gohugo.io/t/how-to-filter-pages-on-homepage-based-on-page-params/1369/4 "2015-06-26T13:23:37Z")

</div>

Didn’t work.

In fact rest of the contents on home page also don’t get generated which suggests that **hugo is silently eating errors** which is bad.

---

<div class="post-metadata">

**Author:** ![bep](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/bep/32/3332_2.png) [@bep](https://discourse.gohugo.io/u/bep)\
**Post date:** [June 26, 2015, 3:16pm UTC](https://discourse.gohugo.io/t/how-to-filter-pages-on-homepage-based-on-page-params/1369/5 "2015-06-26T15:16:57Z")

</div>

@tatsushid knows the most about the where filter

@ashishthedev please file a GitHub issue about the “error eating”. Putting it in bold in a thread on a discussion forum doesnt’t solve it.

---

<div class="post-metadata">

**Author:** ![bep](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/bep/32/3332_2.png) [@bep](https://discourse.gohugo.io/u/bep)\
**Post date:** [June 26, 2015, 5:18pm UTC](https://discourse.gohugo.io/t/how-to-filter-pages-on-homepage-based-on-page-params/1369/6 "2015-06-26T17:18:45Z")

</div>

And it might help to read up on the documentation. In programming it often helps to do it exactly by the book:

> **[Functions Quick Reference](http://gohugo.io/functions/)**
>
> Comprehensive list of Hugo templating functions, including basic and advanced usage examples.

---

<div class="post-metadata">

**Author:** ![tatsushid](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/tatsushid/32/7219_2.png) [@tatsushid](https://discourse.gohugo.io/u/tatsushid)\
**Post date:** [June 26, 2015, 11:44pm UTC](https://discourse.gohugo.io/t/how-to-filter-pages-on-homepage-based-on-page-params/1369/7 "2015-06-26T23:44:14Z")

</div>

I think

```auto
{{range first 10 (where .Paginator.Pages ".Params.notonhomepage" "!=" "true")}}

```

would work if you also set `notOnHomePage = "false"` in any other pages.

`where` function searches the second parameter’s value and when the base parameter (in this case, `.Param`) is `map` type, it returns `zero Value` if there isn’t such a key in the map. `zero Value` is treated as a special case in a condition check in `where` function. It isn’t evaluated in it and always returns `false`

In this case, I guess you only have `notOnHomePage = "true"` so

```auto
{{range first 10 (where .Paginator.Pages ".Params.notonhomepage" "!=" "true")}}

```

returns `false` if it meets such a page and also returns `false` if there isn’t the key’s value in map, means nothing is rendered.

If adding `notOnHomePage = "false"` to other pages annoys you, I suggest simply adding `OnHomePage = "true"` and using

```auto
{{range first 10 (where .Paginator.Pages ".Params.onhomepage" "true")}}

```

---

<div class="post-metadata">

**Author:** ![tatsushid](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/tatsushid/32/7219_2.png) [@tatsushid](https://discourse.gohugo.io/u/tatsushid)\
**Post date:** [June 26, 2015, 11:53pm UTC](https://discourse.gohugo.io/t/how-to-filter-pages-on-homepage-based-on-page-params/1369/8 "2015-06-26T23:53:17Z")

</div>

It may be better to print “no such a key value” if `where` function can’t find a key’s value to help finding out what causes a problem.

---

<div class="post-metadata">

**Author:** ![ashishthedev](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/ashishthedev/32/518_2.png) [@ashishthedev](https://discourse.gohugo.io/u/ashishthedev)\
**Post date:** [June 27, 2015, 11:46am UTC](https://discourse.gohugo.io/t/how-to-filter-pages-on-homepage-based-on-page-params/1369/9 "2015-06-27T11:46:57Z")

</div>

The idea was that privacy and about pages are coming in my homepage.  
So I though I would just add “notOnHomePage” on these specific pages and filter them out.  
But as it turns out, the **“where” functionality is broken when this page specific parameter is not present** on normal pages.

Going the other way, i.e. having tag “OnHomePage = true” is not a good option as this really is the main workflow and not an exception. If I am going to write lets say 200 posts in coming future, it is better to put the tag on just 2 or 3 pages instead of on 200.

Hope that clarifies the use case.

Thanks.  
Github issue links:

> <https://github.com/gohugoio/hugo/issues/1232>
>
> Use Case:
> There are about 200 pages in the website.
> But some pages like "privacy", "about" and "terms and conditions" are appearing on...

  

> <https://github.com/gohugoio/hugo/issues/1233>
>
> Use Case:
> There are about 200 pages in the website.
> But some pages like "privacy", "about" and "terms and conditions" are appearing on...

---

<div class="post-metadata">

**Author:** ![tatsushid](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/tatsushid/32/7219_2.png) [@tatsushid](https://discourse.gohugo.io/u/tatsushid)\
**Post date:** [June 28, 2015, 10:34pm UTC](https://discourse.gohugo.io/t/how-to-filter-pages-on-homepage-based-on-page-params/1369/10 "2015-06-28T22:34:38Z")

</div>

I don’t think `where` behavior is wrong. Comparing with “not exist” value is impossible and I don’t want to write the same story about NULL in the SQL world here.

But mentioned above, it’s **highly inconvenient not to able to filter such values** and yes, I agree with you I also don’t want to write a parameter for filtering time and time.

So, how about introducing `nil` (NULL value in Go) comparison to `where`? In this case, the point is whether `notOnHomepage` parameter exists or not. If there is `nil` comparison, we can write

```auto
where .Paginator.Pages ".Params.notonhomepage" nil

```

or

```auto
where .Paginator.Pages ".Params.notonhomepage" "==" nil

```

To invert the result, just write

```auto
where .Paginator.Pages ".Params.notonhomepage" "!=" nil

```

`"param" "==" nil` means the parameter doesn’t exist. `"param" "!=" nil` means it exists.

According to [http://golang.org/pkg/text/template/](http://golang.org/pkg/text/template/), `nil` can be used in a template so it works. Actually, I’ve tested it could filter a particular article by the rules above and it worked good.

If this sounds reasonable, I’ll send PR

---

<div class="post-metadata">

**Author:** ![bep](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/bep/32/3332_2.png) [@bep](https://discourse.gohugo.io/u/bep)\
**Post date:** [June 29, 2015, 5:50am UTC](https://discourse.gohugo.io/t/how-to-filter-pages-on-homepage-based-on-page-params/1369/11 "2015-06-29T05:50:55Z")

</div>

- where behaves as I expect in this area. It is trivial to write a script that provides default values for historic content’s default values. New content would be handled by archetypes
- It would, however, be cool to have ´nil´ support, if not too much work

---

<div class="post-metadata">

**Author:** ![ashishthedev](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/ashishthedev/32/518_2.png) [@ashishthedev](https://discourse.gohugo.io/u/ashishthedev)\
**Post date:** [June 29, 2015, 8:56am UTC](https://discourse.gohugo.io/t/how-to-filter-pages-on-homepage-based-on-page-params/1369/12 "2015-06-29T08:56:05Z")

</div>

After sitting on this for a couple of days, I think I have a better solution.

**“where” should accept a predicate much like the “if” clause in python’s list comprehensions.**

```auto
newList = [x for x in oldList if x != nil]

```

That predicate should return a bool for each element in the list. If true, that page/node should be retained in the resulting list.

If I understand correctly, **“where” is the only construct which can alter/transform the default list(such as .Paginator.Pages) . And it is too limiting**. You can only check for one condition. If where can support the predicate functionality discussed above, the whole problem could have been gracefully solved in the following manner.

```auto
{{range first 10 (where .Paginator.Pages ( and (isset ".Params" notonhomepage) ( index .Params "notonhomepage" "!=" "true"))}}

```

The benefit of the predicate is that as an end user, I can have all the logic and can chain all the operations to filter out non-required pages.

Not sure if this will break backward compatibility, but will be super useful. If required, hugo should support this functionality even if it means implementing a new keyword apart from "where "(may be call it “if” or “filter”)

@spf13 and @bep may wanna comment on this “predicate” thing.

---

<div class="post-metadata">

**Author:** ![bep](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/bep/32/3332_2.png) [@bep](https://discourse.gohugo.io/u/bep)\
**Post date:** [June 29, 2015, 9:39am UTC](https://discourse.gohugo.io/t/how-to-filter-pages-on-homepage-based-on-page-params/1369/13 "2015-06-29T09:39:39Z")

</div>

First, where isnt’t the only way to transform the list – there is `first` and a few others.

Re. predicate,

The suggestion from @tatsushid is more in line with my world view.

---

<div class="post-metadata">

**Author:** ![tatsushid](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/tatsushid/32/7219_2.png) [@tatsushid](https://discourse.gohugo.io/u/tatsushid)\
**Post date:** [June 29, 2015, 10:54am UTC](https://discourse.gohugo.io/t/how-to-filter-pages-on-homepage-based-on-page-params/1369/14 "2015-06-29T10:54:28Z")

</div>

@bep, I’ve already wrote the patch for introducing `nil` comparison yesterday (not big, modified about 10 lines) so it’s easily added just sending PR and merging it.

@ashishthedev, yes, `where` can only check one condition. When I implemented it, I referred [Jekyll’s `where` template function](http://jekyllrb.com/docs/templates/) and made it have a similar syntax.

In current `where` limitation, to apply multi conditions to an array like your predicate case, it have to be written like following (with `nil` comparison)

```auto
where (where .Data.Pages ".Params.notonhomepage" "!=" nil) ".Params.notonhomepage" "!=" "true"

```

`where` just returns filtered list so it can be reused. I confirmed it worked with my `nil` comparison patched hugo.

BTW, the idea supporting predicate is interesting. I haven’t checked whether it’s possible to evaluate go template string in `where` so it worth considering. [http://golang.org/pkg/text/template/parse/](http://golang.org/pkg/text/template/parse/) and it’s source code or hugo’s shortcode implementation may tell that.

---

<div class="post-metadata">

**Author:** ![tatsushid](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/tatsushid/32/7219_2.png) [@tatsushid](https://discourse.gohugo.io/u/tatsushid)\
**Post date:** [June 29, 2015, 11:00am UTC](https://discourse.gohugo.io/t/how-to-filter-pages-on-homepage-based-on-page-params/1369/15 "2015-06-29T11:00:06Z")

</div>

The example above may displayed in two or more lines but I wrote it in a line. Of course, it can also be written

```auto
$filtered := where .Data.Pages ".Params.notonhomepage" "!=" nil
where $filtered ".Params.notonhomepage" "!=" "true"

```

---

<div class="post-metadata">

**Author:** ![ashishthedev](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/ashishthedev/32/518_2.png) [@ashishthedev](https://discourse.gohugo.io/u/ashishthedev)\
**Post date:** [June 29, 2015, 11:25am UTC](https://discourse.gohugo.io/t/how-to-filter-pages-on-homepage-based-on-page-params/1369/16 "2015-06-29T11:25:20Z")

</div>

> [@tatsushid](#):
>
> ```auto
> where (where .Data.Pages ".Params.notonhomepage" "!=" nil) ".Params.notonhomepage" "!=" "true"
> 
> ```

Wow. This looks very promising. Let me try it and post results here.

Slightly related question: **Can I use `isset` with `where`?**

---

<div class="post-metadata">

**Author:** ![tatsushid](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/tatsushid/32/7219_2.png) [@tatsushid](https://discourse.gohugo.io/u/tatsushid)\
**Post date:** [June 29, 2015, 11:52am UTC](https://discourse.gohugo.io/t/how-to-filter-pages-on-homepage-based-on-page-params/1369/17 "2015-06-29T11:52:50Z")

</div>

I sent [PR](https://github.com/spf13/hugo/pull/1238) and the my original branch is available at [https://github.com/tatsushid/hugo/tree/feature/nil-comparison-in-where](https://github.com/tatsushid/hugo/tree/feature/nil-comparison-in-where) so now you can try it

---

<div class="post-metadata">

**Author:** ![tatsushid](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/tatsushid/32/7219_2.png) [@tatsushid](https://discourse.gohugo.io/u/tatsushid)\
**Post date:** [June 29, 2015, 11:54am UTC](https://discourse.gohugo.io/t/how-to-filter-pages-on-homepage-based-on-page-params/1369/18 "2015-06-29T11:54:29Z")

</div>

Now `where` doesn’t understand `isset` but it’s just a syntax sugar for `"!=" "nil"` so it seems to be easily added

---

<div class="post-metadata">

**Author:** ![bep](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.gohugo.io/bep/32/3332_2.png) [@bep](https://discourse.gohugo.io/u/bep)\
**Post date:** [June 29, 2015, 5:21pm UTC](https://discourse.gohugo.io/t/how-to-filter-pages-on-homepage-based-on-page-params/1369/19 "2015-06-29T17:21:57Z")

</div>

No, drop that. Aliases with no real value just adds complexity and documentation.
