How to customise json values in hugo?

Hi there,

I my hugo pages front matter i have the value floor

details:
  sqm: 34
  floor: 2nd

How can i tell hugo to convert the values to a custom number such as

"basement" = 0 
"lower ground", = 1 
"ground", = 2 
"upper ground", = 3 
"1st", = 4 
"2nd", = 5

etc.

this is my existing json template

{{- $.Scratch.Add "data" slice -}}
{{- $pages := where .Site.RegularPages "Section" "apartments" -}}
{{- $sortedPages := sort $pages ".Params.title" "desc" -}}
{{- range $sortedPages -}}
{{- $content := .Content | plainify | humanize | truncate 140 -}}
    {{- with .Params -}}
        {{- $.Scratch.Add "data" (dict "id" .title "date" .date "lastmod" .lastmod "details" .details "description" $content) -}}
    {{- end -}}
{{- end -}}
{{- $.Scratch.Get "data" | jsonify -}}

thanks

    {{- with .Params -}}
        {{- $floor := "" }}
        {{- with .details }}
          {{- $floor = .floor }}
        {{- end }}
        {{- $.Scratch.Add "data" (dict
          "id" .title
          "date" .date
          "lastmod" .lastmod
          "details" .details
          "floor" $floor
          "foo" "bar"
          "description" $content)
        -}}
    {{- end -}}

You can add any custom data, e.g. the floor and foo on the example above, what you need to do is parse the params and append it to the dict.

1 Like

I still don’t get it, bit confused try many variations but have no idea what you mean and what i am doing. the $floor will simply get the value but how can i define that value to change?

How i tell hugo to turn basement to 0 and ground to 2 etc?

Thanks

I don’t understand what is the relations between those two code snippet, :confused: the first one are the front matter parameters, I’m confused by the second one, what is it? It would be helpful for others to answer your question if you could explain those parameters and their relations in detail.

2 Likes

Hi @razon

So if the front matter value is 2nd. Then the output json is “floor”:“2nd” but instead i want “floor”:“5”

details:
  sqm: 34
  floor: 2nd

The first 1 is frontmatter in yaml and the second one shows the value i would like to output in json. if possible to do so in hugo.

Thank you for taking the time to help

Is there any reason not to declare floor as 5 in front matter? If you want to parse 2nd as 5, you’ve to transform the parameter in some rule, but I couldn’t provide futher info, since I don’t know why 2nd represents 5.

You could use a dict for the mapping.

1 Like

Hi @razon

Yes, there are around 60,000+pages which will require frontmatter modification. So for me it will be way easier option to let json modify these values in the json template.

Thanks

HI @chrillek

Can you please provide an example. What i realise the normal hugo fucntion that normally work are sometime not fucntioning the same way in the json template for me.

Thanks

Hi @chrillek

Are you suggesting something like this in json template of hugo? doesnt seems to be working for me

{{- $.Scratch.Add "data" (dict "floor" (cond
    (eq .details.floor "basement") 0
    (eq .details.floor "lower ground") 1
    (eq .details.floor "ground") 2
    (eq .details.floor "upper ground") 3
    (eq .details.floor "1st") 4
    (eq .details.floor "2nd") 5
    0  # Default value if the floor value is not in the specified list
)) -}}

You want to map keys to values. That’s what a dict does. Given the lack of context, that’s all I can say.

Sounds like you want a lookup table. Something similar to this:

{{- $lookuptable := dict
  "1st" "lower_ground"
  "1"   "lower_ground"
  "2nd" "ground"
  "2"   "ground"
}}
{{- $myparam := "2nd" }}
{{- $myvalue := index $lookuptable $myparam }}{{/* results in "ground" */}}
1 Like

Hi @McShelby

This gives me the idea of what you mean but still cant impliment.

i have front matter values like this

In the front matter floor which keeps values in the format "Basement", "Lower ground", "Ground", "Upper ground", "1st", "2nd", "3rd", "4th", "5th", "6th", "7th", "8th", "9th", "10th", "15th", "20th", "30th", "40th", "50+"

in json template i use

{{- with .Params -}}
{{- $.Scratch.Add "data" (dict "lastmod" .lastmod (dict "sqm" .details.sqm "floor" .details.floor)) -}}
{{- end -}}

this output json value "floor":"2nd" now instead of 2nd i would like to get single numeric value for 2nd “5” like this format

what i cannot figure out is in need to dict at what stage in the $.Scratch.Add or outside? at what stage i tell hugo that these values are coming from .details.floor?

Thank you for taking the time to help

Current error/issue

i try the above in multiple format this is the last one i tried

{{- $floor := .details.floor (dict "Basement" "1")}}

which results in error:

execute of template failed: template: _default/properties-for-sale.json.json:6:22: executing "_default/properties-for-sale.json.json" at <.details.floor>: can't evaluate field details in type page.Page

what i am doing wrong here? Is this the correct format to use?

2nd implementation

2nd format after better understanding your solution is this which also result in error:

{{- $lookuptable := dict
        "Basement" "1"
        "Lower ground" "2"
        "Ground" "3"
        "Upper ground" "4"
        "1st" "5"
        "2nd" "6"
        -}}

        {{- $floorvalue := .details.floor }}
        {{- $floor := index $lookuptable $floorvalue }}

the error message in hugo is :

execute of template failed: template: _default/properties-for-sale.json.json:35:22: executing "_default/properties-for-sale.json.json" at <index $lookuptable $floorvalue>: error calling index: index of type map[string]interface {} with args [<nil>] failed: value is nil; should be of type string


Since not all pages have the floor value i try the with index else but failed i will really appreciate if someone can show the light to solve this

Hi all,

Using this code i can produce the values 0,1,3,4,5 etc but cannot place it in the {{- $.Scratch.Add "data" (dict

{{- $lookuptable := dict
 "Basement" "1"
 "Lower ground" "2"
 "Ground" "3"
 "Upper ground" "4"
 "1st" "5"
 "3rd" "7"
 "2nd" "6"
 "4th" "8"
 "5th" "9"
 "6th" "10"
 "nil" "0"
-}}
{{- $floor := .details.floor }}
{{ if and $floor (index $lookuptable $floor) }}
{{ index $lookuptable $floor }}
{{ else }}
 0
{{ end }}

this still have 2 issues:

  1. I have duplicate values in json once at the begingin and second at the {{- $.Scratch.Add "data" (dict "lastmod" .lastmod (dict "sqm" .details.sqm "floor" $floor)) -}}
  2. Secondly within the {{end}} tag i get proper values but outside i still get 2nd instead of 2

Thanks

Hi @McShelby

This code works fine as long as all the pages have the floor value

{{- $lookuptable := dict
            "Basement" "1"
            "Lower ground" "2"
            "Ground" "3"
            "Upper ground" "4"
            "1st" "5"
            "3rd" "7"
            "2nd" "6"
            "4th" "8"
            "5th" "9"
            "6th" "10"
            -}}
            {{- $floorvalue := .details.floor }}
            
            {{ $floor := index $lookuptable $floorvalue }}

// Using it anywhere like this: the floor value is {{ $floor }}

The only issue is that it cannot handle the empty state in front matter. if a page have no floor value it fail the hugo build

Any solution on how to fix this in the json template?

Thanks

See: Templating | Hugo

1 Like

Thank @McShelby

I can use these regual hugo functions in normal .html layouts but i am strugling to understand how to use it in json template.

Normally i will use {{ if .details.floor }} condition but that seems to be not allowed in the dict as it seems to produce errors that i define above

Thanks

Finally made it work using like this

{{- $floorvalue := .details.floor -}}
{{- if and $floorvalue (index $lookuptable $floorvalue) -}}
{{- $floor := index $lookuptable $floorvalue -}}
{{- $.Scratch.Add "data" (dict "lastmod" .lastmod (dict "sqm" .details.sqm "floor" $floor)) -}}
{{else}}
{{- $.Scratch.Add "data" (dict "lastmod" .lastmod (dict "sqm" .details.sqm )) -}}
{{- end -}}

I wish there was a better way as these if else sound really stupid as the json template grows. wish there was a different method i can figure out to make it work but thats all i can do to make it work.

Thanks for taking time @McShelby