Is this the proper way to read/reference a file located in the current content directory from a Partial?

I’m trying to inline critical (above the fold) CSS in the head of each webpage. Since each page has slightly different CSS, I want a way to customize per page. Currently what’s below is working, but I’m not sure it’s the most efficient way in Hugo. Any feedback or cautions would be greatly appreciated!

If a page has a custom CSS file, I add the following page param:

title: MY PAGE
custom_css: true

and put a file named “index.css” in the current directory. In my partial head.html template I have the following:

{{- if .Params.custom_css }}
    <style>{{ (.Resources.GetMatch "index.css").Content | safeCSS }}</style>
{{- end }}

which seems to work just fine. Pages without the custom_css param don’t throw an error. The biggest issue I can see currently is, if the file is misnamed/doesn’t exist, Hugo throws an error. This is probably the desired result, though it might be better to check if the file exists before trying to render it.

Is my approach correct?

Yes, it’s fine.

Even better use with instead of if in your condition.

If the condition is not met with escapes the code block completely.

Just tried substituting “if” with “with” and it’s throwing the error:

<.Resources.GetMatch>: can't evaluate field Resources in type bool

Interesting. How about using, $.Resources.GetMatch "index.css"?

Hmmm, let me be sure I’m placing the “with” where you are suggesting. Here’s the code:

    {{- if .Params.custom_css }}

    <style>{{ (.Resources.GetMatch "index.css").Content | safeCSS }}</style>

    {{- end }}

I was replacing the “if” with “with” and getting that error I quoted, but then I tried adding “with” both inside the parenthesis and outside. All are throwing errors. Can you give me the code you think should work? I’ll plug it in.

Try:

    {{- with .Params.custom_css }}

    <style>{{ ($.Resources.GetMatch "index.css").Content | safeCSS }}</style>

    {{- end }}

OR

    {{- $style := .Resources.GetMatch "index.css" -}}
    {{- with .Params.custom_css }}

    <style>{{ ($style.Content | safeCSS }}</style>

    {{- end }}

The error you encountered means that the context of the Page has been lost and the CSS resource is cannot be fetched.

It seems that with comes with its own special context hence the error.

To overcome such context issues in Go templates one needs to go higher up in the outer Page context with the $ dollar sign to access the global context. Read more about it here

OR

As I wrote in my second example, store the stylesheet in a variable and then call that variable from inside the with context.

I haven’t quite encountered the error you described myself and that is why I suggested using with in the first place.

Typically with is safer than if because as I said above if a condition is not met then a code block inside a with is completely escaped, apparently that is not always the case within the context of an if condition.

One more:

    {{- if eq .Params.custom_css true }}

    <style>{{ (.Resources.GetMatch "index.css").Content | safeCSS }}</style>

    {{- end }}

The above will execute only if the boolean truth of the custom_css parameter is true.

Thanks for continuing to play along Alexandros. The above and your first code snippet both work, but the second one errored out complaining about an unclosed left parenthesis. Neither of the working snippets could deal with the file not being present in the directory, so if index.css was missing or misnamed in the folder, it errored out just like it does in my original code.

Yes because I forgot to delete it.

Should be:

    {{- $style := .Resources.GetMatch "index.css" -}}
    {{- with .Params.custom_css }}

    <style>{{ $style.Content | safeCSS }}</style>

    {{- end }}

There is no way around that I am afraid.

If a content file has the custom_css parameter then Hugo will fetch that CSS file. If the file is not present there will be a build breaking error.

Yep, that’s what I figured. It’s more of a feature than a bug, in any case. The file is meant to be there if that param is set.

Thanks, enjoy your weekend!

Eliminate the frontmatter parameter and check, and do this instead:

{{ with .Resources.GetMatch "index.css" }}
  <style>{{ .Content | safeCSS }}</style>
{{ end }}
1 Like

This topic was automatically closed after 13 hours. New replies are no longer allowed.