Weekly Meal Shopper
approvedby AJ
Standardize recipe notes, parse ingredient amounts, and generate weekly shopping lists from a meal-plan canvas. - This plugin has not been manually reviewed by Obsidian staff.
Weekly Meal Shopper
Plan a week of meals on an Obsidian canvas, keep recipe amounts in consistent metric measures, and generate a categorised shopping list from that plan.
The plugin ships with its own starter templates. You do not need Obsidian's Templates core plugin.
Support the project: Buy Me a Coffee
First start
- Open
Settings → Weekly Meal Shopper. - Under Setup → Templates, click
Run setupand choose where the editable canvas and recipe templates should live. - Under Setup → Files and folders, set your recipe folder, meal plan canvas and shopping list note.
- Run
Open or create meal plan canvas, then add recipe cards to it. - Run
Generate weekly shopping list from meal-plan canvas.
Commands
Thirteen commands cover the everyday work. One-off and bulk actions live in settings instead, so the command palette stays short.
| Command | What it does |
|---|---|
| Open recipe view in current tab | Split ingredients/directions reading view |
| Open recipe card (planning view) | Recipe card modal, with add-to-canvas |
| Create recipe note from template | New blank recipe note |
| Transcribe recipe from URL entry (website/YouTube) | Imports a recipe from a link |
| Standardise current recipe (preview) | Shows the proposed changes for this note before writing |
| Calculate recipe macros | Per-serving energy and macros for this note |
| Open or create meal plan canvas | Opens the configured canvas, creating it if needed |
| Set active canvas as meal plan canvas | Asks whether this is the primary or second canvas |
| Add active recipe to meal plan | Asks whether it's a weekly meal, a project or hosting |
| Generate weekly shopping list from meal-plan canvas | Builds the shopping list |
| Apply frozen leftovers from meal-plan canvas | As above, and updates frozen portions |
| Manage frozen portions inventory | Edit frozen portions per recipe |
| Add ingredient override from current shopping list line | Recategorise an item from the list itself |
In settings: standardise all recipes, restore a backup, check recipes for problems, calculate macros for every recipe, transcribe an image folder, re-download the nutrition dataset, set a nutrition match, and manage frozen portions.
Settings
Seven groups, in the order you meet them:
- Setup — recipe folder, canvas, shopping list note, and the one-off template setup.
- Recipes & import — metadata field, recipe card view, transcription and your OpenAI key.
- Measurements & rounding — cup sizes, weight-first conversion, the stored ingredient line, which ingredients keep spoons, and unit aliases.
- Shopping list — categories, exclusions, overrides, dried legumes, pack sizes and pantry-check measures.
- Meal-plan canvas — household size, week start, the canvas panels, and a second prep session.
- Nutrition — macro tracking, energy unit, dataset and manual matches.
- Data & maintenance — bulk actions. Nothing is written until you confirm.
How amounts are stored
Ingredients live in the ### Ingredients section in four slots: Amount ; Unit ; Ingredient ; Preparation. Blank slots stay empty, so 1; ; sweet potato; roughly chopped is one sweet potato, no unit, roughly chopped. The separator is configurable (;, ,, :, |). The body is the source of truth; the IngredientsParsed frontmatter field mirrors it and is refreshed automatically a couple of seconds after you edit a note.
Amounts are metric-first:
- Grams wherever a density is known, including liquids, because that's what you cook with.
- Spoons for ingredients where a gram weight is useless: extracts, leavening, and all ground and dried spices by default. You can pin more ingredients to spoons in settings. Anything under 2 g becomes a spoon measure or a pinch.
- Fresh herbs measured by volume keep their tbsp or cup, because density estimates for loose leaves are unreliable.
- A site's own metric values win. If a recipe page publishes 200 g of chocolate chips, that's what's stored — never a converted cup.
Rounding: grams and millilitres to 1 below 10, 5 up to 100, then 10; teaspoons to ¼, tablespoons to ½, cups to ¼; counts to ½, or ¼ below 1. Values a recipe's author wrote are never rounded, and amounts under ¼ cup are stored in tablespoons rather than rounded up.
IngredientsParsed also records where each amount came from (site-metric, dual-unit, converted or original) and keeps the exact unrounded value.
Importing recipes
Transcribe recipe from URL entry fetches the page itself:
- WP Recipe Maker and Tasty Recipes sites: the plugin reads the metric amounts the site publishes.
- Any page with standard recipe structured data: ingredients and steps are taken as written, and OpenAI is not called at all.
- Instagram: the caption is read from the page's description metadata. This needs the plugin's own user agent, so the fetch sends one.
- Anything else, and all image transcription, uses OpenAI with your own API key.
- Mediavine Create is not supported — it's untested, so it falls back to the generic path.
Imported ingredients are shown for review before the note is written, with a badge showing where each amount came from.
Standardise
Standardise current recipe (preview) and Data & maintenance → Standardise all recipes run the same thing: a preview of every proposed line, before → after, grouped into ready, needs review and skipped. You choose what gets written.
- Directions are never rewritten. The only changes are removing bold the plugin previously added and normalising oven temperatures to
180°C (160°C fan). - Legacy free-text ingredients are converted locally, including splitting lines that hold several ingredients. Anything it can't split confidently is flagged rather than guessed.
- A note with headings outside the standard sections is skipped, so nothing is lost.
- Every write is backed up first to
.obsidian/plugins/weekly-meal-shopper/backups/(the last 5 runs). Restore them from settings. - A written note gets
MeasurementsVerified: truein its frontmatter and is skipped by later runs.
Shopping lists
Totals are aggregated unrounded across the plan, then each line is written as what you'd actually pick up:
- Counts are whole and keep what they count:
(21 slices) bread, not21 breads. - Packs: bunches, bags, loaves and cans come from
pack-sizes.json, with what the recipes use alongside —(1 loaf) bread — recipes use 21 slices. The built-in sizes are typical Australian supermarket estimates and are editable in settings. - Liquids are shown in ml and L, which is easier to picture in a shop, even though recipes store them in grams.
- Pantry check: categories you choose get a second measure, e.g.
(600 g, ≈ 4¾ cups) plain flour. - Needs attention: recipes with blank or unreadable
Portionsare listed at the top, because a blank one is counted as a single portion. A recipe whose ingredients can't be read is flagged there too instead of stopping the list.
Canvas panels
- Meal Coverage — per recipe, whether one cook covers what you've planned, with an icon and a word rather than a colour alone, plus buttons for the shopping list and frozen portions. Cards are coloured to match. Click a row to acknowledge one you're happy to cook again.
- Macro Details — per-day energy with a protein/carbs/fat bar, and a button to calculate any meals that don't have macros yet.
Macros and nutrition
- Turn on macro tracking, then run
Calculate recipe macros. Per-serving figures are cached to frontmatter and written into the note's### Nutritionsection. - Names are matched against a curated per-100g table, the downloaded USDA dataset, cached live lookups and your own overrides, in increasing priority.
- Matching tolerates brand and packaging words ("Cube Meredith Dairy feta" → feta cheese) but a name must account for at least half of the entry it matches, so plain "bread" never resolves to bread flour.
- Nothing is guessed. Anything unresolved is listed under the table; an ingredient with no set amount ("salt, to taste") is reported as excluded, not missing.
Configuration files
Created in the plugin folder on first use, and editable:
| File | Holds |
|---|---|
ingredient-categories.json | Shopping category rules |
unit-density-rules.json | Grams per ml per ingredient. Layered over the built-in table; 0 switches one off |
unit-aliases.json | Extra unit spellings |
pack-sizes.json | How things are sold: bunches, bags, loaves, cans |
nutrition-*.json | Nutrition dataset, live-lookup cache and manual matches |
Network use, AI and privacy
Planning, parsing, standardising and shopping lists all work offline.
- Recipe pages are fetched directly when you import a URL, including Instagram, which needs the plugin's own user agent.
- OpenAI (
api.openai.com) is used only for image transcription and for pages with no structured recipe data, with your own API key stored in this vault'sdata.json. Standardising never sends your directions anywhere. - Nutrition (off by default): turning on macro tracking downloads USDA Foundation Foods once (
fdc.nal.usda.gov, desktop only). The optional live-lookup fallback queries USDA (api.nal.usda.gov, your own free key) or Open Food Facts (world.openfoodfacts.org) for ingredients not found locally, and caches every result.
No telemetry, no ads.
Recipe view
- Split-pane reading view in the current tab.
- Left: ingredients from parsed metadata, click to cross off. Right: directions with a step focus box and
j/knavigation. - Ingredients mentioned in the active step are highlighted as you read. That highlighting is applied at display time and never written into the note.
Supported image formats for folder transcription: jpg/jpeg, png, webp, gif, bmp, heic/heif, tif/tiff, avif.
For plugin developers
Search results and similarity scores are powered by semantic analysis of your plugin's README. If your plugin isn't appearing for searches you'd expect, try updating your README to clearly describe your plugin's purpose, features, and use cases.