I’ve got a contact.md page for my contact form, and I want to add the jQuery library and a custom javascript file to that page only.
My theme has a partial called head-additions.html, which conveniently is an empty file and is loaded in the theme’s baseof.html right before the closing “head” tag with the following:
{{ block "head" . }}{{ partial "head-additions.html" }}{{ end }}
That seemed like the perfect opportunity to add the two script files without overriding a theme file that might get changed with a future update.
I created a /layouts/partials/head-additions.html to override the theme version, and added the following code:
{{ range .Params.js }}
<script src="/static/js/{{ .Params.js }}"></script>
{{ end }}
My intent is that I can add the two javascript files in the frontmatter of the contact.md like this:
js:
jquery-3.5.1.min.js
custom.js
Unfortunately, the function in my head-additions.html isn’t getting passed the .Params. I can output hard-coded text and it shows up on the site, so I know my template override is working.
I looked at some of the other partials included in the theme files, and they mostly have a period after the file name, which I thought was required to pass the page variables, but the head-additions.html does not have it. Although I don’t intend to override the baseof.html, I experimented by adding the period and it gave me an error:
Failed to render pages: render of “page” failed: execute of template failed: template: page/single.html:45:24: executing “head” at <partial “head-additions.html” .>: error calling partial: “/home/username/Hugo/foldername/layouts/partials/head-additions.html:2:23”: execute of template failed: template: partials/head-additions.html:2:23: executing “partials/head-additions.html” at <.Params.js>: can’t evaluate field Params in type string
However, without the period, I don’t get anything.
Since I really don’t want to override baseof.html, I looked around and found another theme partial called “site-scripts.html” which puts scripts in the footer. The .Params are in-scope in that file.
With your code, I can get the scripts to display, so it appeared I had two problems:
.Params wasn’t in-scope in my head-additions.html because the period wasn’t there in baseof.html
Also, since the .Params.js is only available at the contact page, any other page where that code is executed will fail to render since… well, .Params.js is absent on them.
with is one way to verify if the variable is available and the code block can be executed.
I switched to overriding another partial, “site-scripts.html”, which adds its content right before the closing body tag and is short enough that I don’t mind overriding it. That will save me adding the period to the partial declaration in baseof.html.
Unfortunately, I spoke too soon. Even though the only page with the “js” in the frontmatter was the contact page, the javascript was showing up on every page.
To simplify things I switched my frontmatter on the contact page to:
Next, I went with the following in the site-scripts.html file to check for the presence of “addcustomjs”:
{{ with .Params.addcustomjs }}
<script src="/static/js/jquery-3.5.1.min.js"></script>
{{ end }}
Now the jquery file is still loading on every page.
I know I’m missing something obvious here. You’ve helped me solve the scope problem. Should I start another thread for the issue with restricting the output only to the Contact page?
I’m not avoiding the dot, I’m avoiding overriding the baseof.html file of the theme I’m using so that I don’t complicate things down the line if I want to update the theme. It is there that the dot wasn’t used for the /layouts/_default/baseof.html file’s call of the partial /layouts/partials/head-additions.html.
I don’t have a repo I can share as I’ve just been testing Hugo locally, but I’m using the Ananke theme, which you can find on Github.
As noted above, I’m just overriding the /layouts/partials/site-scripts.html file from Ananke.
I can create a dummy repo on Github if it will help, though I probably won’t be able to do that until tomorrow…
The moment you mentioned caching, I knew you were correct, because it fits the apparently inconsistent results I was seeing.
I broke down and overrode the theme’s /layouts/_default/baseof.html with my own, and made two changes. First, I added the period to the head-additions.html so it looks like this: