hugo
hugo copied to clipboard
Add .HasCodeBlock
Hugo already has a .HasShortCode
that returns true if a given shortcode was used in the page. I't useful when, for example, we want to include some CSS or JS in the head to handle the content of the shortcode. It would be nice to have a .HasCodeBlock
as well, for when we need to include some CSS or JS in the head to handle the content of particular code-blocks.
For example, mermaid diagrams are typically implemented with code blocks like this:
```mermaid
graph TD;
A-->B;
A-->C;
B-->D;
C-->D;
\```
It would be nice to be able to add something like this in the head:
{{ if .HasCodeBlock "mermaid" }}
...
{{ end }}
It's already possible to do something similar by setting a variable in the codeblock hook, and then adding the JS in the footer or something. But there is currently no way to add it in the head, before the {{ .Content }}
is called. I think it would be nice to have this option, as it's typically recommended by the packages to add things in the head of the page. And it's nice to keep all the resources in the same place in the head of the page. (Without using some variable in the front matter like hasMermaid = true
...)
I agree, but it needs to wait a little, and I'll spend a few lines to explain why:
- We do lazy rendering of
.Content
, mostly to avoid doing the work if it's never used. - We have some methods that depends on
.Content
(e.g..WordCount
) which leads to a rather clumsy init setup. Also, the root Page API has become rather big and is difficult to document (we're working on a auto generated reference). - This situation became even more visible in the recent Hugo edition where we added
.Fragments
(where you now can do.Fragments.Identifiers.Contains "my-page-heading"
) and split the parsing and rendering of the content (calling just.Fragments
is very effective). - I have propsed that we add an
RenderContent
that returns a struct. With.Fragments
in mind, we should probably also have aParseContent
method. When I'm getting around to wrapping up mymillion pages branch
that should also allow us to pass a context (cache) identifiers to these, e.g.RenderContent "home"
. - With that done, it should be much easier to do
.ParseContent.CodeBlocks.Identifiers.Contains
,.ParseContent.ShortCodes.Identifiers.Contains
,.ParseContent.Fragments.Identifiers.Contains
etc. and get a much simpler and easier to understand API.
But there is currently no way to add it in the head, before the {{ .Content }} is called.
You can force content to be rendered anywhere with something like:
<head>
...
{{ $noop := .WordCount }}
{{ if .Store.Get "hasMermaid" }}
...
{{ end }}
...
</head>
Any of these will force content rendering:
Content
FuzzyWordCount
Len
Plain
PlainWords
ReadingTime
Summary (regardless of how you define it)
Truncated
WordCount
Oh, that's a nice workaround. Thanks!