7.2. Creating a recipe

You will recall that there are several types of Pantry files. You have already learned about two: the Pantry native file, and a Foods XML file. You create recipes using a third type of Pantry file: a Recipe XML file. Unlike Pantry native files and Foods XML files, Recipe XML files are read only. That is, though Pantry can read foods created in Recipe XML files, Pantry cannot add foods to Recipe XML files.

7.2.1. Creating a recipes file and its root element

To create a Recipe XML file, start your favorite text editor and open a text file. For the purposes of our example we'll use recipes.xml, though you can create any filename that ends with .xml.

The root element of every Recipe XML file is simply recipes. The recipes element has a single attribute, foodSource. Every recipe in Pantry is a new food that is comprised of several different foods. The foodSource attribute specifies which file contains the foods that will be used to make the recipes in this Recipe XML file. This file may be a Pantry native file or a Foods XML file or even a Foods Text file.[19] When specifying foodSource, it is easiest to use an absolute path--that is, one that begins with a slash.[20] Most likely you will want to use the master file, as we will do in this example.

Example 7.1. A recipes.xml file with an empty recipes element

<recipes foodSource='/home/massysett/pantry/master'>
</recipes>

7.2.2. Creating the recipe element

Next you will need to create a recipe element. This element will contain all the information needed for a single recipe. Remember that each recipe will ultimately create a new food. You use the attributes of the recipe element to specify the traits of the new food you are creating. Thus, the recipe element has several attributes: name, group, refuse, refDesc, date, meal, qty, comment, unit. Of all these attributes, you are required to set only the unit and qty attributes. You can leave as many of the other ones out as you wish, though ordinarily you will set the name and group attributes while leaving many of the others blank.

As with Foods XML files, you must set the unit attribute to one of the available units for the recipe. Pantry will automatically create the g, oz, and lb units for you. You can also have Pantry create a serving unit, as we will discuss shortly.

For our example, we will create a recipe with the name Easy Corn Bread. As you will see, the new recipe has its unit set to serving; shortly we will see exactly how this works. You will also notice that many of the attributes for the various traits, such as date and meal, are not set at all; Pantry will set such traits to the empty string.

Example 7.2. Creating the recipe element

<recipes foodSource='/home/massysett/pantry/master'>
<recipe name="Easy Corn Bread"
    group="Baked Products" pctRefuse='' refDesc='' 
    qty='1' unit='serving'>
</recipe>
</recipes>

7.2.3. Setting the yield of a recipe

Next you will need to set the yield of your recipe. The yield element has two attributes: grams and servings The servings attribute is easier to understand, so we will discuss it first.

7.2.3.1. The servings attribute

Often when you make a recipe, you split it into an even number of servings. If that is the case for your recipe, you may enter an appropriate value for the servings attribute. Pantry will automatically create a serving available unit for the food in this case.

For our corn bread example, we will say that the recipe makes nine servings.

7.2.3.2. The grams attribute

In order for Pantry to accurately calculate the nutrient content of a particular amount of food, it needs to know what the total mass of your completed recipe is, after it has been fully prepared (that is, after cooking, baking, mixing, etc., as the case may be.)

Pantry can "guess" what the total mass of your completed recipe is. Pantry guesses by adding up the mass of all the ingredients you entered for the recipe. To have Pantry guess for you, enter guess for the grams attribute. However, you will often find that the completed recipe weighs significantly less than the mass of all the ingredients. This is because a lot of water often evaporates as you cook or bake foods. Thus, for the most accurate results, you may enter the mass of your completed recipe so that Pantry may take it into account. To do this, enter the appropriate value (in grams) for the grams attribute.

However, if you have entered a servings attribute, and you will use only the serving available unit when you use the recipe, then entering a grams attribute will do you no good. This is because Pantry will calculate each serving so that it is the appropriate fraction of the total, but the actual total mass will not matter.

I always cut my cornbread into nine neat squares, and I always eat only one square at a time. Thus, since I will use only the servings available unit for the corn bread, I will simply enter guess for the grams attribute.

7.2.3.3. Contents of the yield element

Finally, you may enter any text you wish between the opening and closing tags of the yield element. This text can be used to describe the yield of the recipe. Pantry ignores this text, but it is useful because you might find yourself using the XML for other purposes (perhaps, for instance, to print your recipe out for use in the kitchen.)

I make my corn bread in a 8x8-inch dish, so I will make an appropriate entry for the yield element.

7.2.3.4. A complete yield element

Here is an example yield element:

Example 7.3. Setting the recipe yield

<recipes foodSource='/home/massysett/pantry/master'>
<recipe name="Easy Corn Bread"
    group="Baked Products" pctRefuse='' refDesc='' 
    qty='1' unit='serving'>

    <yield grams='guess' servings='9'>
        One square pan
    </yield>
</recipe>
</recipes>

7.2.4. Setting the ingredients of a recipe

No recipe is complete without ingredients. Each single ingredient is represented by a ingredient element. The ingredient element has four attributes: name, qty, unit, and comment.

First, as you will recall, each ingredient comes from the Pantry file given in the foodSource attribute of the recipes element. The name attribute of the ingredient is an exact match of the food you wish to use from the foodSource for this ingredient. You must exactly match every space, and you must exactly match the mixture of upper- and lower-case letters, as well.

The second attribute, qty, is simply the quantity of the ingredient. This must be an integer or floating-point number.

The third attribute, unit, is an exact match of the available unit you wish to use for this ingredient. As with the name attribute, this is case-sensitive.

Finally, the last attribute, comment, is optional. Pantry ignores this attribute, but you might find it handy for you own purposes.

Here is our corn bread example, complete with all its ingredients:

Example 7.4. A recipe with its ingredients

<recipes foodSource='/home/massysett/pantry/master'>
<recipe name="Easy Corn Bread"
    group="Baked Products" pctRefuse='' refDesc='' 
    qty='1' unit='serving'>

    <yield grams='guess' servings='9'>
        One square pan
    </yield>

    <ingredient name='Wheat flour, white, all-purpose, enriched, unbleached' 
        qty='5 5/8' unit='oz' comment='' />
    <ingredient name='Cornmeal, whole-grain, yellow' 
        qty='4.125' unit='oz' comment='' />
    <ingredient name='Sugars, granulated'
        qty='1 3/4' unit='oz' comment='' />
    <ingredient name='Leavening agents, baking powder, double-acting, straight phosphate'
        qty='2' unit='tsp' comment='' />
    <ingredient name='Salt, table'
        qty='1/2' unit='tsp' comment='' />
    <ingredient name='Milk, reduced fat, fluid, 2% milkfat, with added vitamin A'
        qty='1' unit='cup' comment='' />
    <ingredient name='Oil, canola and soybean'
        qty='1/4' unit='cup' comment='' />
    <ingredient name='Egg, whole, raw, fresh'
        qty='1' unit='large' comment='' />
</recipe>
</recipes>

7.2.5. Setting the available units for a recipe

Finally, you may set the available units for the food. Pantry automatically creates the g, oz, and lb units for you; in addition, if you specified a servings attribute to the yield element, as we discussed above, then Pantry will also automatically create a serving available unit. If you wish to create any additional available units, you will need to know the weight (in grams) of that unit. If for instance you are entering a recipe for cookies and you want to create an avaiable unit for one cookie, you'll need to know the weight in grams of one cookie.

To create available units, create one or more unit elements. Each unit element will have both name and grams attributes. As I stated above, I always eat one serving of corn bread, so I do not have any use for the units element here. However, for the sake of illustration, we'll say that a large piece of corn bread weighs 70 grams.

Example 7.5. A complete new recipe

<recipes foodSource='/home/massysett/pantry/master'>
<recipe name="Easy Corn Bread"
    group="Baked Products" pctRefuse='' refDesc='' 
    qty='1' unit='serving'>

    <yield grams='guess' servings='9'>
        One square pan
    </yield>

    <ingredient name='Wheat flour, white, all-purpose, enriched, unbleached' 
        qty='5.625' unit='oz' comment='' />
    <ingredient name='Cornmeal, whole-grain, yellow' 
        qty='4.125' unit='oz' comment='' />
    <ingredient name='Sugars, granulated'
        qty='1.75' unit='oz' comment='' />
    <ingredient name='Leavening agents, baking powder, double-acting, straight phosphate'
        qty='2' unit='tsp' comment='' />
    <ingredient name='Salt, table'
        qty='.5' unit='tsp' comment='' />
    <ingredient name='Milk, reduced fat, fluid, 2% milkfat, with added vitamin A'
        qty='1' unit='cup' comment='' />
    <ingredient name='Oil, canola and soybean'
        qty='.25' unit='cup' comment='' />
    <ingredient name='Egg, whole, raw, fresh'
        qty='1' unit='large' comment='' />
    <unit name='large piece' grams='70' />
</recipe>
</recipes>



[19] Strictly speaking, it can be a Recipe XML file as well, but it is unlikely you would want to do such a thing.

[20] You can use a relative path if you want. Such a path will be resolved relative to your current directory when you execute the Pantry command; the directory of the Recipe XML file is not relevant. This is confusing, which is why I recommend specifying an absolute path.