Minification behavior for template output

Hi there.

I learnt about resources.ExecuteAsTemplate from Hugo’s docs. The example given there is:

{{ with resources.Get "css/template.css" }}
  {{ with resources.ExecuteAsTemplate "css/main.css" $ . }}
    <link rel="stylesheet" href="{{ .RelPermalink }}">
  {{ end }}
{{ end }}

Now suppose I’d like to minify the output of that template, i.e., main.css, which can be achieved simply by adding a minify step:

{{ with resources.Get "css/template.css" }}
  {{ with resources.ExecuteAsTemplate "css/main.css" $ . | minify }}
    <link rel="stylesheet" href="{{ .RelPermalink }}">
  {{ end }}
{{ end }}

So far, everything works as expected. But then I decide to rename template.css to, say, template.css.tmpl, since the template syntax isn’t valid CSS and triggers editor warnings (in contrast with HTML templates). The code above is changed accordingly:

{{ with resources.Get "css/template.css.tmpl" }}
  {{ with resources.ExecuteAsTemplate "css/main.css" $ . | minify }}
    <link rel="stylesheet" href="{{ .RelPermalink }}">
  {{ end }}
{{ end }}

It turns out, however, that this isn’t a valid solution. hugo server and hugo build throw the following error:

execute of template failed at <.RelPermalink>: error calling RelPermalink: MINIFY: failed to transform “css/main.css” (): minifier does not exist for mimetype

It looks like the mimetype is determined by the template rather than its output. Even thought this doesn’t cause a real problem (sticking to .css extension is fine), I definitely find it confusing and would love to learn why it’s the case.

That’s related to the syntax checker and the HTML format. text between elements is just plain text,. so templates are valid in HTML. In a css file the templates break the syntax.
depending on your Editor and engine you may skip some files from being checked…

The type of a resource is determined when reading the resource all next steps take that value determined from file extension.
I think that cannot be changed.

imho adding a mime type for some red lines of a syntax checker in an editor sounds arguable. But if you want to take that line:

You can change the default CSS mime type. Quick test you cannot use css.tpl but csstpl is fine. (guess it’s the delimiter blocking it.)

add this to your hugo.toml, and resources.Get will treat it as text/css and allow your minification

[mediaTypes]
  [mediaTypes.'text/css']
    delimiter = '.'
    suffixes = ['css', 'csstpl']
{{ with resources.Get "css/main.csstpl" }}
  {{ with resources.ExecuteAsTemplate "css/main.css" $ . | minify}}
    <link rel="stylesheet" href="{{ .RelPermalink }}">
  {{ end }}
{{ end }}

You can keep the “template.css.tmpl” file name with…

{{ with resources.Get "template.css.tmpl" }}
	{{ with .Content | resources.FromString "css/main.css" }}
		{{ with . | resources.ExecuteAsTemplate "css/main.css" $ }}
			{{ with . | resources.Minify }}
				<link rel="stylesheet" href="{{ .RelPermalink }}">
			{{ end }}
		{{ end }}
	{{ end }}
{{ end }}

Though if it were my project I’d keep the “template.css” file name and be done with it.

You might also consider using a vars map with the css.Build function to inject values into your CSS.