CSS stylesheet generation

I’m missing a really important part of Hugo generator. The whole day I’m trying to generate CSS style/stylesheet with a code like:

{{- $styles := (slice) -}}
{{- $stylesScratch := .Scratch.Get "Scratch" -}}
{{- with $stylesScratch -}}
    {{- range . -}}
        {{- $styles = $styles | append . -}}
    {{- end -}}
{{- end -}}

{{ $stylesString := delimit $styles " " }}
{{ warnf "Style %q" $stylesString }}
    <style type="text-css" id="img-bg-styles">
        {{ $stylesString | safeCSS }}

The warning in Hugo console outputs twice - empty first and full with correct styles after. But in the final HTML there are only empty style tags.

The smells like a concurrency issue, where sometimes the .Scratch is set, and sometimes not.

Hard to troubleshoot without seeing more/repo.

No repo, cause everything is still local, but in short words different page partials do

{{- page.Scratch.SetInMap "Scratch" $scratch $style -}}

to add styles they need. head partial posted above is unaware of styles values and names, or are they needed at all, just tries to iterate over .Scratch and find there names and values, and then bring them to <style> or <stylesheet>. Despite of the warning on .Scratch docs, i see no other methods to do that kind of things.

Sorry, I don’t have enough information to help.

Well, what happens every time I call page.Scratch.SetInMap from different partials - a totally new .Scratch with [map] is created for current page, purging already existing .Scratch? Or new [map] entries are being created to .Scratch? Do you need the whole code (which contains lots of unrelated code), or just a bit more of context?

Yes. Or a minimal reproducible example.

So here

Scratch is a slice.

But here:

Scratch is a map.

1 Like

If you just want a slice, you don’t need SetInMap, just use .Set and .Add.

Little to no difference with .SetInMap and .Add, .Set is not needed in my case.
But big troubles come from .Scratch usage regarding Hugo render order - I was unable to guarantee that .Scratch is filled by one partial before another partial will try to .Get it. Tried to place .WordCount in all involved shortcodes, all together, or one by one - the first run looks good, but if anything is edited anywhere - I immediately get empty styles.

1 Like

Thank you for trying it. I guess a manageable reproducible test case for bep or jmooring, or others to look at will be needed.

I just thought of a crazy idea for this, which I put in https://github.com/danielfdickinson/image-handling-mod-hugo-dfd/pull/72#issuecomment-1507218459 .

Basically I am assuming Hugo processes the top of baseof first, so move the generation of the CSS (and in our cases images) to the top of baseof, stash them in a page-level .Scratch, and access the .Scratch in head and body partials and shortcodes.

1 Like

A test is required to confirm render order of baseof before putting that much effort into this. In fakt, the test could be runned inside existing code with adding a counter into every partial involved into .Scratch usage and printing that counter together with page and partial name into log. That way rendering order for our particular case will be revealed.

1 Like

Sssooo, I’ve added a code like:

{{- page.Scratch.Add "RenderOrder" "-> Partial name here <-" -}}

to partials involved into styles generation. Then a warning in baseof to display RenderOrder .Scratch :

{{- with .Scratch.Get "RenderOrder" -}}
  {{ warnf "Render order %q for %q" . page.TranslationKey -}}
{{- end -}}

And here is what I’ve got:

  1. For the first run of local Hugo server:
Render order "Add-styles-for-imagesHeadThumbnail-or-full-picture...Thumbnail-or-full-pictureAdd-styles-for-imagesHead" for "home"

Double render of head partial! But at least I get those styles.
2. If I change any partial and save changes:

Render order "Add-styles-for-imagesHead" for "home"

Render order is killing .Scratch usage.

Moved response to