Hacker News new | comments | show | ask | jobs | submit login
Build a JSON API with Hugo's Custom Output Formats (forestry.io)
92 points by regisphilibert 8 months ago | hide | past | web | favorite | 17 comments

This is a really great example of how powerful, and useful, static site technology is for the web.

Open-data is a huge talking point right now, especially with the [GDPR](https://en.wikipedia.org/wiki/General_Data_Protection_Regula...) regulations coming out this year, the discussion around social media and other factors effecting our electoral process, and much more.

Static site generators like Hugo make it trivial for almost anyone to author and share data in open-formats, applying powerful filtering and control over what pieces of your datasets are made available.

Hugo's custom output formats are powerful. It ships with just inbuild RSS xml generation (in addition to HTML of course). But it is very easy to add ATOM xml too.

And another custom output format to dump search index in JSON for the whole site (to be used by sorts of fuse.js, lunr.js, etc.)

True. We use it for our Algolia search index too (documented here: https://forestry.io/blog/search-with-algolia-in-hugo/)

If you're new to Hugo's custom output formats, this is a great example of what you can do with it. https://gohugo.io/templates/output-formats#output-formats

This is a creative and approachable solution for developers who don't want to fall down a back-end rabbit hole. No pun intended.

A cool way to do something 'dynamic'-esque w/ a static site. I wonder if it might make sense for some applications to use json-ld in the static html (and have half the number of static files - which could get big...)

There is no scrollbar, it's not possible to view the article on my machine with the latest Chrome.

Don't know why you were downvoted, the problem is present for me as well (latest Chrome/Linux).

Disabling JavaScript fixes the problem — I can't be bothered to debug the problem specifically right now.

If you're not in the habit of browsing with JavaScript disabled, and you want to disable JavaScript quickly, open the Chrome dev tools, open the dev tools settings, scroll to the bottom of the options, check "Disable JavaScript" and reload the web page.

You can leave the dev tools panel open and re-enable JavaScript when you've finished reading the article.

(If you already know this, forgive me — I meant no offence, just being helpful).

EDIT: okay, so being the curious person I am, I did a little digging and uncovered the problem.

Basically, there is an aside element which, from its class name 'search-results' and id 'search', is most probably used to display search results (using ajax to load results into a panel which is supposed to appear above content like a modal window, saving the user a page load, bla bla bla).

Anyway, the interesting part is how this modal panel is made. Here is the CSS for said element (comments are added by me):

    .search-results {
      background: #fff;
      bottom: 0;
      left: 0;
      overflow: scroll;
      position: fixed;    /* Possibly problematic */
      right: 0;
      top: 0;
      visibility: hidden; /* Possibly problematic */
      z-index: -99;       /* Possibly problematic */
This element is being treated as being on top of the main body of the web page, and since it is sized to fit the full window (absolutely-positioned and fixed-positioned elements are treated as filling the viewport if the containing element is statically-positioned, and if their top/left/right/bottom properties are set to 0), the browser does not pick up any scrolling of the actual article.

Now, I'm guessing that one of two things is going on. Either:

• latest Chrome either has some kind of bug regarding layer compositing (note the z-index: -99 property which should tuck the aside element behind the rest of the content i.e. preventing the aside element from interfering with scrolling of the article); or

visibility: hidden and z-index: -99 aren't enough and either the element needs to be sized when the results are displayed or the element needs to be display: none until the results are displayed.

If it's the former, you and I just need to wait for a version of Chrome that has this bug fixed. Given that others aren't experiencing the problem, it's either Chrome specific or even specific to our build.

It may of course not be a bug — Chrome may be functioning correctly and other browsers may have an oversight regarding layer compositing. I'd need to check the position property of the parent body element.

EDIT AGAIN: okay, so actually I've just picked up on the fact that this troublesome aside element is set to position: fixed by default, which is the real cause of the problem. Whether Chrome specifically treats elements with position: fixed as being always on top, regardless of the presence of an explicit z-index property, is unclear. I think Chrome allows fixed-position elements to be given a layer order if they are within another fixed-position element or an absolutely-positioned element, but not a default i.e. statically-positioned or relatively-positioned element.

Also, to clarify one thing about how visibility: hidden works — it does indeed make an element invisible, but it doesn't prevent interactions with said element. This is the intended behaviour for this CSS property.

Anyway I'm rambling on now. This property probably ought to be set to position: fixed ONLY when the element is actually shown, and should be position: absolute until then for the z-index -99 to actually work. That said, I don't honestly know what the intended behaviour in browsers should be...

* * *

This problem goes away if JavaScript is turned off presumably because this search functionality is intended to use ajax to load results in the aside element results panel, i.e. without a full page load, and thus without JS enabled it just defaults to the old fashioned behaviour of triggering a page load to a results page. I guess.

So, the solution for you and I and anyone else affected is to either browse the page with JS disabled or you can go into the Chrome dev tools, find the aside element (id "search"), right click it and delete it.

This can also be done with a trivial bit of vanilla JavaScript in the browser console:

* * *

To the developers of this website, if you are here: I recommend you apply either:

transform: scale(0); or

position: absolute; or

display: none;

to this aside element until it is meant to be visible, at which point the property can be changed to the value you want, i.e. transform: scale(1), position: fixed, or display: block.

The transform is probably the best way, as messing with positioning and display properties might mess with any animation effects you might have for the search panel.

I mean, that's just so that it wouldn't get in the way for some of your users (though we may be a minority).

I'm interested to know if it's a Chrome bug or if all browsers should treat fixed-position elements like this with no absolutely-positioned or fixed-positioned parent elements.

And yes, sadly position: relative on the html or body elements would be insufficient — at least, I tried it and it didn't work in my Chrome version.

We made the `transform: scale(0)` change to the CSS. I hope this resolved the issue for those affected. Big thank you to Wanda for investigating.

Can confirm that everything works normally on my end now.

Hopefully the user simlevesque will report the same.

Thank you for looking into this Wanda. We'll get someone to fix this issue as soon as possible.

Oh hey! Sorry, I must look like a proper maniac now.

Happy to help.

Lol! Great investigation!

Thank you chief, I appreciate your good humour.

I don't always moonlight as a vigilante CSS debugger, but I am sometimes possessed by curiosity.

You’re an amazing person

You're too kind.

Scrolling works fine for me. Are you on Mac?

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact