Why is this template incomplete?


#1

Hi, everyone. I’ve got a partial template, about.html, which hugo calls incomplete with the following error: ERROR: 2017/01/05 14:22:43 general.go:236: theme/partials/about.html is an incomplete or empty template

However, the template is entirely identical to another partial template with the exception of the data it calls. So where this one says .Site.Params.about.title, the working one says .Site.Params.beers.title, etc.

For the life of me, I cannot figure out why. Logs generated by verbose log do not give me any more than the error above.

Thanks for your help!

> {{ "<!-- Portfolio Grid Section -->" | safeHTML }}
> <section id="about" class="bg-light-gray">
>   <div class="container">
>     <div class="row">
>       <div class="col-lg-12 text-center">
>         <h2 class="section-heading">{{ with .Site.Params.about.title }}{{ . | markdownify }}{{ end }}</h2>
>         <h3 class="section-subheading text-muted">{{ with .Site.Params.about.subtitle }}{{ . | markdownify }}{{ end }}</h3>
>       </div>
>     </div>
>     <div class="row">

>       {{ range .Site.Data.about }}
>         <div class="col-md-4 col-sm-6 portfolio-item">
>           <a href="#aboutModal{{ .modalID }}" class="portfolio-link" data-toggle="modal">
>             <div class="portfolio-hover">
>               <div class="portfolio-hover-content">
>                 <i class="fa fa-plus fa-3x"></i>
>               </div>
>             </div>
>             {{ $url := printf "img/about/%s" .preview }}
>             <img src="{{ $url | absURL }}" class="img-responsive" alt="">
>           </a>
>           <div class="portfolio-caption">
>             <h4>{{ .title | markdownify }}</h4>
>             <p class="text-muted">{{ .category | markdownify }}</p>
>           </div>
>         </div>
>       {{ end }}

>     </div>
>   </div>
> </section>

#2

Well I made it stop happening by deleting sections methodically.

This line is the culprit:

        <p class="text-muted">{{ .category | markdownify }}</p>

It’s still not clear to me why it was happening, though.


#3

If you’re trying to get the category that a post is in, you should use .Params.categories
There’s nothing stopping a post having multiple categories, so something like this might be better:

<p class="text-muted">{{ range .Params.categories }} {{ . | markdownify }} {{ end }} </p>

#4

Is somebody already working on or an issue created or something related to the fact that it is not printing the actual underlying error? This problem would be mitigated greatly by just having some more output. I get the same line number on my output (general.go:236, for version 0.18.1) but it looks like that’s just where the logger output code is, so that’s useless. I can potentially help dig in a bit here but I wanted to see if anyone had any further comment on that. I have a hunch a parser is erroring somewhere internally and that message is being thrown away.


#5

We are throwing the error away because it is extreeemely verbose, and not very informative, see https://github.com/golang/go/issues/17414

If you want a better error in this situation, you will have to bring it up with the Go team.


#6

Thanks, bep.

Please have a look at my pull request: https://github.com/spf13/hugo/pull/2926

I see the issue but I think it will greatly improve the user experience for people doing template work to get a truncated version of that message rather than discarding it. More explanation and example in the PR.


#7

Hi @bep ,
I seem to have an error very similar, if not identical, to this one, with Hugo 0.18.1.

I have a data file like this, in “data/enmain.toml”, generated by a script:

list = [
"""
a (multiline) chunk of HTML code with <strong>markup</strong> of all sorts, links double quotes etc...
"""
]

I have then written a partial like this in layout/partials/sidebar.html, because I need the HTML above to go in the sidebar of each page:

<aside class="l-sidebar">
<section class="panel panel-default">
{{ range .Site.Data.enmain }} {{ . | safeHTML }} {{ end }}
</aside>

If I remove the “| safeHTML” part, hugo gives no errors, but renders escaped HTML code, eg all the < characters are replaced by &lt; and so on. Besides the whole HTML escaped string is enclosed in square brackets.

If I add safeHTML, hugo aborts saying:

ERROR: 2017/01/21 20:22:04 general.go:236: theme/partials/sidebar.html is an incomplete or empty template

what is happening, and what should I change either in the data file format, or in the partial, to make hugo place the HTML as is in the right place?

Please note that I cannot change or reformat the HTML blob itself. If it were a list, for example, I’d follow the example and instructions in the datafile documentation page, but
Thanks!


#8

SOLVED. (for me at least). Sorry…

Of course, the best solution to my specific situation, that is include into a template a whole blob of HTML code saved into a file, is not to use data files, but do this (assuming the HTML is in blocks/enmain.html):

 {{ readFile "blocks/enmain.html" | safeHTML }}

Now the only thing I still need is how to make this language-sensitive on a multilingual website, i.e. how to tell Hugo the equivalent of this:

if (language of current page == 'en' )
then
      {{ readFile "blocks/enmain.html" | safeHTML }}
else  if (language of current page == 'it' )
then # load the equivalent block, in Italian
      {{ readFile "blocks/itmain.html" | safeHTML }}

I’ll go check the docs again, but of course any pointer is welcome…


#9

for now, I have solved this with this ugly hack:

{{ if eq .LanguagePrefix "" }} {{ readFile "blocks/en/main.html" | safeHTML }} {{ end }}
{{ if eq .LanguagePrefix "/it" }} {{ readFile "blocks/it/main.html" | safeHTML }} {{ end }}

I’m sure there must be better / more elegant solutions, thanks in advance for pointing me to them


#10

Have you checked out Hugo’s multilingual support? That seems to cover your use case – your blocks/[en,it] will just be taken care of for you.


#11

@jxf I already know about Hugo Multilingual support, as you can see in this other thread that I myself started last month:

The rest of that website, as far as multilingual goes, is OK now. Only this different (sub)issue was still open for me. I have already got what I wanted with the hack in my previous comment. But I would still like to know if there is a better way to do this, i.e to pass to readFile a file name that is NOT a constant string, but contains a Hugo variable. In bash, I know I could say

readFile "blocks/$LanguagePrefix/main.html"

what is the equivalent go/Hugo syntax to do the same thing? This is what I still don’t know.


#12

Gotcha, thanks for clarifying @mfima. I have found that the templates are extremely strict with their typecasting, and that when I want to get fancy with variables, I have to downcast to strings first. Try doing something like:

{{ $prefix := printf "%s" .LanguagePrefix
{{ readFile (delimit (slice "blocks/" $prefix "/main.html") "") }}

#13

Thanks @jxf. That was it! I only had to add two parentheses, this is the form that works as I need it:

{{ $prefix := printf "%s" .LanguagePrefix }}
{{ readFile (delimit (slice "blocks" $prefix "/main.html") "") | safeHTML }}

because it inserts “blocks/main.html” in the English pages, which have an empty language prefix, and inserts “blocks/it/main.html” in the italian pages, where the same variable is equal to “/it”. So it does the same thing as my initial hack, but much better: less code, and more flexible. As is, it would work even on a site with many different languages.

Thanks again! (gee, this whole go/Hugo thing doesn’t have an easy attitude at all, but it’s really starting to grow on me :slight_smile: )