feat: implement base recipe references with customizable ingredients and instructions
Add comprehensive base recipe system allowing recipes to reference other recipes dynamically. References can include custom items before/after the base recipe content and render as unified lists. Features: - Mark recipes as base recipes with isBaseRecipe flag - Insert base recipe references at any position in ingredients/instructions - Add custom items before/after referenced content (itemsBefore/itemsAfter, stepsBefore/stepsAfter) - Combined rendering displays all items in single unified lists - Full edit/remove functionality for additional items with modal reuse - Empty item validation prevents accidental blank entries - HTML rendering in section titles for proper <wbr> and ­ support - Reference links in section headings with multiplier preservation - Subtle hover effects (2% scale) on add buttons - Translation support for all reference fields - Deletion handling expands references before removing base recipes
This commit is contained in:
@@ -21,6 +21,45 @@ export const POST: RequestHandler = async ({request, locals}) => {
|
||||
throw error(404, "Recipe not found");
|
||||
}
|
||||
|
||||
// Check if this recipe is referenced by others
|
||||
const referencingRecipes = await Recipe.find({
|
||||
$or: [
|
||||
{ 'ingredients.baseRecipeRef': recipe._id },
|
||||
{ 'instructions.baseRecipeRef': recipe._id }
|
||||
]
|
||||
});
|
||||
|
||||
// Expand all references into regular content before deletion
|
||||
for (const depRecipe of referencingRecipes) {
|
||||
// Expand ingredient references
|
||||
if (depRecipe.ingredients) {
|
||||
depRecipe.ingredients = depRecipe.ingredients.flatMap((item: any) => {
|
||||
if (item.type === 'reference' && item.baseRecipeRef && item.baseRecipeRef.equals(recipe._id)) {
|
||||
if (item.includeIngredients && recipe.ingredients) {
|
||||
return recipe.ingredients.filter((i: any) => i.type === 'section' || !i.type);
|
||||
}
|
||||
return [];
|
||||
}
|
||||
return [item];
|
||||
});
|
||||
}
|
||||
|
||||
// Expand instruction references
|
||||
if (depRecipe.instructions) {
|
||||
depRecipe.instructions = depRecipe.instructions.flatMap((item: any) => {
|
||||
if (item.type === 'reference' && item.baseRecipeRef && item.baseRecipeRef.equals(recipe._id)) {
|
||||
if (item.includeInstructions && recipe.instructions) {
|
||||
return recipe.instructions.filter((i: any) => i.type === 'section' || !i.type);
|
||||
}
|
||||
return [];
|
||||
}
|
||||
return [item];
|
||||
});
|
||||
}
|
||||
|
||||
await depRecipe.save();
|
||||
}
|
||||
|
||||
// Remove this recipe from all users' favorites
|
||||
await UserFavorites.updateMany(
|
||||
{ favorites: recipe._id },
|
||||
|
||||
Reference in New Issue
Block a user