Need help understanding content organization for product pages

I’m putting together a small e-commerce site and giving Hugo a try. I’ve got an index page built and a couple other static pages (About, contact us) also working. Now I’m getting into more content and data and not understanding how to build links in the template or set up the data or content files.

I have an index page - a section of that page has a image/link for each product, this is pulled from data files. Sample code:

                {{ range sort .Site.Data.products "weight" }}
                <div class="single__prod {{ delimit .categories ", " }}">
                    <div class="product">
                        <div class="prod__inner">
                            <div class="prod__thumb">
                                <a href="#">
                                    <img src="{{ .Site.BaseURL }}{{ .image }}" alt="{{ .title | plainify }} product images">
                        <div class="product__details">
                            <h2><a href="#">{{ .title | safeHTML }}</a></h2>
                            <span class="prod_price">{{ .price }}</span>
                {{ end }}

*Data files that are placed in site root/data/products. 11 files, one for each product.

My product file looks like this (TOML):

    weight = 1
    title = "Product Name"
    price = "$9.95"
    image = "images/product/1.jpg"
    categories = ["cat--1"]

The index page displays the product image and details from the data file just fine. My next step is to add in the proper link in the two “a href=”#"" portions. I’ve got a product details html file. I’m not sure where to place that or how to build the links to the details page.

I suspect I need to put something in the product-details.html in site root/layouts/products. And I’d probably put a URL element in my product TOML file too. But how does this work so that the product-details.html is built with the data in the product TOML?

Well, you could add a section for the product details under content and use new version 0.32’s bundling feature.

That way you could make a folder for each product, and include details files under there, either in each folder’s or, in a referenced file, and, any images of the product. I am not sure if the referenced file can be anything, or, if your html files would suffice.

As for the links, have you tried adding a line or lines in each data file for those href s? Once you get the product details files set, you’ll know what their URLs are, and then you could add those to your data files.

Btw, I saw your first code block worked and your second didn’t. The first was indented enough but the second wasn’t so I added “fencing” around the second. Edit to see it. It’s just five tildes before and after. I like it better since indenting in here is a bit of a pain.

Hi RickCogley -

Thank you for the tip on tildes, I’ll use that.

I’ve just now read through bundles segment you pointed me to, and I rather like this organization so I think I might try that. In reading that, it has lead me down another path of reading.

I think there is still some short comings in my understanding, let me try something with the bundles and see what I get. I’ll post back with results.

OK - I’m about 80% converted to the page bundle system, a few more things to do and then I can get back to trying to build product pages.

So I have something like:

├── products/
│   ├── prod1/
│   ├── prod2/
│   ├── prod3/
│   └── etc

When I run something like

{{ range where .Site.Pages.ByWeight "Section" "products" }}

I get the following kind of links:


I’d like to not get an output for /products/, just the /products/prod1/. Is there a way to suppress or eliminate an output from the /products/? I’m using this range capability to list the actual products.

Should be .Site.Regular.Pages or .Site.Data.Pages

Great, this works!

I used .Data.Pages.

OK, next step, using the .Resize shown in the Hugo 0.32 HOWTO article that RickCogley linked me to.
I’m having trouble implementing Resize.

My Content folder

├── products/
│   ├── prod1/
│             ├
                 ├ images/
                     ├ prod1.jpg

I’ve tried:

{ $imgVar := (print .Permalink .Params.image_prod1) }}
{{ $imgVar.Resize "120x140" }}   error because of string

{ $imgVar := (print .Permalink .Params.image_prod1) }}
{{ $img := .Resources.GetByPrefix $imgVar }}
{{ $img.Resize "120x140" }}  error Resource.resource?

Thank you in advance.

GetbyPrefix is exactly what it sounds like. You are using it in conjuction with a permalink that you are getting with print. So it’s natural that you’re getting an error.

Check out @bep test repo for 0.32 to get a better understanding of the new features.

Thank you @alexandros

Doing more reading, digging and checking out that repo, I came up with this to be working:

{{ $img := (.Resources.GetByPrefix .Params.image_prod1 ) }}
{{ with $img }}
{{ $resized := $img.Resize "120x140" }}
<img src="{{ $resized.Permalink }}" alt="small-image">
{{ end }}

And in my file I have something like:

image_prod1: "prod1.jpg"

Oh that’s interesting.

.GetByPrefix is meant to get a file prefix and in your case that should have been prod1 without the .jpg extension

But since you got this working, good for you.

I’ve been through the 0.32 doc and repo a couple times and have spent 30 minutes trying several things. Of course I’m finding new things in the documentation, However i’m still missing something or not seeing and understanding what I need to for my task at hand.

Right now I’m trying to access the other .md files in the bundle. (I’m really glad I was pointed to the bundle of 0.32, it is the organization I need)

I have this:

├── products/
│   ├── prod1/
                 ├ images/
                     ├ prod1.jpg

The Params in I can access and use. The Content I can use as well.
However I can’t figure out how to get the Content of

if I do this:

{{ with .Resources.ByType "page"}}
{{ . }}
{{ end }}

I can see this in the HTML file:

[Page(&#34;desc_long&#34;) Page(&#34;desc_short&#34;)]

Thank you for any help you can provide.

You are not doing it right. See the example at the Docs:

I have been able to get that example to run. I think there is some oddity in that output in that I’m seeing multiple content, however I haven’t dove into that.

This example though still doesn’t show me what I need. I don’t want to loop or range over the .mds. I want to get the Content of a specific .md at point A in my template and content of a different .md at a point B in my template. My thought was that I’d be able to reference the .md. So I’ve been trying to limit ByPrefix or GetPage but I’m not having success.

You need to have {{ .Content }} to render the file’s content.

I haven’t had the need to do what you’re trying to do just yet. And I can’t test it right now.

I understand the .Content requirement.
I also figured out the one oddity I mentioned when i run the example (I have more than two md files).

In my file tree shown above, how would I reference just Instead of

{{ with .Resources.ByType "page" }}
{{ range . }}

Which gives me both desc_short and desc_long.

Have you tried

{{ $desc_short := .Resources.GetByPrefix "desc_short" }}
{{ with $desc_short }}
{{ .Content }}
{{ end }}

This is untested.

Yes, this is one thing I’ve tried and I get no output in the HTML. No errors either from Hugo server.

(Editing the post to be more complete)

I even did this, thinking first I need to limit it to the resources in this bundle.

{{ with .Resources.ByType "page" }}
{{ $desc_short := .Resources.GetByPrefix "desc_short" }}
{{ with $desc_short }}
{{ .Content }}
{{ end }}
{{ end }}

But that didn’t work either. I get a Hugo error in the CL

<.Resources.GetByPref...>: can't evaluate field Resources in type []resource.Resource

I’ve also tried this:

{{ with .Resources.ByType "page" }}
{{ .GetByPrefix "desc_short" }}
{{ .Content }}
{{ end }}

I get a similar error:

executing "products/product-details.html" at <.GetByPrefix>: can't evaluate field GetByPrefix in type []resource.Resource

Another item tried, but failed. My thinking was the first line gets the pages in the bundle (it does). The second line gets the specific page. But it errors.

{{ with .Resources.ByType "page" }}
{{ .GetPage "desc_short" }}
{{ .Content }}
{{ end }}

Error: <.GetPage>: can't evaluate field GetPage in type []resource.Resource