
Build a JSON API with Hugo's Custom Output Formats - regisphilibert
https://forestry.io/blog/build-a-json-api-with-hugo/
======
chrisdmacrae
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...](https://en.wikipedia.org/wiki/General_Data_Protection_Regulation))
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.

------
kaushalmodi
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.)

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

------
sgallant
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](https://gohugo.io/templates/output-formats#output-formats)

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

------
blacksmith_tb
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...)

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

~~~
wanda
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:

    
    
        document.getElementById('search').parentNode.removeChild(document.getElementById('search'));
    

* * *

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.

~~~
forestryio
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.

~~~
wanda
Can confirm that everything works normally on my end now.

Hopefully the user simlevesque will report the same.

