Introduction

Comfy Recipes is a program that allows you to create a rich collection of recipes and create a presentable website from them.

Get started

If you don't have comfyrecipes installed yet, please see Installation

  1. write a recipe in a yaml format to myrecipes/recipes/xxxx.yaml, for example

🗎 myrecipes/recipes/pancakes.yaml:

title: Swedish Pancakes
ingredients:
  - 3 piece egg
  - 1.25 cup milk
  - 0.75 cup all purpose flour
  - 1 tablespoon white sugar
  - 1 tablespoon butter
steps:
  - Beat eggs in a bowl until the mixture is smooth.
  - Add milk
  - Mix flour, sugar and salt in a separate bowl
  - Mix together with the egg mixture, mix until it's smooth
  - heat a griddle
  - Drop just enough of the mixture to the griddle to spread to all corners
  - After about a minute, turn the pancake over
  1. run comfyrecipes build myrecipes/ (this will build the website to myrecipes/out/html)
  2. run comfyrecipes serve myrecipes and navigate to http://localhost:8000 (this will run a web server and allow you to see your rendered recipe)

Installation

Docker

The containers are available on https://codeberg.org/comfy.city/-/packages/container/comfy-recipes/latest

docker run --rm -v path/to/myrecipes:/mnt codeberg.org/comfy.city/comfy-recipes ARGUMENTS

for example:

docker run --rm -v path/to/myrecipes:/mnt codeberg.org/comfy.city/comfy-recipes build /mnt

Docker is currently the only supported installation method, if you would like to use another method, please refer to the building instructions which are available in the project README.md

Tutorial

This is the full file structure of comfy recipes input data:

- myrecipes/            - can be named according to your preference

    - recipes/          - directory that will hold the recipes
        - pancakes.yaml    - the individual recipe

    - units.yaml        - OPTIONAL, file containing all valid units and their properties
    - ingredients.yaml  - OPTIONAL, file containing all valid ingredients and their properties
    - settings.yaml     - OPTIONAL, file for overriding default settings

In the following sub-chapters we will first create a simple recipe and then find out what each file does and what functionalities they can offer.

Quick Start

Let's start writing recipes. First, create the directory structure that will hold all our input data.

- myrecipes/
    - recipes/
        - pancakes.yaml

Now when we have the structure created, let's create the most minimal possible pancakes.yaml:

🗎 myrecipes/recipes/pancakes.yaml:

- title: Pancakes

And render it by running:

$ comfyrecipes build myrecipes

This will create a new directory out/ in myrecipes/ containing the built data.

- myrecipes/
    - out/
        - html/
            - index.html
            - pancakes.html
    - recipes/
        - pancakes.yaml

We can see the result if we start a web server pointing to that directory, for example by using:

$ comfyrecipes serve myrecipes

and navigate to http://127.0.0.1:8000/

serve should NOT be used in production.

While that was a valid recipe, it's not very useful and we can only see the title. Let's improve that:

🗎 myrecipes/recipes/pancakes.yaml:

- title: Pancakes
  ingredients:
    - 100 gram flour
  steps:
    - make pancakes
  • each ingredient is a step in the format amount unit name
    • amount has to be a number
    • unit has to be a single word
    • name can be a string with arbitrary content
    • for a full description of this format, please see the Reference section
  • each step is a string with arbitrary content

And again, build, make sure the server is running and navigate to http://127.0.0.1:8000/. From now on, we will assume you know how to build and serve your output directory.

Once more, let's improve the recipe once again to something that can actually be made and is not just a demo. This does not introduce any new concepts compared to the last recipe we wrote.

🗎 myrecipes/recipes/pancakes.yaml:

title: Swedish Pancakes
ingredients:
  - 3 piece egg
  - 1.25 cup milk
  - 0.75 cup all purpose flour
  - 1 tablespoon white sugar
  - 1 tablespoon butter
steps:
  - Beat eggs in a bowl until the mixture is smooth.
  - Add milk
  - Mix flour, sugar and salt in a separate bowl
  - Mix together with the egg mixture, mix until it's smooth
  - heat a griddle
  - Drop just enough of the mixture to the griddle to spread to all corners
  - After about a minute, turn the pancake over

For a full reference for what a recipe yaml can contain, please see the Recipe Reference

Units

Each recipe ingredient has a string unit assigned to it. This is great, but a centralized list of all alowed units with some additional properties has several advantages:

  • spelling mistakes are not silently ignored, if you make a mistake in the ingredient unit name, comfyrecipes will warn you that it's not on the units list
  • gram and g can refer to the same unit (using aliases)
  • we can tell comfyrecipes unit conversion rates (for example 1000 gram = 1 kilogram) which it can then use for example for calculating prices

This example will use the final example from Quick Start.

🗎 myrecipes/recipes/pancakes.yaml:

title: Swedish Pancakes
ingredients:
  - 3 piece egg
  - 1.25 cup milk
  - 0.75 cup all purpose flour
  - 1 tablespoon white sugar
  - 1 tablespoon butter
steps:
  - Beat eggs in a bowl until the mixture is smooth.
  - Add milk
  - Mix flour, sugar and salt in a separate bowl
  - Mix together with the egg mixture, mix until it's smooth
  - heat a griddle
  - Drop just enough of the mixture to the griddle to spread to all corners
  - After about a minute, turn the pancake over
- myrecipes/
    - recipes/
        - pancakes.yaml
    ...
    - units.yaml (we will be creating this file)

If you don't want to write the file manually, we can generate it using:

$ comfyrecipes generate-units

This will generate a minimal units.yaml:

🗎 myrecipes/units.yaml:

- name: cup
- name: piece
- name: tablespoon

Now, let's say we would want to call tablespoon just tbsp, we can add an alias:

🗎 myrecipes/units.yaml:

- name: cup
- name: piece
- name: tablespoon
  aliases:
    - tbsp

Now we can rename the tablespoon unit in the recipe to tbsp and it will reference the tablespoon unit.

For a full reference for what a recipe yaml can contain, please see the Units Reference

Ingredients

Similar to units.yaml, also ingredients.yaml is not a mandatory file, but having it gives us several advantages.

  • spelling mistakes are not silently ignored, if something is not listed in ingredients.yaml, comfyrecipes will warn you
  • we can use aliases - different names referring the same ingredient
  • we will be able to add some more data to ingredients that will allow us to calculate prices (described in Prices and Conversions)
- myrecipes/
    - recipes/
        - pancakes.yaml
    ...
    - ingredients.yaml (we will be creating this file)

We will again use the final recipe from Quick Start.

🗎 myrecipes/recipes/pancakes.yaml:

title: Swedish Pancakes
ingredients:
  - 3 piece egg
  - 1.25 cup milk
  - 0.75 cup all purpose flour
  - 1 tablespoon white sugar
  - 1 tablespoon butter
steps:
  - Beat eggs in a bowl until the mixture is smooth.
  - Add milk
  - Mix flour, sugar and salt in a separate bowl
  - Mix together with the egg mixture, mix until it's smooth
  - heat a griddle
  - Drop just enough of the mixture to the griddle to spread to all corners
  - After about a minute, turn the pancake over

If you don't want to write the file manually, we can generate it using:

$ comfyrecipes generate-ingredients

This will generate a minimal ingredients.yaml:

🗎 myrecipes/ingredients.yaml:

- name: all purpose flour
- name: butter
- name: egg
- name: milk
- name: white sugar

Now, let's say we would want to call all purpose flour just flour, we can add an alias:

🗎 myrecipes/ingredients.yaml:

- name: all purpose flour
  aliases:
    - flour
- name: butter
- name: egg
- name: milk
- name: white sugar

Now whenever we add an ingredient called flour, it will be a reference to all purpose flour.

For a full reference for what an ingredients yaml can contain, please see the Ingredients Reference

Prices and Conversions

ComfyRecipes has the ability to compute recipe prices if we give it enough information. This requires your recipe collection to have an ingredients.yaml file. Like with the previous sections, we will use

Settings

Sometimes we need to configure some defaults globally, this is what settings.yaml is for. Currently it's only used for setting the default_currency.

Let's create settings.yaml and set the default currency to USD.

- myrecipes/
    - recipes/
        - pancakes.yaml
    ...
    - settings.yaml

🗎 myrecipes/settings.yaml:

default_currency: USD

For a full reference for what a settings yaml can contain, please see the Settings Reference

Reference

  • What's not marked as MANDATORY is optional.

Data Types

  • string - text of arbitrary length
  • integer - a whole number
  • float - a decimal number
  • number - integer or float

Table Of Contents

Recipe (recipes/*.yaml)

Simplified Ingredient

= string in a specific format

[amount unit] ingredient name [(note)]

[] means these sections are optional

  • amount - number
  • unit - a single word string
  • name - string with arbitrary content
  • note - string with arbitrary content, but has to be enclosed in parentheses, otherwise it will be considered to be part of name

for example, valid values are:

1 piece carrot (sliced)
^ amount
  ^---^ unit
        ^----^ ingredient name
               ^-----^ note
200 gram green onion
^-^ amount
    ^--^ unit
         ^---------^ ingredient name
apple
^---^ ingredient name
apple (red)
^---^ ingredient name
      ^---^ note

When amount and unit is not in the string, it is assumed to be 1 piece.

Ingredient

  • name - MANDATORY, string, name has to be listed in ingredients.yaml if ingredients.yaml exists
  • amount - number
  • unit - string, unit has to be listed in units.yaml if units.yaml exists
  • or - list of Ingredient
  • note - string

Steps Section

  • section - MANDATORY, string, section name
  • steps - list of strings

Units (units.yaml)

Unit

  • name, MANDATORY, string
  • conversions, list of Conversions
  • aliases, list of strings

Conversion

  • to, MANDATORY, string, to has to be listed in units.yaml if units.yaml exists
  • ratio, MANDATORY, number

(this is similar to Ingredients Conversion, but the from field is automatically set to unit's name)

Ingredients (ingredients.yaml)

Ingredient

  • name, MANDATORY, string
  • aliases, list of strings
  • wdid, integer
  • prices, list of Prices
  • conversions, list of Conversions

Price

  • price, MANDATORY, number
  • amount, MANDATORY, number
  • unit, MANDATORY, string, unit has to be listed in units.yaml if units.yaml exists
  • currency, string

Conversion

  • from, MANDATORY, string, from has to be listed in units.yaml if units.yaml exists
  • to, MANDATORY, string, to has to be listed in units.yaml if units.yaml exists
  • ratio, MANDATORY, number

Settings (settings.yaml)

  • default_currency, string