Sure. Try this:
\function get.meals() [[Meal Plan]get[text]enlist-input:raw[]tag[Recipes]]
\function get.ingredients() [all[tiddlers]field:recipe-parent<currentTiddler>]
{{{ [get.meals[]] :map:flat[get.ingredients[]] +[sort[]] }}}
Here I’ve used functions for legibility/potential reusability, but this is all equivalent to
{{{ [[Meal Plan]get[text]enlist-input:raw[]tag[Recipes]]
:map:flat[all[tiddlers]field:recipe-parent<currentTiddler>] +[sort[]] }}}
- The map filter run prefix is the key element here!
- If you do use functions, the
\function
definition pragmas need to be at the top of the tiddler (i.e., before any non-pragma wikitext.)
The rest of this post is musings not directly related to your question; feel free to ignore!
An alternate approach
I can’t help thinking that it’s a bit unwieldy to have a separate tiddler for each Recipe:Ingredient combo: you’ll end up with a lot of ingredient tiddlers very quickly, and it’s more difficult to add and update ingredient lists since you need to modify tiddlers outside the recipe you’re currently editing. I experimented a little with including an ingredients block directly in the recipe tiddler:
I used the
wikitext style block marker @@ to delimit the ingredients block, with the class
.ingredients
to make it easy to filter for
this style block in particular. As a bonus, you can also define an
.ingredients
class in CSS and easily apply whatever styling you like to the list.
Conventions I chose:
- each ingredient gets its own bullet point
- format of each line:
- [[Ingredient]], quantity (preparation notes)
I rewrote the Kolachi and African Chicken recipes in this format.
With all the ingredients listed directly in the recipe, it’s a bit easier to sort and filter values. Here’s some sample code I used to generate a list of all the ingredients from the meal plan and the quantities/recipes in which they’re used:
\function get.meals() [[Meal Plan]get[text]enlist-input:raw[]tag[Recipes]]
\function get.ingredients() [get[text]split[@@.ingredients]butfirst[]split[@@]first[]splitregexp[\n]removeprefix[* ]]
\function all.ingredients() [get.meals[]] :map:flat[get.ingredients[]]
\function get.amount() [<recipe>get.ingredients[]removeprefix<ingredient>trim[, ]]
<ul style="columns: 30em;">
<$list filter="[all.ingredients[]] :map[split[,]first[]] +[unique[]sort[]]" variable=ingredient>
<li style="break-inside: avoid;">
<<ingredient>>
<ul>
<$list filter="[get.meals[]search<ingredient>]" variable=recipe>
<li>
<<get.amount>>
(<$link to=<<recipe>> />)
</li>
</$list>
</ul>
</li>
</$list>
</ul>
Demo:
This is just a general proof of concept; you may have different display needs (combining quantities of the same ingredient where appropriate?). I’m sure there are some unfamiliar filter patterns in there, so do feel free to ask if you’re interested.
Here’s a package containing the two rewritten recipes, the altered Meal Plan, and the filter testing tiddler: recipe filter demo.json (3.0 KB) You can import it into your wiki if you’d like to test it yourself.