Break range loop

Hi,

I’m trying to cause an error if a value isn’t found in a JSON file.

I’m iterating through the file with a range loop and finding the values ok. However, I have tried adding a {{ break }} when the value is found so that I can have an else that causes an error but it doesn’t seem to be working.

According to the docs, break seems to be supported but googling seems to suggest there’s a bit of history… can anyone tell me if what I am trying is possible?

Thanks!

Please show an example.

So, this does what I want:

{{ $searchterm := .Inner }}
{{ $searchtermlower := lower $searchterm }}

{{ $file :=  "/glossaryitems.json" }}

{{ $glossary := getJSON $file }}
{{ range $term, $value := $glossary }}
    {{ $term := lower $term }}
    {{ if eq $term $searchtermlower }} 
        <span class="definition" >{{ $value.definition }}</span>
    {{ else if eq $term (strings.TrimSuffix "s" $searchtermlower) }}
        <span class="definition">{{ $value.definition }}</span>
    {{ end }}
{{ end }}

But when I try to cause an error when the term is not found, it seems to error every time:

{{ $searchterm := .Inner }}
{{ $searchtermlower := lower $searchterm }}

{{ $file :=  "/glossaryitems.json" }}

{{ $glossary := getJSON $file }}
{{ range $term, $value := $glossary }}
    {{ $term := lower $term }}
    {{ if eq $term $searchtermlower }} 
        <span class="definition" >{{ $value.definition }}</span>
        {{ break }}
    {{ else if eq $term (strings.TrimSuffix "s" $searchtermlower) }}
        <span class="definition">{{ $value.definition }}</span>
        {{ break }}
    {{ else }}	 
        {{ errorf "Glossary term not found: %q in %s" $searchterm .Position }}
    {{ end }}
{{ end }}

Thanks!

Comments:

  1. I’m not sure why you need a loop here, provided that the keys in your JSON file are lowercase
  2. There’s no need to use getJSON (which is deprecated); use the data directory instead.
data/
└── glossaryitems.json

layouts/shortcodes/get-glossary-definition.html

{
  "foo": {
    "definition": "This is the definition of foo."
  },
  "bar": {
    "definition": "This is the definition of bar."
  }
}

layouts/shortcodes/get-glossary-definition.html

{{ with .Get 0 | lower }}
  {{ with or
    (index site.Data.glossaryitems .)
    (index site.Data.glossaryitems (strings.TrimSuffix "s" .))
  }}
    <span class="definition" >{{ .definition }}</span>
  {{ else }}
    {{ errorf "The %q shortcode was unable to find the definition of %q. See %s" $.Name . $.Position }}
  {{ end }}
{{ else }}
  {{ errorf "The %q shortcode requires a single positional parameter: the term to look up. See %s" .Name .Position }}
{{ end }}

And the shortcode calls from Markdown:

{{< get-glossary-definition foo >}} 

{{< get-glossary-definition foos >}} 

{{< get-glossary-definition Foo >}} 

{{< get-glossary-definition Foos >}} 

The keys are in title case while the shortcode is passed a mixture of cases.
Interesting about getJSON though. I will investigate data directories.

You still don’t have to loop. You can convert the argument to title case before the lookup.

That might be a bit more complex. For example, acronyms that are in all caps in both cases…

If it were me, I would lowercase all keys in the DB. It just makes things so much easier.

1 Like

Also, the title function doesn’t convert “ABC” to “Abc” – it remains “ABC”.

If it were me, I would lowercase all keys in the DB. It just makes things so much easier.

Unfortunately, there is another shortcode that simply displays a formatted list of all the keys and their values so that would involve further updating…

Also, the title function doesn’t convert “ABC” to “Abc” – it remains “ABC”.

Oh ok. I’ll take another look at the list of keys and do some testing. Thanks for the pointers!

Here’s quick example:

git clone --single-branch -b hugo-forum-topic-48702 https://github.com/jmooring/hugo-testing hugo-forum-topic-48702
cd hugo-forum-topic-48702
hugo server

And the error checking should give users a clue (e.g., “eu” for European Union returns an error, so it must be “EU”).

Or you could add more expressions to the “or” statement (e.g., first to upper, all upper, etc.).

1 Like