Shortcode to display datas from json file

I am trying to have a shortcode to display datas from a json file as a table or a list using the new function transform.Unmarshal.

For example having the following json file:

{ "device": "item 1",

"brand": "Brand 1",
"category": "Cat 1" },

{ "device": "Item 2",
"brand": "Brand 2",
"category": "Cat 2" },

{ "device": "Item 3",

"brand": "Brand 2",
"category": "Cat 2" },

{ "device": "Item 4",
"brand": "Brand 3",

"category": "Cat 3" },

{ "device": "Item 5",

"brand": "Brand 1",

"category": "Cat 1" }

I would like to get a table or list or tabs selection to display all items per Category (and possibly to count them).

The json file (whislist.json) could be located in page bundle or in assets/data.

I put the wishlist.json file in page bundle (content/news/wishlist/...)

I am trying to follow [the Hugo docs]( transform.Unmarshal ) with the shortcode wishlist.html as follows:

{{ $data := dict }}

{{ $path := "wishlist.json" }}

{{ with .Resources.Get $path }}

  {{ with . | transform.Unmarshal }}

    {{ $data = . }}

  {{ end }}

{{ else }}

  {{ errorf "Unable to get page resource %q" $path }}

{{ end }}

{{ range $category, $device := .Site.Data.wishlist }}

  <p>{{ $category | title }}</p>

  <ul>

    {{ range $device }}

      <li>{{ . }}</li>

    {{ end }}

  </ul>

{{ end }}

Unfortunately I get the following error :

failed to extract shortcode: template for shortcode "wishlist" not found

Thanks for your help and guidance

restart the server.
check your layout paths, spelling capitalization, folders
lookup order new/old system
check your content file

or just post a link to your repo

Maybe I missed something as I already did what you suggested.

However please find here the repo

I just checked the first errors and looks like you have a problem with

  • identifying resources.
  • context

the shortcode:

  • you call it like this {{< wishlist >}} → no arguments

The . in shortcode is the shortcode (context) :wink:

You code:

{{ $data := dict }}
{{ $path := "data/wishlist.json" }}
# the DOT here is the Shortcode - to access page resources use .Page.Resources
{{ with .Resources.Get $path }}
  {{ with . | transform.Unmarshal }}
    {{ $data = . }}
  {{ end }}
{{ else }}
# with the change above it fails here, cause there is no such page resource content/news/wishlist/data/withlist.json
  {{ errorf "Unable to get page resource %q" $path }}
{{ end }}

{{ $category := $data.properties.category }}
{{ $device := $data.properties.device }}
{{ range $data }}
  <p>{{ $category }}</p>
  <ul>
    {{ range $device }}
      <li>{{ . }}</li>
    {{ end }}
  </ul>
{{ end }}

Here’s some code that:

  • creates a sorted list of categories (determined by the data itself, so no need to know which categories exist)
  • containing a sorted list of assigned devices
{{ $data := dict }}
{{ $path := "wishlist.json" }}
{{ with .Page.Resources.Get $path }}
  {{ with . | transform.Unmarshal }}
    {{ $data = . }}
  {{ end }}
{{ else }}
  {{ errorf "Unable to get page resource %q" $path }}
{{ end }}

{{ warnf "data: %s" (debug.Dump $data) }}
{{ range apply $data "index" "." "category" | uniq | sort}}
  <p>{{ . }}</p>
    <ul>
      {{ range sort (where $data "category" .) "device" }}
        <li>{{ .device }}</li>
      {{ end }}
    </ul>
{{ end }}

p.s.

building with hugo fails with a lot of resource errors on minify …

in head/css.html you use

{{ $css := resources.Match "css/*.css" | resources.Concat "main.css" -}}
# the resource is in $css
  {{- if hugo.IsDevelopment -}}
    <link rel="stylesheet" href="{{ $css.RelPermalink }}">
  {{- else }}
# what is the DOT here - it's the PAGE passed by   by head.html {{ partialCached "head/css.html" . -}}
    {{- with . | minify | fingerprint }}
      <link rel="stylesheet" href="{{ $css.RelPermalink }}" integrity="{{ .Data.Integrity }}" crossorigin="anonymous">
    {{- end -}}
  {{- end -}}

Thanks you for the solution

PS: Does it mean that it’s not recommended to minify either css or js, html ?

No. It means that you should check what . (the dot) refers to. As @irkode pointed out, in your head/css.html the line with . | minify... does not refer to CSS but to the current page. Minifying the current page and fingerprinting it makes not a lot of sense.

You should definitely read and digest

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