Recipe Template for Ryder Theme

Optimize Recipe Content with the Schema

The recipe templates for The Ryder Theme for Hugo websites are progressing well. Today I released an update that creates the schema.org json-ld specification tags for a recipe. This allows your recipe content to show up as “rich content” in search engines and social media platforms.

Using my favorite sample data recipe, Tarragon Beets Salad, you can see the metadata laid out as it is seen by computers on this Google test tool. Rich Results Test.

Test results from the google rich results tool.

The warnings received are because there were no images defined for each HowToStep of the recipe. The entire recipe does have an image url; it uses the same image url that is used to generate the OG tags.

This update was helped greatly by @idarek on the Hugo forums and his recipe website Yummy Recipes UK - Nut-Free Cooking & Baking. I did modify the code posted on those forum pages to expand the schema to support HowToStep for each step of the recipe, instead of just posting the entire recipe in one HowToStep.

I did this by including a table in the Front matter of each page for each step and the data.

Front matter

Ingredients is an actual taxonomy setup in hugo.toml, so that is just a summary of the main ingredients. It then creates taxonomy pages for these main ingredients, so I can have summary pages of all the recipes using my favorite ingredients easily… like Mushrooms

recipeIngredients is the list of actual recipe ingredients with the units built into the string. There is the dream of separating units out but it is too complicated to do with Hugo on this first pass through.

Each [[recipeInstruction]] is essentially an array of tables to which you can add what is needed. I override name with a ** which skips that row in the schema and outputs a header in the template.

ingredients = [
  "beets",
  "celery",
]
recipeIngredients = [
    "**FOR SALAD",
    "5 Beets",
    "½ heart of celery",
    ...
]
[[recipeInstructions]]
  name = "**For Beets (Can be done the day before)"
[[recipeInstructions]]
  name = "preheat"
  text = "Preheat oven to 425."
[[recipeInstructions]]
  name = "slice"
  text = "Cut (optionally peeled) beets into medium thin slices."
  ...

Shortcodes

Here are the shortcode which are included as part of the Ryder Theme from arts-link.com.

recipe-ingredients-list.html

 1{{ .Page.Params.recipeIngredientsTitle | default "" }}
 2<div class="pl-2 grid grid-cols-2 gap-x-4">
 3  {{ with .Page.Params.recipeIngredients }}
 4    {{ $itemCount := 1 }}
 5    {{ range $index, $element := . }}
 6      {{ if findRE "^\\*\\*" $element }}
 7        <h3 class="col-span-2" id="ingredient-sub">{{ replaceRE "^\\*\\*" "" $element }}</h3>
 8      {{ else }}
 9        <div class="relative flex items-start mb-2">
10          <span class="flex-none w-8 h-8 rounded-full flex items-center justify-center dark:bg-rose-950 dark:text-neutral-100 dark:border-neutral-200 bg-sky-300 border-violet-900 text-violet-900 border-2 ">{{ $itemCount }}</span>
11          <span class="ml-2">{{ $element | markdownify }}</span>
12        </div>
13        {{ $itemCount = add $itemCount 1 }}
14      {{ end }}
15    {{ end }}
16  {{ else }}
17    <div>No ingredients listed.</div>
18  {{ end }}
19</div>

recipe-howto-steps-list.html

 1{{ $page := .Page }}
 2<div class="pl-2 grid">
 3  {{ with .Page.Params.recipeInstructions }}
 4
 5    {{ $itemCount := 1 }}
 6    {{ range $index, $element := . }}
 7      {{ if findRE "^\\*\\*" $element.name}}
 8        <h3 class="" id="ingredient-sub-{{ $itemCount }}">{{ replaceRE "^\\*\\*" "" $element.name }}</h3>
 9      {{ else }}
10        {{ if $element.image }}
11        {{- $opts := dict
12          "page" $page
13          "alt" $element.name
14          "title" $element.name
15          "src" $element.image
16          "overlay" "images/bs_full_wordmark.png"
17        }}
18        {{- partial "picture.html" $opts }}
19        {{ end }}
20        <h4 class="relative flex items-start mb-2" id="{{ $element.name }}">
21          <span class="flex-none p-4 rounded-full flex items-center justify-center dark:bg-rose-950 dark:text-neutral-100 dark:border-neutral-200 bg-sky-300 border-violet-900 text-violet-900 border-2 text-4xl"><i class="fa-regular fa-hand-point-right"></i></span>
22          <span class="ml-2 font-normal">{{ $element.text | markdownify }}</span>
23        </h4>
24        {{ $itemCount = add $itemCount 1 }}
25      {{ end }}
26    {{ end }}
27  {{ else }}
28    <div>No How-To Steps listed.</div>
29  {{ end }}
30</div>

Test results

Rich results from the google rich results tool.