My iframes have broken!

Hello, I have a problem that I am really struggling to understand. I hope someone can give me a steer on it. I have just come back to hugo after about 12 months away from it and discovered a problem with my theme.

What’s the problem?

My iframes have all broken.

It seems to be related to upgrading from Hugo 0.115.1 to Hugo 0.135.0.

Context

I’m a university lecturer and I have a site I developed for my students using my own custom theme.

The site includes example HTML, CSS and JavaScript code example for my students. Along with my code listings, I includes iframes which show the resulting web pages as they would see them. For example, this exercise shows how to build an animated menu with HTML and CSS. The code is introduced step by step and each step includes an iframe which shows the site as the students should see it.

The site was built last year with Hugo 0.115.1 and I recently started creating a new site with the same theme. I upgraded Hugo to 0.135.0 before starting and I was confused to find that the iframes were not working in the same way as the original site.

I tried serving the old site locally with v0.135.0 and all the iframes were broken in that also. From this, I conclude that the cause seems to be the upgrade from Hugo 0.115.1 to Hugo 0.135.0. I’m not sure where the issue was introduced but I’m assuming I was relying on a bug of some kind which may have now been fixed?

How did it work?

I have a fairly standard shortcode in my theme like this:

<iframe loading="lazy" {{- range $k, $v :=.Params -}} {{- (printf " %s=%q" $k $v) | safeHTMLAttr -}} {{- end -}}>
    {{- .Inner | .Page.RenderString -}}
</iframe>

The iframes are included like this.

{{<iframe src="examples/step-01" width="360" height="640">}}{{</iframe>}}

The page bundle includes the code for all the steps in the exercise under a folder (in this case examples).

content/
├── the-section/
│   ├── the-page/
│   │   ├── examples/             <-- This contains example code
│   │   │   ├── step-01/          <-- These folders are to be presented within iframes
│   │   │   │    ├─ style.css
│   │   │   │    └─ index.html
│   │   │   ├── step-02/
│   │   │   │    ├─ style.css
│   │   │   │    └─ index.html
│   │   │   └── step-03/
│   │   │        ├─ style.css
│   │   │        └─ index.html
│   │   └── index.md              <-- This is where I include iframes within the content
│   ├── another-page/
│   │   └── index.md
│   └── _index.md
└── _index.md

I need the iframes to display the HTML with linked CSS and JavaScript.
The code should be stored in my project as resources, not content.

I was very pleased with myself when I came up with this idea and it has demonstrably worked well in older versions of hugo.

What have I tried?

I can see its something to do with whether the example code is treated as content.
When I experiment, there are two things happening.

  1. The current situation is that the content is completely ignored by the compilation process and I get a compiled 404 not found page in the iframes.

  2. If I remove a folder, the examples are being treated as content and are compiled into my template. So the iframes are showing compiled pages

Neither of these is what I want.

I was wondering if there was a way to mark the content as static within my page bundle. Or perhaps I can do something more clever?

Please help!

If you don’t actually want to use the new hugo features, you can just downgrade to the 0.115 release.

(A quick search of the release notes didn’t bring up anything iframe-specific.)

1 Like

Mmh. Maybe something with bundles, params, safaHTML settings, config, links, resources…

If I were you I would extract just one example thats runnable and works with 115. Someona can replay and compare with 135…

Without too much guessing. And I’m pretty sure in general iframes are working.

maybe this one for Hugo 123 is related Companion page-bundle HTML files not being copied to subfolder of output directory anymore

1 Like

Change your shortcode to this:

{{ range .Page.Resources.Match "**.html" }}
  {{ $publishPath := urls.JoinPath $.Page.RelPermalink .Name }}
  {{ (.Content | resources.FromString $publishPath).Publish }}
{{ end }}
<iframe loading="lazy" {{- range $k, $v :=.Params -}} {{- (printf " %s=%q" $k $v) | safeHTMLAttr -}} {{- end -}}>
  {{- .Inner | .Page.RenderString -}}
</iframe>
1 Like

Update

Thanks for your replies.

I tried a few things. This example should demonstrate my confusion.

I don’t think the problem relates to iframes as such, its whether or not content is created in the /public/ folder for a page.

I created the following structure. The intent is that the example folders are not content and should not be compiled. They should be directly copied into the /public folder under the current page so they can be accessed via my iframes with simple relative urls.

content/
│ 
├── page-1/
│   ├── example-1/
│   │   └── nested-folder/
│   │        ├─ test.html
│   │        └─ index.html
│   ├── example-2/
│   │    ├─ test.html
│   │    └─ index.html
│   ├── example-3/
│   │    └─ index.html
│   └─ index.html
│
└─ _index.html

When I delete the public folder entirely and run hugo server, the resultant page-1 folder only has an index.html file and nothing else. None of these folders make it into the newly created public folder. My iframes show a compiled 404 not found page.

However, if I subsequently make a change, e.g. if I add a new file (another.html) into the example-3 folder, then an example-3 folder is created on the fly with an another folder inside it, with an index.html file inside that which is a compiled template! The result has meta tags and a title tag inside the body!

This is really confusing me.

For my solution, I just need a way to get my example files copied over automatically as is without being compiled.

As it stands, there seems to be two problems:

  1. My files are only being created if I make a change whilst serving.
  2. They are being wrapped in a template, even though they have no front-matter and are fully valid HTML files.

I could go back to an older version. This might be my best option. But I’d like to understand whether I have uncovered a bug or whether I just don’t understand what the expectation is for this situation.

Changing the shortcode as I described above works great.

Try it:

git clone --single-branch -b hugo-forum-topic-51799 https://github.com/jmooring/hugo-testing hugo-forum-topic-51799
cd hugo-forum-topic-51799
hugo server

Thanks @jmooring, your example works perfectly on its own.

Unfortunately, I tried this in my code and nothing changes. The iframes are still broken, the files are still not moved to the public folder.

When I create a new section/page in my project with the same code, iframes show that the html files are being compiled!

I then introduced my theme to your example and after some messing about, it works.

I’m seeing some kind of inconsistent behaviour that I can’t quite get my head around. Perhaps cacheing?

I think I have a way forwards, but I remain confused. I don’t really understand how the change works and I don’t understand why I’m seeing different results in different pages.

You are more likely to receive a prompt and accurate response if you post a link to your project’s Git repository.

See Requesting Help.

Let us see your code

Include a link to the source code repository of your project, because we really need the context of seeing your templates and partials to be able to help you. It is trivial to do a quick git clone on your repo, then run hugo server in your project, to help you out. On the other hand, recreating your code from screenshots, or sort of guessing at it, is not.

If you can’t share your repository for whatever reason, consider creating a dummy repo that you can share, which reproduces the problem you’re experiencing.

Thanks @jmooring, after lot’s of experimenting, I think I have found the problem.

Steps to recreate:

git clone --single-branch -b hugo-forum-topic-51799 https://github.com/jmooring/hugo-testing hugo-forum-topic-51799
cd hugo-forum-topic-51799
hugo server

Now simply change the value of baseURL in hugo.toml from:

baseURL = 'https://example.org'

to

baseURL = 'https://example.org/test'

You may also need to delete the previously created public folder and restart the server.
Notice that there are now two copies of the the-section. One inside public/test and one in the root of the public folder.

That doesn’t make sense to me, but I won’t be able to look at this again until Wednesday. Perhaps someone else can help in the interim.

1 Like

These are not TWO copies, but the processed html files are published to a test subfolder, whereas the rest still is published to the normal the-section folder.

using the original baseURL we get:

C:\_REPOS\GITHUB\CLONE\HUGO-FORUM-TOPIC-51799\PUBLIC
│   favicon.ico
│   index.html
│
└───the-section
    │   index.html
    │
    └───the-page
        │   index.html
        │
        └───examples
            ├───step-01
            │       index.html
            │       styles.css
            │
            └───step-02
                    index.html
                    styles.css

using baseURL = 'https://example.org/test/' results in:

C:\_REPOS\GITHUB\CLONE\HUGO-FORUM-TOPIC-51799\PUBLIC
│   favicon.ico
│   index.html
│
├───test
│   └───the-section
│       └───the-page
│           └───examples
│               ├───step-01
│               │       index.html
│               │
│               └───step-02
│                       index.html
│
└───the-section
    │   index.html
    │
    └───the-page
        │   index.html
        │
        └───examples
            ├───step-01
            │       styles.css
            │
            └───step-02
                    styles.css

So here we are - but don’t ask me why :blush:

If I change the shortcode to use .Path instead of the calculated $publishPath both variants of the baseURL work.

{{ range .Page.Resources.Match “**.html” }}
  {{ (.Content | resources.FromString .Path).Publish }}
{{ end }}

the original shortcode used was:
{{ range .Page.Resources.Match "**.html" }}
  {{ $publishPath := urls.JoinPath $.Page.RelPermalink .Name }}
  {{ (.Content | resources.FromString $publishPath).Publish }}
{{ end }}
<iframe loading="lazy" {{- range $k, $v :=.Params -}} {{- (printf " %s=%q" $k $v) | safeHTMLAttr -}} {{- end -}}>
  {{- .Inner | .Page.RenderString -}}
</iframe>
1 Like

Thanks so much, I have updated my theme and everything seems to work perfectly now. :sunny:

This solution breaks the principle of least astonishment for me. I would expect that the lack of front matter would be enough indication that an HTML file is a resource rather than content. Is there any documentation of this distinction between HTML files and e.g. CSS files which did not need to be handled separately? I’d like to understand what happened more deeply so I can become a better hugoer.

There’s an open issue for this:
https://github.com/gohugoio/hugoDocs/issues/2428

1 Like

What about the implementation. Is this the correct way to handle that?

1 Like

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.