Keep images & content together

my file structure is

…/content/post/test1.md
…/content/post/test1.jpg

after lunch HUGO. the destination become

…/Destination/post/test1/index.html
…/Destination/post/test1.jpg <== not in the same folder.

the image and html does not include in same folder. ???
In the test1.md
Include image by below code.
![imagee here ](test1.jpg)

is there any way to refine or setting this?
it is help to use Markdown editor Typora for preview and edit.
thanks your time.

1 Like

I don’t quite understand the situation here. The topic has been raised in 2015, it was said it’s not super hard to code and it would be coming soon, but 2 years later in version 20.7 I don’t find it resolved. Is this pending development or is considered solved?

I can’t see any other way than to use absolute path to reference the content that lies just next to my .md file. Is there at least any way to make it nicer by using some kind of variable to capture the url that points to the directory of the .md file? I’ve read the docs and tried to use variable in my .md but it doesn’t seem to work. Any hints how make this work natively?

1 Like

This is a must if you are doing lot of blog posts or documentation. Also for non technical users, they can’t be expected to find what folder the image goes and add appropriate link. Also this will work with github and show you the image. Currently, github does not show you the image in your repo.

1 Like

No, this has not been implemented.

Hugo is open source. Contributors like myself develop what they need or what they think is interesting, or whatever. The fastest way to get it done is always to do it yourself. Of course, if that is not an option – then wait.

2 Likes

I am aware of the software’s nature. Any ideas where to start looking in the latest source code to do it?

You would kind of have to look at most of the core Hugo code to be able to pull this off, start at the hugolob/page.go and see how that is used. I would also suggest you create some kind of proposal/design before spending too much time coding.

Don’t know what exactly you’re looking for, but this works for me:

$ tree content/ content/ └── post ├── 14th-anniversary │ ├── gaura-nitai_2011_installation.jpg │ └── offering_2011_installation_lunch.jpg ├── 14th-anniversary.adoc ├── happy-birthday │ └── gaura-nitai_97.jpg ├── happy-birthday.adoc ├── how-what-to-preach.adoc

and I reference the image in my post as:

{{< figure src=“gaura-nitai_97.jpg” title="Sri Sri Gaura-Nitai ’97" class="center">}}

I’m aware there is probably more one could like to see, but the present feature fulfills most of my use cases in a sense that I can simply put the images used in a blog post in a folder which is named the same as the post itself. :sweat_smile:

1 Like

I tested the figure shortcode, but it works only on the top level and only if you put images into a subfolder, which is not optimal. I summarized my ideas as a Proposal: allow for keeping text and post-related resources in the same folder. So please feel free to have a look and comment.

@zjedi I think most of what you are looking for is already possible since Hugo v0.14 (see Issue 147). Any files in the content folder that are not picked up by Hugo for processing are just copied over in the same file structure.

I have been using this a lot with images inside the same folder as the markdown file. If you don’t want to put the assets in a subfolder you will need to name your content index.md or use slug = "/" in your front matter.

You can see how I’m using it in the discussion about Content Organization Best Practice (See Structure B).

The way I reference a file in my markdown files is just with [My Image](my-image.png). Of course, if you let Hugo rewrite the url of your markdown file (for example based on the date 2017/05/20), then that will not work (maybe this issue about asset bundling might fix this - if it is actually something we want…).

What is not easily possible yet is nested sections if this is what you would like to do. There is an issue for nested sections.

Does this answer your question or am I missing something?

1 Like

I didn’t manage to get it working like you mention with your “Structure B” example, not sure why. Do you have a public repo anywhere I could see that working and clone the pattern?

It seems that whatever solution HUGO has is going against my freedom to organise content in a way that would also preserve natural markdown path validity. That must be because it magically interprets folders as categories or asset directories. Can I turn the logic off somehow and define it manually?

I found one more problem: whatever works for linking the content from the post itself becomes broken from the perspective on the post preview (the main page).

Actually, the only solution that worked 100% (except keeping markdown locally valid) is to use absolute URL.

You can have a look at this repo (it’s German but you’ll get the picture): https://github.com/makery/www.landmais.ch

In the maissorten subfolder you will see content with subfolders (like a blog with blog posts).

1 Like

Resurrecting this thread because… relevant.

After some experimentation and based on what others have shown, you can put assets along with content files but they have to follow a certain structure format.

Content and Asset on same level

content
    - blog
        - post.md
        - post.png

This also works if the content and asset are on the same level but in their own sub-directory:

content
    - blog
        - post        
            - index.md
            - post.png

But! The content file has to have the name of index.md or else you’ll double stack on the directories in the built page (/blog/post/post/).

Both of these have the added benefit of allowing functioning markdown previews with graphics (assuming they are not done with shortcode) in editors that feature that, and also in GitHub previews.

However

If you use permalinks on your page, this will make it all come crashing down. The content will render but none of the assets referenced in the content will. The content gets the new permalink name but the assent is copied directly over in the directory structure name. There are really bad workarounds but it’s a problem. Maybe there is a function or something I’m missing that would make this work out… but I’m not aware of it. There is quite a contentious issue here https://github.com/gohugoio/hugo/issues/1199 but it points out the problem. It was continued less contentiously here https://github.com/gohugoio/hugo/issues/1768 .

What might be the way forward on this?

1 Like

Wait for Hugo 0.26

See: Add Content Bags · Issue #3651 · gohugoio/hugo · GitHub

On the ball! Thanks!

So, I imagine this question is entirely personal, but is there a “right” or “better” way to go about this, if one has all the options available to them (split between static/content or bundled all in content via subfolders)? Is there a more preferred or efficient structure?

Well I guess it’s a personal choice. There have been many requests about this feature so I guess it’s needed.

Even though I prefer to keep everything organized under /static/ I might use the new bags/bundles (whatever it’s called) feature for a product catalogue, as in this case it makes sense (at least to me), since this type of site changes its content completely every 6 months and there is no need for an archive.

I will try to get “bundles with image scaling etc.” done for Christmas. That should make a nice Christmas present/bundle …

See https://github.com/gohugoio/hugo/issues/3651#issuecomment-346950344

7 Likes

Just saw the demo you made with bundles.

{{ with .Resources.ByType "image" }}

The above is great for all its simplicity. And exactly how I thought that a bundle would work.

But this: {{ with .Resources.ByType "page" }} is amazing!

Sub-pages or even sub-links or whatever for a content file. now. I’m impressed!

Thank you so much!

Thanks, this is going to more useful than I first thought … And if I can manage to get the image API I have in my head working at scale, even I will be impressed by myself.

5 Likes

I have to admit that originally I was kind of skeptical about keeping images & content together.

But after seeing the demo that @bep made for .Resources , I can’t wait until the release.

To prepare for it I have already began reorganizing my static assets alongside content files.

But the interesting thing is that it is possible to publish a Hugo project with the new organization right now!

Here is my semi-magical shortcode:

{{% asset_img "1.jpg" %}}

And here are the contents of asset_img.html:

<!-- image -->
<figure>
{{ $base := $.Page.Permalink | replaceRE "([^/]*)/$" "" }}
{{ $link := $.Page.RelPermalink | replaceRE "([^/]*)/$" "" }}
{{ $file := .Get 0 }}
{{ $.Scratch.Add "src" $link }}  
{{ $.Scratch.Add "src" $file }} 
{{ $src:= $.Scratch.Get "src"}}  
{{ $config := imageConfig (printf "/content/%s" $src) }}
        <img class="thumb b-lazy" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-src="{{ $base }}{{ .Get 0 }}" alt="{{ with $.Page.Params.title}}{{.}}{{end}}" height="{{$config.Height}}" width="{{$config.Width}}" />
            <noscript>
    <img src="{{ $base }}{{ .Get 0 }}" alt="{{ with $.Page.Params.title}}{{.}}{{end}}"/>
  </noscript>
</figure>
<!-- image -->

First of all I have set a variable called $base with the .Permalink of the post in which the shortcode resides. In this variable I have also piped a Regular Expression to remove the final part of the permalink after the last slash to get the content directory where both content and image reside.

So http://localhost:1313/blog/2017/07/after-as-before/ becomes http://localhost:1313/blog/2017/07/

Then I am constructing the img data-src with "{{ $base }}{{ .Get 0 }}" That’s straightforward enough. The above permalink variable alongside a shortcode positional parameter.

Now I always use imageConfig in my img shortcodes because I use modal plugins like Photoswipe that require width and height values.

THe imageConfig function first reads a file from the file system to determine its dimensions and Hugo outputs the img URL later.

Therefore I set a second variable called $link to get the page’s RelPermalink because if I used the absolute Permalink I would get a broken URL.

Again I performed the same RegEx as before, in this variable, to remove the last part and point to the content directory.

Then I set the following variables (the first one gets the shortcode filename and then with .Scratch I combine it with the RelPermalink variable)

{{ $file := .Get 0 }}
{{ $.Scratch.Add "src" $link }}
{{ $.Scratch.Add "src" $file }}
{{ $src:= $.Scratch.Get "src"}}

And finally I use the $src variable to get the image’s dimensions with imageConfig
{{ $config := imageConfig (printf "/content/%s" $src) }}

That’s it! It’s very versatile in the sense that I can prepare for .Resources and have a functional Hugo site right now.

2 Likes

Feedback wanted in this discussion: