Check empty front matter field

If I want a front matter field location: "" not to show up in content when it is empty, how to go about it? This solution fails.

The error is range can’t iterate over value with value here being one of the existing values in front matter like location: "Tokyo". Since this is remote data, I don’t have access to the field itself.

The solution you linked works if used properly. You might have an issue with how you call the shortcode. Maybe show your implementation, and a sample of the data it receives and someone might be able to help you.

Part of the JSON front matter looks like so (location is not an array)

{
  "Name": "ENT Clinic",
  "Location": " ", <!-- or location: "Tokyo" -->,
  "Type": "Medical Clinic"
}

I then just copy pasted the code in the attached link and replaced .Params.product with .Params.Location.

I cannot find any solution on the internet. Or perhaps the search terms I am typing are incorrect.

Check this snippet.

FrontMatter:

---
title: "First post"
custom:
    - name: "ENT Clinic"
    - location: " "
    - type: "Medical Clinic"
---

First loop:

    {{/* print 'key' and 'value' when the value is not empty or set to 'false' */}}
    {{with .Params.custom}}
        {{range .}}
            {{range $key, $value := .}}
                {{if $value}}
                    <p>{{$key}} | {{$value}}</p>
                {{end}}
            {{end}}
        {{end}}
    {{end}}

Output of the first loop:

name | ENT Clinic

location |

type | Medical Clinic

Second loop

    {{/* print 'key' and 'value' when the value is not empty or set to 'false' and do not contain a single space */}}
    {{with .Params.custom}}
        {{range .}}
            {{range $key, $value := .}}
                {{if (and ($value) (ne $value " "))}}
                    <p>{{$key}} | {{$value}}</p>
                {{end}}
            {{end}}
        {{end}}
    {{end}}

Output of the second loop

name | ENT Clinic

type | Medical Clinic
  1. Mine is not an array. So this solution or the previous one I attached won’t work.
  2. I have 14 fields I want to check if they are empty or not, so I would prefer the solution to be in line with the method I attached or similar so I can only pass the front matter values in a simpler way.

Solution similar to the provided by you:

FrontMatter

---
title: "First post"
name: "ENT Clinic"
location: ""
note: "Medical Clinic"
---

Single.html

    {{ with partial "hasValues.html" .Params.location}}
        {{.}}
    {{end}}

hasValues.html

{{$value := .}}
{{$data := newScratch}}
{{$data.Set "hasValue" false}}

{{if $value}}
    {{$data.Set "hasValue" true}}
{{end}}

{{ return $data.Get "hasValue" }}

Doesn’t work either. Instead shows location: "" and location: "Tokyo" as true in content in the frontend. That is, in the frontend, it shows the word “true” in that field.

I want location: "" to be hidden in content entirely but location: "Tokyo" to appear as is. So basically, empty string, don’t show in content.

Two more questions:

  1. Should the param key also be printed? I mean the string location: from your example.
  2. Do you need to call each param separately (i.e.:
  • with partial "hasValues.html" .Params.location
  • with partial "hasValues.html" .Params.type

or can you apply a loop over all params in the single.html?

No. I am translating those fields, so those will be hard corded e.g {{ T "type" }}: {{ $value }} in templates.

I’m not sure how that would work, since I am calling those fields separately like in question one. That means each field is to be wrapped in a way that it shows if present or is hidden entirely when empty in the front matter.

Some of the remote files have empty fields in different entries, hence the need to wrap every entry with a condition. For example, some have type, but no location or some don’t have both! In that case, insted of showing empty fields, hide them entirely! There are about 14 fields in total that need to be wrapped that way.

Ok - for me it will be easier to loop over all of these fields instead of calling them separately.
How do you load these fields from the remote source? Are they present in frontmatter of the .md file?

Yes they are. see Check empty front matter field - #3 by steppa

I would just put the simplified code from my first answer to the single.html template.

    {{with .Params}}
        {{range $key, $value := .}}
            {{if (and ($value) (ne $value " "))}}
                <p>{{$key}}: {{$value}}</p>
            {{end}}
        {{end}}
    {{end}}

It will make a loop over each param and display key and value if the value is not equal to false, "" or " ".

I noticed another issue. The “type” field is Hugo built-in field and it override the default template. If you can change the way as the params are loaded into .md file I will place them in this way:

{
    "title": "first post",
    "custom": {
        "Name": "ENT Clinic",
        "Location": "Tokyo",
        "type": "Medical Clinic"
    }
}

and loop them this way:

    {{with .Params.custom}}
        {{range $key, $value := .}}
            {{if (and ($value) (ne $value " "))}}
                <p>{{$key}}: {{$value}}</p>
            {{end}}
        {{end}}
    {{end}}

I don’t have control over the data since it is remote. The fields are imported as they are into the front matter. The first option works, but I cannot define the key separately as I want. I am also excluding some fields (I need 14 out of 18), so I don’t want to range over all of them.

Can you explain what do you mean saying:

this part

I don’t know if it is possible to translate the variable inside the loop in the previous snippet. So maybe - if these 14 fields are the same for each page, may you go this way?

single.html - put just one line into a single template

{{partial "printParams.html" .}}

printParams.html - write a separate line for each param by hand. Yes, I know it isn’t the elegant way, but there are only 14 fields to serve, and you will write these only once. And maybe searching for more advanced syntax is not worth it.

{{if .Params.name}}
    {{T "Name"}}: {{.Params.Name}}
{{end}}

{{if .Params.location}}
    {{T "Location"}}: {{.Params.Location}}
{{end}}

{{if .Params.info}}
    {{T "Info"}}: {{.Params.Info}}
{{end}}

The output is as expected - with empty location param you get:

Name: ENT Clinic
Info: Medical Clinic

I was doing that initially before posting the question. I relooked at it again and the problem is the custom key I am inserting before the value. Without it, the code works, but when it is there, its text is left while the value is blank. So {{T "Info"}}: becomes Info: <blank>. Removing the text before the value leaves a blank space. see Screenshot by Lightshot

Any ideas? @regis @jmooring . I am about to pull my hair out coz this data should be up on the site in 24 hours.

Hi @steppa everybody wants to help here, but I’m not sure I understand your problem. You don’t provide any example of your own code. Please do.

It seems you are checking the value of your parameter and only printing it if it’s different than a " " right?

What is the exact test you perform before printing the value?

Basically, what is shown here is what I have Check empty front matter field - #16 by LukaszJedrasiak.

yes. If it’s empty, then it is not shown at all.