Range over string or string array in Go template - go

I am writing a Go template that uses consecutive alpha characters. As a simple example:
{{ range $i, $e := until 2 }}
{{ range $a := .[]string{"a", "b", "c"} }}
<p>{{ $e }}{{ $a }}. Sample Text</p>
{{ end }}
<br>
{{ end }}
Should yield:
<p>0a. Sample Text</p>
<p>0b. Sample Text</p>
<p>0c. Sample Text</p>
<br>
<p>1a. Sample Text</p>
<p>1b. Sample Text</p>
<p>1c. Sample Text</p>
<br>
The above code would work if go templates let you define arrays this way inside the template. I would need something similar to this, or the answer here, with the exception that I am not able to write my own functions. I am using this for another piece of software that lets me write go templates, but I cannot modify the go code itself, meaning no passing variables either.
Am I asking the impossible?

It looks like the template host uses Sprig. Use the list function from Sprig.
{{ range $i, $e := until 2 }}
{{ range $a := list "a" "b" "c"}}
<p>{{ $e }}{{ $a }}. Sample Text</p>
{{- end}}
<br>
{{- end}}
Run an example on the playground.

Related

how to remove the file extension from an href in an go template?

I am new to go-templates and i wonder if there's a way to remove the file extension within the template.
{{- range $val := .Filelist}}
<li>
<a href="{{$val}}">
{{ $val }}
</a>
</li>
{{- end }}
As you can see, i declared my filelist and declared the href. the outcome of this is for example:
1.graph
2.graph
But i only want the 1 or 2 to be shown.

go template alternating design between rows

I have a simple template fetching a list of blog posts:
<div class="row">
<div class="cell">
{{range .Pages}}
<p class="dialogue dialogue--wide">
{{.Title}}
</p>
{{end}}
<br />
<br />
<br />
</div>
</div>
I would like to alternate the design between posts e.g. the first will use a certain class like
and the second record (or even and odd records if you prefer) another p e.g.
thank you!
I suggest solving this with CSS to save yourself some trouble. You can use odd or even in nth-child:
.dalogue:nth-child(odd) {
// CSS Property
}
Alternatively, you can use the index of the items. Below, I am using the modulo operator to determine if it's odd or even.
{{ range $index, $page := .Pages }}
{{ if eq (mod $index 2) 0 }} odd {{ else }} even {{ end }}
{{end}}
Note, I am switching odd and even around. Because the index starts at 0 and not at 1. But when looking at a table, you start counting at 1 and this is also how CSS would behave.
I have implemented the mod function myself using template.Funcs.
t.Funcs(map[string]any{"mod": func(a, b int) int { return a % b }})
https://go.dev/play/p/aAupH-4CugV

Calling variables inside Hugo partial

I have this code I use inside a partial in Hugo to pass context to it.
{{- $ctx := . -}}
{{- $curPage := .page -}}
{{- $otherVar := .otherVar -}}
{{- with $curPage -}}
{{ $section := .CurrentSection }}
{{ if .IsHome }}
<span class="post-section">{{ $section.Title }}</span>
{{ else }}
{{ $section.Title }}
{{ end }}
{{- end -}}
I then add {{- $curPage := . -}} at the top of the template where I want the partial to appear, then call the partial as {{ partial "partial-name.html" (dict "page" $curPage "otherVar" .) }}. However, the content returns nil on the homepage while it works everywhere else sitewide. Could anyone look at my code and tell me where I went wrong?
Sorry - didn't see your with statement.
So {{- $curPage := .page -}}
is a typo.
.Page
Tested on local - most present version of hugo.
Also note - I don't think homepage has a section so your span will output very little as most of the currentsection or section related will return nothing.
Since you call the partial like this:
{{ partial "partial-name.html" (dict "page" $curPage "otherVar" .) }}
^^^^^^^^^^^^
Notice
The dot (.) is contained in .otherVar. To find out if you are on the home page, use something simple like this at the top of partial-name.html:
{{ if .otherVar.IsHome }}
<pre>Debugging: YES .IsHome</pre>
{{ else }}
<pre>Debugging: NOT .IsHome</pre>
{{ end }}
After you test with the above GO HTML fragment, you can update your original code above.
TIP: In the Hugo world, it is common to use "context", "ctx", "page", or "Page" rather than "otherVar" as the name of the dictionary key that contains the dot. For a discussion about this, see Naming convention for page context (within a dictionary) when calling partial: seeking opinions in the Hugo discussion group.
ANOTHER TIP: There are some Hugo weirdnesses related to case sensitivity so I would not use "otherVar" anyway. Instead use "othervar", "context", or any name that is all lower case with no whitespace. I do this because I have spent a lot of time messing around with case sensitivity Hugo issues.

Hugo data files from dynamic parameter

I'm developing a big hugo template. I try to simplfy the problem, so I have two datafile:
PROMO_00_1.yaml
PROMO_00_2.yaml
that are phisically stored in this directory:
themes/data/hp/
So, in the site config the user will decide which of this data file will be used simply indicate it in a param (HpElement).
In the template I call the partial in this way:
{{ partial "multiplepages/homepage/promos/00_promo_singleslide_text_video" (dict "context" . "data" $.Site.Params.HpElement) }}
In a partial I write:
{{ $data_partial := (printf "$.Site.Data.homepage.%s" .data)}}
{{ $data_partial}}
and the Hugo output is on the website:
$.Site.Data.homepage.PROMO_00_1
What I need is to access the single variable inside the .yaml file but the user MUST can decide which YAML file have to use. How can I achieve that?
Thanks
I just finished up a similar use case where I needed to select a YAML based on a date stamp. The index function is key to this operation.
https://gohugo.io/functions/index-function/
Here is a simplified version of my situation:
{{ $date := now.Format "s20060102"}}
{{ $data := (index .Site.Data.schedule $date) }}
{{ with $data }}
<h1>.longdate</h1>
{{ range .times }}
<h2>{{ .name }} - {{ .location }}
{{ end}
{{ end}
The example in the Hugo documentation uses an example where the data file is selected based on an attribute in the front matter.

HUGO IN function not accepting variable as ITEM

I am using the IN function of Hugo that can be used as in SET ITEM as defined at Hugo Documentation for IN
I am trying to filter out posts of a particular category by the below code
{{ range where .Site.Pages "Section" "products"}}
{{ if in .Params.categories "New Arrival" }}
<li>{{ .Title }}</li>
{{end}}
{{end}}
the above code works completely fine.
But if I use a variable instead of a string for the ITEM. It always returns False.
{{ $display_product_cat := "New Arrival" }}
{{ range where .Site.Pages "Section" "products"}}
{{ if in .Params.categories $display_product_cat }}
<li>{{ .Title }}</li>
{{end}}
{{end}}
The above code does not work as expected.
Wondering if I am missing something here. Appreciate your time and help.
You can test what the boolean is by something like:
{{ $i := in .Params.categories "New Arrival" }}
{{ $i }} ## will output true|false
{{ $var := "New Arrival" }}
{{ $j := in .Params.categories $var }}
{{ $j }} ## will output true|false
If it's giving false outcomes, you might need to inspect how your .Params are actually constructed (what pattern are they in, etc.).
Providing more info will allow a better debug for you (like the snippet of your Params).

Resources