Is it possible to parametrize references?

I have price calculation in a template that looks like this:

{{ with $.Site.Data.prices.supplier1 }}
Price calculation
{{ end }}

I have 2 suppliers. Is it possible to store references to supplier1/suppler2 data in .Params - like (in YAML front matter):

supplier1: “{{ with $.Site.Data.prices.supplier1 }}”

supplier2: “{{ with $.Site.Data.prices.supplier2 }}”

I want to be able to choose between
{{ with .Site.Data.prices.supplier1 }} and {{ with .Site.Data.prices.supplier2 }}

I feel like that this could be useful:

In the example it shows how to do look up different data using a variable from the front matter.

When the template is rendered, the frontmatter evaluation is done. So you can’t set it later on because it won’t be read (uneducated guess). It would probably lead to complications further down the road anyway.

Have a look at .Scratch. This is your notepad to save values while doing templating.

There are some notes about how to access these values global or in partials - so be careful how to define your variables. It’s pretty straight forward if you want to carry values around.

Thank you guys!
It’s a shortcoming of Hugo that a reference to a partial or data file can’t be stored in a parameter. OK, I will find a workaround.
@davidsneighbour, do you think I can store a reference in a .Scratch - and it will be usable?? Do you know how I can set .Scratch in .Params?

I was looking for something like
{{ if .Params.supplier1 }}
{{ with $.Site.Data.prices.supplier1 }}
{{ end }}

{{ if .Params.supplier2 }}
{{ with $.Site.Data.prices.supplier2 }}
{{ end }}

I don’t think of it as “shortcoming” because it’s possible. It’s just not the task of a template to start configuring something. You can store whatever you want in a GLOBAL scratch and access it where ever. You have to move away from “let’s put it into .Params” and into “let’s put it into my own $supplierselection”. Then it works.

Apart from this: maybe I understand your question completely wrong:

Frontmatter (YAML):

supplier:
    name: "supplier 1"
    address: "somewhere"

Somewhere in the page layout:

{{ with .Params.supplier }}
{{ .name }}
{{ .address }}
{{ end }}

That is possible. can be deeper structured. You need to have the “dot” on the page-“object” for this to work or just use another variable where it is located.

If you want to define “use supplier 1” via frontmatter, it’s the same way. You for instance add the supplier to a data file, then in the frontmatter you add supplier: "supplier1" Then you use the index function to write something like:

{{ with index .Site.Data.suppliers .Params.supplier }}
...

Here the data file has to have a key supplier1:, then below it name and address like above.

If not let me know and I’ll write a quick sample of how a global scratch could look like.

@davidsneighbour Thank you very much! I’ll try to figure it out.
My current idea is to have a dedicated template for each of the suppliers, but this may be a more elegant way if it works out.

{{ partial (printf "%s%s%s" "subfolderinpartials/" (index .Site.Data.suppliers .Params.supplier) ".html" ) }}

Then add /layouts/partials/subfolderinpartials/supplier1.html and supplier2.html.

But I agree, my solution might be better, because it separates your layout from the content (in data). And you just add a third supplier by adding it to data.

Thank you very much! This may be the solution, but I’m not understanding it yet.
Do I understand you correctly, that say, I have

/layouts/partials/suppliers/supplier1.html and supplier2.html.

In those files I have content like

{{ with $.data.prices.supplier1 }}
<select class="order form-control border-0" id="select-0" required>
	<option value="{{ $price1 }}">{{ .product1 }}</option>
	<option value="{{ $price2 }}">{{ .product2 }}</option>
</select>
{{ end }} 

{{ with $.data.prices.supplier2 }}
<select class="order form-control border-0" id="select-0" required>
	<option value="{{ $price1 }}">{{ .product1 }}</option>
	<option value="{{ $price2 }}">{{ .product2 }}</option>
</select>
{{ end }} 

In YAML frontmatter of content files like

content/product1/productDescription.md
content/product2/productDescription.md

I have configs like

suppler: supplier1
or
suppler: supplier2

Now in my _default.html template I use

{{ partial (printf “%s%s%s” “suppliers/” (index .Site.Data.suppliers .Params.supplier) “.html” ) }}

to insert supplier1.html or supplier2.html into the template.

What is going on in this line? This is not clear.
What “%s%s%s” stands for?

In your layouts/partials/subfolderinpartials/supplier1.html you have

<select class="order form-control border-0" id="select-0" required>
	<option value="{{ $price1 }}">{{ .product1 }}</option>
	<option value="{{ $price2 }}">{{ .product2 }}</option>
</select>

in supplier2 the second code.

Have a look at printf and index (see links below).

printf PRINTs Formatted content.

It’s very powerful, but for now, all you need to know is that %s means print a string.

So printf "%s%s%" param1 param2 param3 means print these three params without space after each other and use their values as string (%s, you could read them as anything else from integers to dates to whatever).

The partial looks in the folder /layouts/partials for a file and the rest is the formatted URL. So, you might go just with 2 %s and print the suppliername and “.html” in that place or you have a subfolder.

Other than than I think you understand it. The last line with the partial and print loads either supplier1 or supplier2.html from your partials subfolder.

Hello @davidsneighbour,

right now I have the following setting:

the acting template:
_default/single.html

price calculators:
_default/suppliers/supplier1.html
_default/suppliers/supplier2.html

pricelists: sections suppler1 and suppler2 in
data/prices.yml

configs in content/productDescription.md files:
supplier: [“supplier1”]
or
supplier: [“supplier2”]

the acting function:
{{ partial (printf `%s%s%s` `suppliers/` (index .Site.Data.prices .Params.supplier) `.html` ) }}

the error message at starting the hugo server (contains the content of the pricelist):
Error: Error building site: failed to render pages: render of “page” failed: execute of template failed: template: _default/single.html:272:3: executing “main” at <partial (printf %s%s%s suppliers/ (index $.Site.Data.prices .Params.supplier) .html)>: error calling partial: partial “suppliers/map[HDD:Optional Extra HDD HDD1:No Extra HDD HDD2:HDD 1Tb HDD3:HDD 2Tb HDDp1:%!s(int=0) HDDp2:%!s(float64=44) HDDp3:%!s(float64=75) OS:Select Operating System OS1:MS Windows 7 64-bit Licensed OS2:MS Windows 10 64-bit Licensed OS3:Linux Mint 64-bit Licensed OSp1:%!s(float64=35) OSp2:%!s(float64=35) OSp3:%!s(float64=5) RAM31:DDR3 2GB RAM32:DDR3 4GB RAM33:DDR3 8GB RAM3p1:%!s(float64=13) RAM3p2:%!s(float64=20) RAM3p3:%!s(float64=33) RAM41:DDR4 4GB RAM42:DDR4 8GB RAM43:DDR4 16GB RAM44:DDR4 32GB RAM45:DDR4 64GB RAM4p1:%!s(float64=26) RAM4p2:%!s(float64=42) RAM4p3:%!s(float64=80) RAM4p4:%!s(float64=140) RAM4p5:%!s(float64=280) SSD:Select SSD SSD1:SSD 16GB SSD2:SSD 32GB SSD3:SSD 64GB SSD4:SSD 128GB SSD5:SSD 256GB SSD6:SSD 512GB SSD7:SSD 1Tb SSDp1:%!s(float64=10) SSDp2:%!s(float64=15) SSDp3:%!s(float64=17) SSDp4:%!s(float64=25) SSDp5:%!s(float64=39) SSDp6:%!s(float64=72) SSDp7:%!s(float64=115) VESA:Select VESA bracket VESA1:No VESA bracket VESA2:VESA bracket VESAp1:%!s(int=0) VESAp2:%!s(float64=5) margin:%!s(float64=1.25)].html” not found

Can you see what I’m doing wrong?

No, I can’t :slight_smile: Because you post only the things that YOU find connected to the issue. Could you please create a simple repository with a working demo of what throws the error? like three four sample content files and all connected layout files. No need to add design. Even better if you can make the original repo public.

Everyone trying to help will need more info and appreciates something they can use locally to test it out.

@ pkollitsch Sorry, I don’t know how to create a repo. I tried - too complicated. I’ll do it in the future.

This is the syntax I need:
{{ partial (printf `%s%s%s` `suppliers/` (index .Params.supplier) `.html` ) }}

However I’m getting an error message again: executing “main” at <partial (printf `%s%s%s` `suppliers/` (index .Params.supplier) `.html`)>: error calling partial: partial “suppliers/supplier1.html” not found. - This happens while _default/suppliers/supplier1.html exists.

I have 2 directories that contain partials: layouts/_default and layouts/partials.
The main product template is layouts/_default/single.html

If suppliers directory is in _default, the server does not start - the error message is “partial not found”. If it is in partials directory - the partial is found, the server starts, but the partial suppliers1.html is not loaded into the template…

I’ve removed the suppliers folder and put supplier1.html into partials folder: partials/supplier1.html
The fundtion line is: {{ partial (printf `%s%s` (index .Params.supplier) `.html` ) }}

To sum it all up - if supplier1.html is not found, the server does not start. If it is found, the server starts, but it is not loaded into the template.
Why it is not loaded?!

I’ve solved my problem of connecting different price lists with this function:
{{ with (index .Site.Data.prices .Params.supplier) }}

{{ end }}

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