layouts/partials/header.html – the part provided by the theme
layouts/partials/head_custom.html – for adding own scripts etc., header.html loads this
Also, I have created some shortcodes which need specific JS libraries. So far, they are all included in head_custom.html for every page. But the shortcodes are not used on every page!
So, my idea is the following:
Set a variable in the shortcodes ($i_need_library)
Check in head_custom.html for the presence of this variable
Only if variable is present, include library.
Is this possible somehow? I could not achieve it so far.
If there is a forum question for this already, I’m sorry that I haven’t found it yet; however, most similar entries seem to suggest a solution by manually setting front matter information, which I do not want.
Thank you! This works nicely now in my “posts” pages, however it does not work on the list pages. In both templates (single.html and list.html) the header partial is included in exactly the same way.
Could this be related to the .Summary behaviour? I use this command in list.html, manually setting <!--more--> in my posts for the summary to be rendered correctly.
Do all pages in the rendered Group contain this shortcode or not?
If the latter then of course the scripts will be included, since not all pages contain that shortcode.
If the former please provide a repo that reproduces the issue for us to have a better look.
Not all pages contain the shortcode. I didn’t think about this. So just to clarify, .HasShortcode only evaluates to true if all pages in a list page have the shortcode? From my userspace kind of view I would have expected Hugo to look at the (list) page, see that the shortcode is included (because of the appearance in at least one summarised page) and behave like is it there then…
Maybe I should just generally include the scripts without condition in list.html, which of course would be less nice if I want to change anything later.
.HasShortcode returns true for the specific page context. So, if you have a posts/_index.md that uses that shortcode, it will evaluate to true on your list.html layout.
You will need to include some logic to do this. Something like (untested)
{{ $include := false }}
{{ if .IsNode }} <!-- list page -->
{{ if .HasShortcode }} <!-- list page _index.md uses shortcode -->
{{ $include = true }}
{{ end }}
{{ range .Pages }} <!-- check child pages -->
{{ if .HasShortcode }}
{{ $include = true }}
{{ end }}
{{ end }}
{{ else }} <!-- single page -->
{{ if .HasShortcode }}
{{ $include = true }}
{{ end }}
{{ end }}
Technically, this works (with, in my case, another recursion because .Pages is only “Posts” and the articles are below that).
However it is just as good as when I did not have any check at all (for list pages; for single pages it definitely is an improvement), because this checks every whole article, resulting in “of course we need all those scripts” even if the shortcodes are only used after the summary.
Is there any possibility to filter out the “raw” contents in the summary? .Summary.HasShortcode does not work, probably because it’s already the rendered HTML.
Thank you for the explanation and the links! From there on, I could make it work. In case anyone ever has a similar objective, this is a possible solution:
{{ $includeScript := false }}
{{ if .IsNode }} <!-- list page -->
{{ range .Pages }} <!-- check child pages -->
{{ range .Pages }} <!-- another recursion because of the "/posts/xyz" structure; does work with category lists -->
{{ $rawsummary := split .RawContent "<!--more-->" }} <!-- prepare for checking only the part of the article that will show up on the list page -->
{{ if (findRE "{{< first-shortcode|{{< second-shortcode" (index $rawsummary 0)) }} <!-- check if this part uses the shortcode -->
{{ $includeScript = true }}
{{ end }}
{{ end }}
{{ end }}
{{ end }}
{{ if or (.HasShortcode "first-shortcode") (.HasShortcode "second-shortcode") }} <!-- check if single page or list page itself use the shortcode -->
{{ $includeScript = true }}
{{ end }}
Later on, include the script with
{{ if $includeScript }}
<script type="text/javascript" src="{{ "js/my-fancy-script.js" | relURL }}"></script>
{{ end }}
This is suitable for the shortcodes first-shortcode and second-shortcode both needing the same script my-fancy-script.js. Adapt to your needs!