Recipe and ingredient database for Fathub v2
Add format documentation
Add spicy fried rice
Add Miso Soup


browse  log 



You can also use your local clone with git send-email.

#Fathub.org dataset

These are the data files for all the recipes and info on fathub.org

#Data structure

The second version of fathub.org supports internationalisation. This is accomplished by having translated copies of the dataset. The root folder of the repository contains a subdirectory for every language. The english language is the canonical dataset and if a translated version in another subdirectory exists that file will be preferred.

├── en
│   ├── ingredients
│   │   ├── example-ingredient.md
│   │   ├── category
│   │   │   ├── detailed-ingredient.md
│   │   │   └── another.md
│   └── recipes
│       ├── dutch # Cuisine subdirectory
│       │   └── main # Course subdirectory
│       │       └── boerenkool.toml # Recipe
├── nl
│   ├── ingredients
│   │   ├── example-ingredient.md # Translation of the EN page
│   └── recipes
│       └── dutch
│           └── main
│               └── boerenkool.toml # Dutch translated recipe
├── README.md
└── tools
    └── lint.py

#Recipe file format

The recipes are described in toml. Here's an example recipe:

name = "Stamppot Boerenkool"
author =  "Martijn Braam <martijn@brixit.nl>"
created = 2021-08-01
cuisine =  "Dutch"
course = "main dish"
preptime = 5
cooktime = 35
serves = 4

tips = [
    "If the [kale] isn't pre-cut you need about [kale:1:kg] and wash/cut it",
    "This dish can be made vegetarian by substituting the fried bacon with peanuts, add some butter to compensate for the lack of grease",
    "The dish works best with some floury potatoes such as Russet and Yukon Gold",
    "Traditionally this dish is served with 'rookworst' which doesn't seem to be really available internationally"

  id = "potatoes"
  amount = 2000
  unit = "g"
  prep = "peeled"
  id = "vegetables/kale/curly"
  amount = 600
  unit = "g"
  id = "water"
  amount = 100
  unit = "mL"
  id = "salt"
  amount = 10
  unit = "g"
  id = "meat/pork/bacon"
  amount = 250
  unit = "g"

    name = "cooking"
    steps = [
        "Put the [kale,water] and [salt] in a large pan with a lid and bring to a boil",
        "When the [kale] has shrunk enough, put the [potatoes] on top of them",
        "Cut the [bacon] in small strips and fry them until crispy",
        "Once the [potatoes] are done, pour off the cooking liquid, but keep it",
        "Crush the mass (with a potato masher) and mix them",
        "Add the cooking water back and add the [bacon] with all the grease"

The first keys in the file contain the main metadata of the recipe. Then a tips list that is rendered at the end of the recipe normally but has to be at the start of the recipe for toml syntax reasons.

#Recipe ingredients

Then the ingredient list is added as a dictionary. The name inside the brackets is the name used to refer to the ingredient inside the recipe. The id is the path to the ingredient file inside the database.

For ingredients the following properties are supported:

amount: For ingredients that have a specific amount that needs to be added. The unit for this field is described in the unit field.
unit: When the amount is specified this sets the unit. This can be one of:

  • L
  • mL
  • cup
  • teaspoon
  • tablespoon
  • fl oz
  • g
  • ounce
  • kg
  • piece

The frontend is able to convert the unit to whatever the user desires. If the specific weight for an ingredient is known in the database it's also possible to swich the display value between the weight and volume units.

In translated recipes the units should still be defined by these english terms

prep: This is a single line description of specific preperation of the ingredient. This can be "sliced" to denote the ingredient is assumed to be pre-sliced to avoid a list of these tasks in the recipe steps themselves.

#Recipe steps

The next section in the file is the [[instructions]] list. There can be multiple of these sections to break up larger recipes into "chapters". The two supported properties are:

name: The name for this section. This can be a free text field for complicated recipes but should just be the "cooking" string for simple recipes to make it auto-translatable. Another predefined option is "preparation" for recipes with an extra preperation step.

steps: This is a list of strings, one for each of the steps in the recipe. The frontend will render every line in this as a step with a checkbox to mark your progress while cooking. The recipe lines are mostly plain text but there is a DSL for making references:

When square brackets are put around a word it's a reference to an ingredient in the list. This is used to have translated ingredient names in recipes even before the recipe itself is translated. It also stylizes the name of the ingredient slightly to make it stand out in the recipe listing. Multiple names can be added seperated by a comma as a shorthand for adding a list of ingredients.

It's also possible to reference a specific amount of the ingredient by using the [ingredient:amount:unit] format that will render the ingredient in the page consistently with changes done in the ingredient list by the user like swapping the unit or multiplying the recipe amounts by a factor.

The last part of the DSL is the double brackets for referring to another recipe. with [[dutch/main/boerenkool]] a link would be generated to the recipe with that specific path. This is mainly useful for referring to other recipes in the tips section.