Hugo

Struggling with leaf bundle

Hi, I have started to create my first theme and have been struggling with leaf bundles for a couple of weeks now: time to register and post a question.

What I would like to accomplish is the following:

  • I receive an HTML file which contains a document. Along with it comes a PDF file with the same content.
  • I want to display the HTML file and have a link to download the corresponding PDF file.

What I have done is the following:

  • I have a single.html file that contains {{ .Content }}.

  • My directory structure looks like this:

    • content
      • kb
        • testkb
          • index.md
          • myfiles
            • source.html
            • source.pdf
  • The file index.md contains the resources like so:

    title: ‘Test KB article’
    author: Marc
    date: ‘2019-11-27’
    draft: false
    resources:

    • src: myfiles/source.html
      name: SourceHTML
      title: Source HTML
    • src: myfiles/source.pdf
      name: SourcePDF
      title Source PDF

    {{< showfile >}}

  • The shortcode showfile has contained a number of things in order to try to make this work; not yet touching on providing the link to download the PDF file. For example:
    <embed src="{{ (.Resources.Match “**”).Content }}" width=“100%” height=“100%”>
    or
    <embed src="{{ (.Resources.Match “SourceHTML”).Content }}" width=“100%” height=“100%”>
    or
    <embed src="{{ (.Resources.Match “source.html”).Content }}" width=“100%” height=“100%”>
    or
    <embed src="{{ (.Resources.Match “myfiles/source.html”).Content }}" width=“100%” height=“100%”>
    or
    {{ with .Page.Resources.GetMatch “SourceHTML” }}

    {{ end }}
    or
    {{ range .Page.Resources.Match “*” }}

    {{ end }}

I have read the Hugo Page Bundle documentation numerous times, as well as the Hugo Page Resources documentation.

I must be missing something. Any help to get me on the right track is much appreciated.

Thank you.

Marc.

Can you please add code either with the code button here in the editor or with three backticks `< these things. This way the formatting will be readable.

I am not 100% sure but I believe that html is not a resource type. Maybe try using .txt as ending, but the resources I have experience with are mostly images or PDF.

Question: Where is single.html located? Or did you mean source.html?

1 Like

Apologies for the bad formatting. I have revised it below. To answer your question around single.html, it is indeed single.html and it is located in themes/mytheme/layouts/kb.

Hi, I have started to create my first theme and have been struggling with leaf bundles for a couple of weeks now: time to register and post a question.

What I would like to accomplish is the following:

  • I receive an HTML file which contains a document. Along with it comes a PDF file with the same content.
  • I want to display the HTML file and have a link to download the corresponding PDF file.

What I have done is the following:

  • I have a single.html file that contains {{ .Content }}.
  • My directory structure looks like this:
+ content
  + kb
    + testkb
      - index.md
      + myfiles
        - source.html
        - source.pdf

The file index.md contains the resources like so:

title: ‘Test KB article’
author: Marc
date: ‘2019-11-27’
draft: false

resources:
- src: myfiles/source.html
  name: SourceHTML
  title: Source HTML
- src: myfiles/source.pdf
  name: SourcePDF
  title Source PDF

{{< showfile >}}

The shortcode showfile has contained a number of things in order to try to make this work; not yet touching on providing the link to download the PDF file. For example:

<embed src="{{ (.Resources.Match “**”).Content }}" width=“100%” height=“100%”>

or

<embed src="{{ (.Resources.Match “SourceHTML”).Content }}" width=“100%” height=“100%”>

or

<embed src="{{ (.Resources.Match “source.html”).Content }}" width=“100%” height=“100%”>

or

<embed src="{{ (.Resources.Match “myfiles/source.html”).Content }}" width=“100%” height=“100%”>

or

{{ with .Page.Resources.GetMatch “SourceHTML” }}
  <embed src="{{ .RelPermaLink }}" width="100%" height="100%"></embed>
{{ end }}

or

{{ range .Page.Resources.Match “*” }}
  <embed src="{{ .PermaLink }}" width="100%" height="100%"></embed>
{{ end }}

I have read the Hugo Page Bundle documentation numerous times, as well as the Hugo Page Resources documentation.

I must be missing something. Any help to get me on the right track is much appreciated.

Thank you.

Marc.

Further to this, the files source.html and source.pdf (in the content/kb/testkb/myfiles directory) may as well be called myfile.html and myfile.pdf or anything else.

In light of the possibility that embedding HTML might not be supported, and that I see a lot of examples with images, I tried the following:

  • I added photo.jpg to the directory content/kb/mytest/myfiles.
  • In content/kb/mytest/index.md, I added:
- src: myfiles/photo.jpg
  name: photo
  title: Photo of a mountain
  • I updated the content of the showfile shortcode to the following (example taken from here):
{{ with .Resources.ByType "image" }}
	<div class="Image">
	{{ range . }}
		<img src="{{ .RelPermalink }}">
	{{ end }}
	</div>
{{ end }}

The result when I build the site is:

...failed to process shortcode: ".../showfile.html:1:18": execute of
template failed: template: shortcodes/showfile.html:1:18: executing
"shortcodes/showfile.html" at <.Resource.ByType>: can't evaluate field
Resources in type *hugolib.ShortcodeWithPage

I am getting the same error message, regardless of whether I specify the resource in content/kb/mytest/index.md or not.

Thanks in advance for any suggestions.

Hi,

html files are page-type resources. Therefore, no .Permalink: https://gohugo.io/content-management/page-resources/.

You need to get the .Resources from the .Page variable when inside the shortcode context:

.Page.Resources

Cool, so I changed the shortcode to say .Page.Resources.ByType and now the image is displayed.

Is there a way to display an HTML file?

You could try grab the .Content instead.

If you want the html to have its own .Permalink, and therefore its own navigable page, you have to make it its own Hugo page.

content
* kb
  * testkb
    * _index.md        # change this to a branch bundle
    * myfiles
      * source.html    # this renders to yoursite.com/kb/testkb/myfiles/source.html
      * source.pdf

This has a few side effects though, primarily that source.pdf will no longer belong to the testkb/_index.md page’s .Resources.

The problem I can see with that approach is that my HTML file (source.html in this example) is not a complete stand-alone page. In the shortcode, I have been trying things like:

{{ range .Page.Resources.GetMatch "*.html" }}
  <embed src="{{ .PermaLink }}" width="100%" height="100%"></embed>
{{ end }}

When building the site, this breaks on the very first line with:

execute of template failed: template: shortcodes/showfile.html:1:44:
executing "shortcodes/showfile.html" at <"*.html">: range can't iterate over <nil>

Another thing I just tried was to change the extension from .html to .txt and then try to get a match on the *.txt file. This results in the same error.

.GetMatch returns the first match: https://gohugo.io/content-management/page-resources/#methods

It is not an array; therefore it cannot be range-d over.

and again, page-type resources have no .Permalink.

Ok, so if I change the shortcode to the following:

{{ with .Page.Resources.GetMatch "*.html" }}
  <embed src="{{ .Content }}" width="100%" height="100%"></embed>
{{ end }}

Then nothing is displayed. Equally, if I change the file extension to .txt.

src takes a URL. .Content is not a URL. It is the actual content of the resource: https://gohugo.io/content-management/page-resources/#properties

{{ with ... }}
  {{ .Content }}
{{ end }}

Thank you for your patience with this. I am trying to get my head around this. So, I have updated my shortcode to look like this:

{{ with .Page.Resources.GetMatch "*.html" }}
  {{ .Content }}
{{ end }}

When I now build the site, no content is shown; just empty space. The same if I change the extension to .txt.

If I change the shortcode to:

before loop
{{ with .Page.Resources.GetMatch "*.html" }}
  before content
  {{ .Content }}
  after content
{{ end }}
after loop

Then it prints: before loop after loop. So that indicates that it never ran through the loop, correct?

I think there may be a problem with the way GetMatch is trying to find the html file.

My content/kb/mytest/index.md file contains:

- src: myfiles/source.html
  name: htmlfile
  title: HTML file

The shortcode is saying {{ with .Page.Resources.GetMatch "*.html" }}. When I copy the html file to the content/kb/mytest directory (the same directory as the index.md file, then my html file is displayed, along with the text before loop before content and after content after loop.

I guess I am not properly looking for the html file.

I just changed the shortcode to:

{{ with .Page.Resources.GetMatch "myfiles/*.html" }}

And then it does grab the correct html file!

Thank you so much for your time and patience. This outcome is a really big step forward for me.