Compare commits
No commits in common. "b41d0124b792e0bdb19c993d3437a52a6e497abe" and "f38a464c9492d3ad9f30d219e73fd94375523524" have entirely different histories.
b41d0124b7
...
f38a464c94
|
|
@ -1,81 +0,0 @@
|
||||||
import { Recipe, Parser, getImageURL } from '@cooklang/cooklang-ts';
|
|
||||||
import fs from 'fs';
|
|
||||||
|
|
||||||
let config = {}
|
|
||||||
export default function (eleventyConfig, pluginOptions) {
|
|
||||||
config = pluginOptions;
|
|
||||||
eleventyConfig.addTemplateFormats('cook');
|
|
||||||
eleventyConfig.addExtension("cook", cookExtension);
|
|
||||||
};
|
|
||||||
|
|
||||||
const cookExtension = {
|
|
||||||
getData: async function (inputPath) {
|
|
||||||
const content = fs.readFileSync(inputPath, "utf-8").split("---")[2];
|
|
||||||
|
|
||||||
// Parse recipe using cooklang-ts
|
|
||||||
const recipe = new Recipe(content);
|
|
||||||
|
|
||||||
let steps = [];
|
|
||||||
let ingredients = [];
|
|
||||||
let cookware = [];
|
|
||||||
const recipeTags = recipe?.metadata?.tags?.split(",") || [];
|
|
||||||
|
|
||||||
function getStepTokenHTML(token) {
|
|
||||||
const { quantity, units, name, value, type } = token;
|
|
||||||
let tagContent = "";
|
|
||||||
|
|
||||||
if (token.type == "timer") {
|
|
||||||
tagContent = `${quantity} ${units}`;
|
|
||||||
} else {
|
|
||||||
tagContent = token.name || token.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (config.outputHtml) {
|
|
||||||
return `<span class="recipe--${type}">${tagContent}</span>`;
|
|
||||||
} else {
|
|
||||||
return `${tagContent}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
recipe.steps.forEach((stepTokens, i) => {
|
|
||||||
if (!steps[i]) steps[i] = [];
|
|
||||||
|
|
||||||
stepTokens.forEach((token) => {
|
|
||||||
if (token.type == "ingredient") {
|
|
||||||
let { name, quantity, units } = token;
|
|
||||||
|
|
||||||
if (
|
|
||||||
config.limitIngredientDecimals &&
|
|
||||||
!isNaN(config.limitIngredientDecimals)
|
|
||||||
) {
|
|
||||||
const decimalPlaces = parseInt(config.limitIngredientDecimals);
|
|
||||||
// Parsing float twice removes any trailing 0s
|
|
||||||
quantity = parseFloat(parseFloat(quantity).toFixed(decimalPlaces));
|
|
||||||
}
|
|
||||||
ingredients.push({ name, quantity, units });
|
|
||||||
}
|
|
||||||
|
|
||||||
if (token.type == "cookware") {
|
|
||||||
const { name } = token;
|
|
||||||
cookware.push({ name });
|
|
||||||
}
|
|
||||||
|
|
||||||
steps[i].push(getStepTokenHTML(token));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
|
||||||
recipe,
|
|
||||||
steps,
|
|
||||||
ingredients,
|
|
||||||
cookware,
|
|
||||||
recipeTags,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
compile: async (inputContent) => {
|
|
||||||
// We probably don't need the raw content but it's here if we want
|
|
||||||
return async () => {
|
|
||||||
return inputContent;
|
|
||||||
};
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
@ -8,7 +8,6 @@
|
||||||
import Image from '@11ty/eleventy-img';
|
import Image from '@11ty/eleventy-img';
|
||||||
import util from 'util';
|
import util from 'util';
|
||||||
import eleventyNavigationPlugin from "@11ty/eleventy-navigation";
|
import eleventyNavigationPlugin from "@11ty/eleventy-navigation";
|
||||||
import eleventyCooklang from "./_config/eleventy-plugin-cooklang.js";
|
|
||||||
|
|
||||||
const emojiRegex = /[\u{1f300}-\u{1f5ff}\u{1f900}-\u{1f9ff}\u{1f600}-\u{1f64f}\u{1f680}-\u{1f6ff}\u{2600}-\u{26ff}\u{2700}-\u{27bf}\u{1f1e6}-\u{1f1ff}\u{1f191}-\u{1f251}\u{1f004}\u{1f0cf}\u{1f170}-\u{1f171}\u{1f17e}-\u{1f17f}\u{1f18e}\u{3030}\u{2b50}\u{2b55}\u{2934}-\u{2935}\u{2b05}-\u{2b07}\u{2b1b}-\u{2b1c}\u{3297}\u{3299}\u{303d}\u{00a9}\u{00ae}\u{2122}\u{23f3}\u{24c2}\u{23e9}-\u{23ef}\u{25b6}\u{23f8}-\u{23fa}]/ug
|
const emojiRegex = /[\u{1f300}-\u{1f5ff}\u{1f900}-\u{1f9ff}\u{1f600}-\u{1f64f}\u{1f680}-\u{1f6ff}\u{2600}-\u{26ff}\u{2700}-\u{27bf}\u{1f1e6}-\u{1f1ff}\u{1f191}-\u{1f251}\u{1f004}\u{1f0cf}\u{1f170}-\u{1f171}\u{1f17e}-\u{1f17f}\u{1f18e}\u{3030}\u{2b50}\u{2b55}\u{2934}-\u{2935}\u{2b05}-\u{2b07}\u{2b1b}-\u{2b1c}\u{3297}\u{3299}\u{303d}\u{00a9}\u{00ae}\u{2122}\u{23f3}\u{24c2}\u{23e9}-\u{23ef}\u{25b6}\u{23f8}-\u{23fa}]/ug
|
||||||
|
|
||||||
|
|
@ -22,7 +21,6 @@ export default async function (eleventyConfig) {
|
||||||
eleventyConfig.addPassthroughCopy('src/admin');
|
eleventyConfig.addPassthroughCopy('src/admin');
|
||||||
|
|
||||||
eleventyConfig.addPlugin(eleventyNavigationPlugin);
|
eleventyConfig.addPlugin(eleventyNavigationPlugin);
|
||||||
eleventyConfig.addPlugin(eleventyCooklang);
|
|
||||||
|
|
||||||
/* Collections */
|
/* Collections */
|
||||||
eleventyConfig.addCollection('recipes', collection => {
|
eleventyConfig.addCollection('recipes', collection => {
|
||||||
|
|
|
||||||
12
package-lock.json
generated
12
package-lock.json
generated
|
|
@ -9,7 +9,6 @@
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@cooklang/cooklang-ts": "^1.2.7",
|
|
||||||
"alpinejs": "^2.8.2",
|
"alpinejs": "^2.8.2",
|
||||||
"decap-cms-app": "^3.6.2",
|
"decap-cms-app": "^3.6.2",
|
||||||
"decap-server": "^3.2.0"
|
"decap-server": "^3.2.0"
|
||||||
|
|
@ -521,12 +520,6 @@
|
||||||
"node": ">=0.1.90"
|
"node": ">=0.1.90"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@cooklang/cooklang-ts": {
|
|
||||||
"version": "1.2.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/@cooklang/cooklang-ts/-/cooklang-ts-1.2.7.tgz",
|
|
||||||
"integrity": "sha512-eVjyZ7HUbboP4y76L+OvsoEvY+oncIAqLr4vbXG5c0DuZEroRz1q+7JxYX8EEoa1ZKbIk5We0CHkUH6N49JMLw==",
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"node_modules/@dabh/diagnostics": {
|
"node_modules/@dabh/diagnostics": {
|
||||||
"version": "2.0.3",
|
"version": "2.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.3.tgz",
|
||||||
|
|
@ -11134,11 +11127,6 @@
|
||||||
"resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz",
|
||||||
"integrity": "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA=="
|
"integrity": "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA=="
|
||||||
},
|
},
|
||||||
"@cooklang/cooklang-ts": {
|
|
||||||
"version": "1.2.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/@cooklang/cooklang-ts/-/cooklang-ts-1.2.7.tgz",
|
|
||||||
"integrity": "sha512-eVjyZ7HUbboP4y76L+OvsoEvY+oncIAqLr4vbXG5c0DuZEroRz1q+7JxYX8EEoa1ZKbIk5We0CHkUH6N49JMLw=="
|
|
||||||
},
|
|
||||||
"@dabh/diagnostics": {
|
"@dabh/diagnostics": {
|
||||||
"version": "2.0.3",
|
"version": "2.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.3.tgz",
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,6 @@
|
||||||
"sass": "^1.86.3"
|
"sass": "^1.86.3"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@cooklang/cooklang-ts": "^1.2.7",
|
|
||||||
"alpinejs": "^2.8.2",
|
"alpinejs": "^2.8.2",
|
||||||
"decap-cms-app": "^3.6.2",
|
"decap-cms-app": "^3.6.2",
|
||||||
"decap-server": "^3.2.0"
|
"decap-server": "^3.2.0"
|
||||||
|
|
|
||||||
|
|
@ -1,111 +0,0 @@
|
||||||
{% extends 'layouts/base.njk' %}
|
|
||||||
|
|
||||||
{% block content %}
|
|
||||||
{% recipeimage image, "c-recipe__header-image", title, "100vw" %}
|
|
||||||
<h1 class="c-recipe__title">{{ title }}</h1>
|
|
||||||
<section>
|
|
||||||
<div class="l-container">
|
|
||||||
<div class="c-recipe__recipe-content-wrapper">
|
|
||||||
<div class="c-recipe__tag-list">
|
|
||||||
{% for tag in tags %}
|
|
||||||
<a class="c-tags__tag" href="/tags/{{ tag | noEmoji | slug }}">{{ tag }}</a>
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
{% set ingredientsArray = [] %}
|
|
||||||
{% for ingredient in ingredients %}
|
|
||||||
{% set value = [ingredient.quantity, ingredient.units, " ", ingredient.name] | join %}
|
|
||||||
{% set ingredientsArray = (ingredientsArray.push(value), ingredientsArray) %}
|
|
||||||
{% endfor %}
|
|
||||||
<div class="c-recipe__ingredients-wrapper" x-data='{currentServings: {{ servings if not servings == "" else false }}, ingredients: decodeURI("{{ ingredientsArray | arrayToString }}").split("£") }'>
|
|
||||||
<!-- <div class="c-recipe__ingredients-wrapper" x-data='{currentServings: {{ servings if not servings == "" else false }}, ingredients: decodeURI("{{ ingredients | arrayToString }}").split("£") }'> -->
|
|
||||||
{% if time or not servings == "" %}
|
|
||||||
<div class="c-recipe__additional-info">
|
|
||||||
{% if time %}
|
|
||||||
<p>{% include "icons/time.svg" %}{{ time }}</p>
|
|
||||||
{% endif %}
|
|
||||||
{% if not servings == "" %}
|
|
||||||
<p>
|
|
||||||
<template x-if="currentServings > 1">
|
|
||||||
<button @click="currentServings -= 1" class="c-recipe__serving-button">
|
|
||||||
-
|
|
||||||
<span class="u-sr-only">Remove 1 serving</span>
|
|
||||||
</button>
|
|
||||||
</template>
|
|
||||||
<span x-text="currentServings"></span>
|
|
||||||
<button @click="currentServings += 1" class="c-recipe__serving-button">
|
|
||||||
+
|
|
||||||
<span class="u-sr-only">Add 1 serving</span>
|
|
||||||
</button>
|
|
||||||
<span>{{ site.servingsLabel }}</span>
|
|
||||||
</p>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<h3>{{ site.ingredientsLabel }}</h3>
|
|
||||||
<template x-if="currentServings">
|
|
||||||
<ul class="c-recipe__ingredients-list">
|
|
||||||
<template x-for="(ingredient, index) in ingredients" :key="index">
|
|
||||||
<li><label><input type="checkbox"><span x-text="adaptQuantity(ingredient, {{servings}}, currentServings)"></span></label></li>
|
|
||||||
</template>
|
|
||||||
</ul>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<template x-if="!currentServings">
|
|
||||||
<ul class="c-recipe__ingredients-list">
|
|
||||||
{% for ingredient in ingredients %}
|
|
||||||
<li><label><input type="checkbox"><span>{{ingredient.quantity}}{{ ingredient.units}} {{ ingredient.name }}</span></label></li>
|
|
||||||
{% endfor %}
|
|
||||||
</ul>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<h3>Cookware</h3>
|
|
||||||
<ul class="c-recipe__ingredients-list">
|
|
||||||
{% for ingredient in cookware %}
|
|
||||||
<li><label><input type="checkbox"><span>{{ingredient.quantity}}{{ ingredient.units}} {{ ingredient.name }}</span></label></li>
|
|
||||||
{% endfor %}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="c-recipe__instructions-wrapper u-free-text">
|
|
||||||
{% set notesArr = notes.split('|') %}
|
|
||||||
{% if notesArr.length > 1 %}
|
|
||||||
<aside class="alert">
|
|
||||||
{%- for note in notesArr -%}
|
|
||||||
{{ note | safe }}<br>
|
|
||||||
{%- endfor -%}
|
|
||||||
</aside>
|
|
||||||
{% endif %}
|
|
||||||
<!-- {% if notes.length > 1 %}
|
|
||||||
<aside class="alert">
|
|
||||||
{%- for note in notes -%}
|
|
||||||
{{ note | safe }}
|
|
||||||
{%- endfor -%}
|
|
||||||
</aside>
|
|
||||||
{% endif %} -->
|
|
||||||
<!-- {{ content | safe }} -->
|
|
||||||
{% for step in steps %}
|
|
||||||
<p>
|
|
||||||
{% for stepDetail in step %}{{ stepDetail | safe }}{% endfor %}
|
|
||||||
</p>
|
|
||||||
{% endfor %}
|
|
||||||
<!-- {% for step in steps %}
|
|
||||||
<p>
|
|
||||||
{% for stepDetail in step %}{{ stepDetail.value | safe }}{{ stepDetail.name | safe }}{% endfor %}
|
|
||||||
</p>
|
|
||||||
{% endfor %} -->
|
|
||||||
{% if source %}
|
|
||||||
<p><a href="{{ source }}" target="_blank" rel="noopener">Source</a></p>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
function adaptQuantity (ingredient, originalServings, currentServings) {
|
|
||||||
return ingredient.replace(/(\d|\.|,)+/, match => Number(Math.round(parseFloat(match.replace(',', '.')) * currentServings / originalServings + 'e' + 2) + 'e-' + 2));
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
{% endblock %}
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
{
|
|
||||||
"layout": "layouts/recipe-cook"
|
|
||||||
}
|
|
||||||
|
|
@ -1,32 +0,0 @@
|
||||||
---
|
|
||||||
title: Simple brownies
|
|
||||||
image: https://ichef.bbci.co.uk/food/ic/food_16x9_1600/recipes/richchocolatebrownie_1933_16x9.jpg
|
|
||||||
tags:
|
|
||||||
- Sweet 🍬
|
|
||||||
- Cake 🍰
|
|
||||||
- Vegetarian 🌿
|
|
||||||
- Sharable
|
|
||||||
- Favourite ⭐
|
|
||||||
time: 45 min
|
|
||||||
servings: 4
|
|
||||||
source: https://www.bbc.co.uk/food/recipes/richchocolatebrownie_1933/
|
|
||||||
notes: I much prefer a flatbread to a crunchy tostada or taco so that's what I have this with. | I like [these Deli Kitchen ones](https://mydelikitchen.co.uk/products/4-greek-style-flatbreads/).
|
|
||||||
---
|
|
||||||
|
|
||||||
= Dough
|
|
||||||
|
|
||||||
Heat the oven to 190C/170C Fan/Gas 5. Line a #20x30cm baking tin{} with baking paper.
|
|
||||||
|
|
||||||
Gently melt the @butter{225%g}(preferably unsalted) and the @caster sugar{450%g} together in a #large pan{}. Once melted, take off the heat and add the @chocolate{140%g}(dark, broken into pieces). Stir until melted.
|
|
||||||
|
|
||||||
Beat in the @eggs{5}(free-range medium eggs), then stir in the @flour{110%g}(plain) and the @cocoa powder{55%g}.
|
|
||||||
|
|
||||||
Mix @onion{1}(peeled and finely chopped) and @garlic{2%cloves}(peeled and minced) into paste.
|
|
||||||
|
|
||||||
|
|
||||||
= Baking
|
|
||||||
Pour the brownie batter into the prepared tin and bake for ~{30%minutes}, ~{35%minutes}, or until the top of the brownie is just firm but there is still a gentle wobble in the middle.
|
|
||||||
|
|
||||||
Take out of the oven and leave to cool in the tin. Cut the brownies into 5cm squares when only just warm, or completely cool. -- Test
|
|
||||||
|
|
||||||
Pour over with @./sauces/Hollandaise{150%g}
|
|
||||||
Loading…
Reference in a new issue