My layout file looks like this:
{{ define "main" }}
...
{{ end }}
And my base_of.html looks like:
<!DOCTYPE html>
<html lang="{{ site.LanguageCode | default `en-US` }}">
...
</head>
<body>
...
<!-- cache partial only in production -->
{{ if hugo.IsProduction }}
{{ partialCached "script.html" . }}
{{ partialCached "footer.html" . }}
{{ else }}
{{ partial "script.html" . }}
{{ partial "footer.html" . }}
{{ end }}
</body>
</html>
In the scripts.html file, I load the JS files that all pages will use. However, on a specific layout page, I want to load an additional JS file, but it must be loaded after all of my other site-wide JS files have been loaded.
From within the scope of the layout page, I do not seem to be able to set a boolean variable that the scripts.html partial can reference, so that it knows to load that additional script.
Is there a way to do this with Hugo at all?
One of the possibilities how to achieve this is by specifying another block next to the main one in your layout file. You can have as many defined blocks as you want and then you will just render them in other files by the block statement.
{{ define "main" }}
...
{{ end }}
{{ define "scripts" }}
<script src="/js/layout.special.js"></script>
{{ end }}
Then, in your baseof.html, just add this code after your main scripts to render the block:
{{ block "scripts" . }}{{ end }}
Another way how to solve this problem is to test the page type using a simple if statement like shown in the code below. This can be done as a sub condition in those conditions you already have in the file, or as a new separate condition after. It depends on your case and goal.
<!-- cache partial only in production -->
{{ if hugo.IsProduction }}
{{ partialCached "script.html" . }}
{{ partialCached "footer.html" . }}
{{ if eq .Type "layout-name" }}
{{ partialCached "script.layout-name.html" . }}
{{ end }}
{{ else }}
{{ partial "script.html" . }}
{{ partial "footer.html" . }}
{{ if eq .Type "layout-name" }}
{{ partial "script.layout-name.html" . }}
{{ end }}
{{ end }}
Note that in this case, you must ensure that the page has the type specified. There are two possibilities how to do this:
type in the front matter in your content files, orThe default value of the .Type variable is page.
Many ways actually.
You could have a front matter "toggle"
i.e. let's say you have a parallax.js you only want to load on certain pages.
In front matter: "parallax: true"
In your baseof you can do:
{{ if .Params.parallax }}
<script html here>
Or via partial (why did you load your scripts via a partial?).
{{ end }}
I don't have access to your repo, so I'm going blind here so: You could also have that silos layout (i.e. let's say you have /content/about-us/)
And in layouts you put /layout/about-us/
In their have your single and your list files and define your blocks.
See here for examples:
templates how to use
single page template
list page template
And simply load the scripts you want for that silo.
You could also in your JS simply put an "if" statement to see if a specific class is in that file ( I wouldn't suggest it, but you could ).
So let's say you had a carousel on specific pages and it had a class of "my-excellent-carousel" you then do the if statement in the JS.
That's a few ways.
Let me know if you have any questions.
Also, do look at the Hugo docs.
Specifically: https://gohugo.io/templates/base/
Blocks are good - you might be using them, but I can't tell.
I also always suggest looking at other themes so you can get the "hang" of ways to do this. There are a ton, but you're safe starting with BEP's (being the main maintainer of Hugo) https://github.com/bep/docuapi