Sub-entries (dishes & ingredients)

A Property kind that lets one Entry hold a list of other Entries — a dish made of ingredients, a recipe of steps, a meal of foods. The ingredients vary every time, and each one is a real Entry that rolls up on its own.


Most Property kinds answer "what did you log?" with a number, some text, or a yes/no. Sub-entries answers it with other Entries. It's the "this thing is made of other tracked things" kind — the way you log a dish and the ingredients inside it.

The headline case is food: a Dish Type with one Sub-entries Property called Ingredients. Log a dish, and you add whatever foods went into it — a hamburger today (beef, buns, sauce), a salad tomorrow (tomato, broccoli, olive oil). The ingredients change every single time, and that's the point.

The key idea: ingredients aren't fixed to the Type

This is what makes Sub-entries different from a Routine, which logs the same set of Types every time. With Sub-entries:

  • The Dish Type only says "entries of this Type can hold ingredients." It never decides which ingredients.
  • Each dish Entry holds its own, chosen as you log it.
  • The same Dish Type produces a hamburger one day and a salad the next.

So you build one Dish Type, and every dish you log is free to contain anything. (If a Type's children are usually the same, you can give it a default starting set — still editable on every entry.)

How it works in the app

1. Add the Sub-entries Property. In the Type builder, add a property and pick Sub-entries from the Other group. Give it a name that suits the Type — Ingredients for a dish, Steps for a recipe. That's the only extra property a dish needs — the macros live on the foods, not the dish.

2. Log a dish. Create a Dish Entry. Its card shows an Ingredients list with a + Add button.

🍽  Hamburger
   Ingredients
   + Add

3. Add ingredients. Tap + Add and search your foods. Pick an existing one (🧀 Mozzarella) or type a new name to create it on the spot. Each pick becomes a child entry under this dish.

🍽  Hamburger
   Ingredients
   🥩  Beef        ✕
   🍞  Buns        ✕
   🥫  Sauce       ✕
   + Add

4. Fill in each ingredient's details. An ingredient is a normal Entry of its food Type with its own Properties (grams, calories, …). On the dish's own page each ingredient is a toggle — click the triangle to collapse it to a single line, or expand it to edit its fields right there. They start expanded, so opening a "Sets" entry shows every set's reps ready to edit without leaving the page. (You can still click an ingredient's name to open its own full page.)

Remove an ingredient with the ; delete the whole dish and its ingredients go with it.

Compact or full

By default the ingredient list is compact — one line per ingredient (emoji + name), like a checklist. If you'd rather see each ingredient's full detail — its macros and fields — right on the card, switch the Ingredients property to Full cards:

Open the Dish Type → Properties tab → the Ingredients row → the Compact / Full dropdown.

In Full mode each ingredient renders as its own mini card (the same layout a routine log uses for its entries), and you can edit an ingredient's numbers right there. Compact is best for long lists; Full is best when you want the macros visible at a glance.

Start every entry with the same sub-entries

Sometimes a Type's children barely change — a Bench press that's always three Sets, a Smoothie that always starts from the same base. Instead of adding them by hand every time, give the Type a default sub-entries list, and every new entry is born with them already attached.

Open the Type → Properties tab → the Sub-entries row → Add default sub-entry. Search your Types (or create one on the spot), and it joins the starting set. Click a default to expand it and preset its values — a "Set" that always starts at 10 reps, say.

When you then log that Type, the entry already contains those children — and you're still free to add more, remove them, or change their numbers for that one entry. It's a head start, not a fixed line-up:

  • Editing the defaults later only changes new entries — ones you already logged keep whatever they had.
  • Each default child is created with its own Type's defaults first, then your preset values on top.
  • It goes one level deep: if a default child's Type also has defaults of its own, those aren't expanded.
  • It works everywhere a log is created — the quick logger and the AI assistant included.

Why each ingredient is its own Entry

When you add "Mozzarella" to a dish, you're not typing a word — you're logging a Mozzarella Entry that happens to live inside the dish. That one design choice unlocks the analysis:

  • Your daily calories include every ingredient automatically — a banana eaten on its own and a banana inside a smoothie count exactly the same.
  • "How much cheese did I eat this year?" is a chart on the Mozzarella Type — every dish's mozzarella is a real Mozzarella Entry, so they all add up.
  • No double-counting. The dish itself carries no macros; the numbers live on the ingredients, so totals are counted once.

This is the universal engine doing its job: ingredients are just Entries, and Entries roll up.

Dish as one entry, or broken down — your call

You don't have to break every meal into parts:

  • Flat — for a restaurant meal you only know the total of, give the Dish its own Calories/Protein Properties and type the total. One Entry, done.
  • Broken down — for a homemade meal, leave the macros off the dish and add ingredients with their own numbers.

Pick per meal. A quick photo-style "≈850 kcal pizza" is flat; "200g dough, 150g mozzarella, 80g sauce" is broken down.

Examples

🍔 DishIngredients (Sub-entries). The everyday meal log; name each one as you go (Hamburger, Salad, Stir-fry).

🥗 RecipeIngredients (Sub-entries) · steps (Markdown) · servings (Number). A reusable recipe with its parts and method.

🛒 Shopping tripItems (Sub-entries) · total (Number). Each item is its own Entry with a price.

🎒 Packing listItems (Sub-entries) · packed (True/false on each item). What went in the bag this trip.

Sub-entries vs Relation vs Routine

All three connect things, but they're for different jobs:

| Kind | What it does | Example | |------|--------------|---------| | Sub-entries | Holds child Entries this entry owns | A dish's ingredients | | Relation | Points at another Entry that stands on its own | A reading session → the Book it's from | | Routine | Logs the same set of Types together every time | Morning ritual: meditation + stretch + journal |

Use Sub-entries when the parts belong to this one thing and change each time. Use Relation to link to something independent. Use a Routine when the line-up is always the same.

Next