Table of Contents
The master
file comes with over
7,000 foods. However, you might find that you also need to
add additional foods to Pantry. This chapter will tell you
how to add additional foods by creating an XML file.
If you have a prepackaged food that already has a nutrition label, you can easily add it to a file. If however you have multiple foods that you wish to combine, then what you want is a recipe. We will discuss recipes in the next chapter.
As you may recall from our earlier discussions, an
essential element of Pantry is the food. Foods are contained
in food files. There are several different kinds of food
files. Until now, all the food files we have used have been
Pantry native files. You have been able to copy foods from
one Pantry native file, such as the master
file, and change the traits of those foods. To create
entirely new foods, you will create a different type of food
file, which we will call a Foods XML
file. Unlike a Pantry native file, the Foods XML file is in
human-readable, plain-text XML, which allows you to create
new foods.
In your favorite text editor, create a new file
whose name ends with .xml
. As
an example, we will create a file named
foods.xml
.
The root element of a Foods XML file is a
foods
element, so to get started
create that element.
Each food you create in the
foods.xml
file is contained
within a food
element. The
food
element has several
attributes. Each corresponds to the various food
traits that we've discussed earlier:
name
, group
,
date
, meal
,
unit
, qty
, and
comment
. Only the
unit
and qty
attributes are required. The unit
attribute may contain g
,
oz
, or
lb
, or it may contain one of
the units given in the units
element, which we will discuss shortly. The
qty
attribute must contain either
an integer or a floating-point number.
For the other attributes, which are optional,
pantry will create a zero-length
attribute for those you leave unset. Typically
though, you will set the name
and
group
attributes to something
useful, while leaving many of the others blank.
Typically you will be getting your nutrition
information from food labels. Usually these will
indicate a serving size, as well as a serving in
grams. You will set the unit
and
qty
traits to match what is given
on the food label. As an example, we will use a Clif
Bar. You may find it helpful to follow along with
its nutrition label, which you can find here.[11]
Its label shows a serving size of 1 bar. So, we
enter the following text into our
foods.xml
to start:
Example 5.2. foods.xml
with
food
element
<foods> <food name="Clif Bar, Oatmeal Raisin Walnut" group="Snacks" refDesc="" pctRefuse="" unit="bar" date="" meal="" qty="1.0" comment=""> </food> </foods>
Next, you will create nutrients for your food.
You define each nutrient by creating a
nutrient
element. Each
nutrient
element has two required
attributes and one optional attribute.
The name
attribute to the
nutrient
element, which is
required, gives the name of the nutrient, such as
Calories
or
Iron
. These names must
correspond to one of the nutrients that is allowed
in Pantry; to get a list of the allowed nutrients,
run pantry --nutrient-list all --print
list
. The names are case sensitive,
so although Saturated Fat
is
a valid nutrient, Saturated
fat
is not a valid nutrient.
The amount
attribute to the
nutrient
element is also
required, and it is a number (either floating-point
or integer) indicating the amount of the
corresponding nutrient.
The third attribute to the
nutrient
element,
units
, is optional. Setting
this attribute to %
,
indicates that the amount
attribute is a percentage of an FDA Daily Value. Pantry
will convert the amount
attribute
to an appropriate amount. This is useful because
vitamins and minerals are listed on food labels by
percent of daily value, rather than by amount. If
the units
is any value other than
%
, Pantry ignores
it.[12]
To continue with our Clif Bar example, here is the Clif Bar with its nutrient information. Because I am lazy, I did not enter all the nutrition information; instead, I just entered all the macronutrients and four of the vitamins and minerals.
Example 5.3. Food with nutrients
element
<foods> <food name="Clif Bar, Oatmeal Raisin Walnut" group="Snacks" refDesc="" pctRefuse="" unit="bar" date="" meal="" qty="1.0" comment=""> <nutrient name="Calories" amount="240"/> <nutrient name="Total Fat" amount="5"/> <nutrient name="Saturated Fat" amount="1"/> <nutrient name="Trans Fat" amount="0"/> <nutrient name="Cholesterol" amount="0"/> <nutrient name="Sodium" amount="130"/> <nutrient name="Potassium" amount="310" /> <nutrient name="Total Carbohydrate" amount="43"/> <nutrient name="Dietary Fiber" amount="5"/> <nutrient name="Sugars" amount="20"/> <nutrient name="Protein" amount="10"/> <nutrient name="Vitamin A" units="%" amount="30"/> <nutrient name="Vitamin C" units="%" amount="100"/> <nutrient name="Calcium" units="%" amount="25"/> <nutrient name="Iron" units="%" amount="25"/> <unit name="bar" grams="68"/> </food> </foods>
Finally, it is time to enter units, which you do
using the unit
element. These
elements map common units of measure to a food's
weight in grams, and they correspond to to the
available units that we discussed earlier. Thus,
each unit
element has two
attributes. name
corresponds to
the name of the unit, such as
cup
or
stick
or
box
--whatever is appropriate.
The grams
attribute corresponds
to whatever the weight of a single
name
is, in grams.
As always, Pantry will provide the units
g
, oz
,
and lb
for you, so do not
enter those in unit
elements.
However, if you entered anything other than
g
, oz
,
or lb
for the
unit
attribute of the
food
element, you must define a
corresponding unit
element. Thus,
because the unit
attribute for
our Clif Bar is bar
, we must
define a corresponding unit
element. With that, we have a complete
foods.xml
file.
Example 5.4. Complete foods.xml
file.
<foods> <food name="Clif Bar, Oatmeal Raisin Walnut" group="Snacks" refDesc="" pctRefuse="" unit="bar" date="" meal="" qty="1.0" comment=""> <nutrient name="Calories" amount="240"/> <nutrient name="Total Fat" amount="5"/> <nutrient name="Saturated Fat" amount="1"/> <nutrient name="Trans Fat" amount="0"/> <nutrient name="Cholesterol" amount="0"/> <nutrient name="Sodium" amount="130"/> <nutrient name="Potassium" amount="310" /> <nutrient name="Total Carbohydrate" amount="43"/> <nutrient name="Dietary Fiber" amount="5"/> <nutrient name="Sugars" amount="20"/> <nutrient name="Protein" amount="10"/> <nutrient name="Vitamin A" units="%" amount="30"/> <nutrient name="Vitamin C" units="%" amount="100"/> <nutrient name="Calcium" units="%" amount="25"/> <nutrient name="Iron" units="%" amount="25"/> <unit name="bar" grams="68"/> </food> </foods>
[11] Use of the Clif Bar in this example wholeheartedly implies my endorsement of Clif Bars. They are handy, tasty snacks.
[12] Even though Pantry ignores this attribute
if it is anything other than
%
, you might set it
anyway. For instance, perhaps you want to
use XSLT to print food labels. Your printout
can easily incorporate the values of the
units
attributes if you
wish.